From de0d821c8a0689d5ad980ac3760cd91f51bcf6fe Mon Sep 17 00:00:00 2001 From: Likho Date: Mon, 10 Jul 2023 18:41:26 +0200 Subject: [PATCH 01/80] Remove trailing comma from ios headers --- crypto_plugins/flutter_libepiccash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index e1df08873..cd12741de 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit e1df088733695ad06d377087d069eae1746d55a7 +Subproject commit cd12741de19e4faef39a23b7d543a2452524990a From 99b809ef17ba59465739aacb101ad453a1225eac Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Jul 2023 08:50:54 -0600 Subject: [PATCH 02/80] fix: bch address book entry address validation --- lib/utilities/address_utils.dart | 46 +++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/lib/utilities/address_utils.dart b/lib/utilities/address_utils.dart index 454391f56..0093e1d00 100644 --- a/lib/utilities/address_utils.dart +++ b/lib/utilities/address_utils.dart @@ -10,11 +10,11 @@ import 'dart:convert'; +import 'package:bitbox/bitbox.dart' as bitbox; import 'package:bitcoindart/bitcoindart.dart'; import 'package:crypto/crypto.dart'; import 'package:flutter_libepiccash/epic_cash.dart'; import 'package:nanodart/nanodart.dart'; -import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/coins/ecash/ecash_wallet.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; @@ -64,7 +64,27 @@ class AddressUtils { case Coin.litecoin: return Address.validateAddress(address, litecoin); case Coin.bitcoincash: - return Address.validateAddress(address, bitcoincash); + try { + // 0 for bitcoincash: address scheme, 1 for legacy address + final format = bitbox.Address.detectFormat(address); + + if (coin == Coin.bitcoincashTestnet) { + return true; + } + + if (format == bitbox.Address.formatCashAddr) { + String addr = address; + if (addr.contains(":")) { + addr = addr.split(":").last; + } + + return addr.startsWith("q"); + } else { + return address.startsWith("1"); + } + } catch (e) { + return false; + } case Coin.dogecoin: return Address.validateAddress(address, dogecoin); case Coin.epicCash: @@ -94,7 +114,27 @@ class AddressUtils { case Coin.litecoinTestNet: return Address.validateAddress(address, litecointestnet); case Coin.bitcoincashTestnet: - return Address.validateAddress(address, bitcoincashtestnet); + try { + // 0 for bitcoincash: address scheme, 1 for legacy address + final format = bitbox.Address.detectFormat(address); + + if (coin == Coin.bitcoincashTestnet) { + return true; + } + + if (format == bitbox.Address.formatCashAddr) { + String addr = address; + if (addr.contains(":")) { + addr = addr.split(":").last; + } + + return addr.startsWith("q"); + } else { + return address.startsWith("1"); + } + } catch (e) { + return false; + } case Coin.firoTestNet: return Address.validateAddress(address, firoTestNetwork); case Coin.dogecoinTestNet: From 51cc5654f6cbf18e7914ae3b33a6d2a3971371eb Mon Sep 17 00:00:00 2001 From: Josh Babb Date: Tue, 11 Jul 2023 15:50:08 -0500 Subject: [PATCH 03/80] update windows build docs more --- docs/building.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/building.md b/docs/building.md index 63d67278a..b56a87899 100644 --- a/docs/building.md +++ b/docs/building.md @@ -134,10 +134,28 @@ flutter run linux Visual Studio is required for Windows development with the Flutter SDK. Download it at https://visualstudio.microsoft.com/downloads/ and install the "Desktop development with C++" workload, including all of its default components. ### Building libraries in WSL2 -Set up Ubuntu 20.04 in WSL2. Follow the entire Linux host section to get set up and build windows `dll` libraries. Copy the resulting `dll`s to their respective positions on the Windows host: +Set up Ubuntu 20.04 in WSL2. Follow the entire Linux host section in the WSL2 Ubuntu 20.04 host to get set up to build. You will also need to install Rust and MXE dependencies on the WSL2 Ubuntu 20.04 host: + - [Install Rust](https://rustup.rs/) + ```sh + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + ``` + - Install MXE by running `stack_wallet/scripts/windows/deps.sh` + ```sh + ./stack_wallet/scripts/windows/deps.sh + ``` + +The WSL2 host may optionally be navigated to the `stack_wallet` repository on the Windows host in order to build the plugins in-place and skip the next section in which you copy the `dll`s from WSL2 to Windows. Then build windows `dll` libraries by running the following script on the WSL2 Ubuntu 20.04 host: + +- `stack_wallet/scripts/windows/build_all.sh` + +Copy the resulting `dll`s to their respective positions on the Windows host: - `stack_wallet/crypto_plugins/flutter_libepiccash/scripts/windows/build/libepic_cash_wallet.dll` - `stack_wallet/crypto_plugins/flutter_liblelantus/scripts/windows/build/libmobileliblelantus.dll` + ### Install Flutter on Windows host From 983cdca73615c7362dba1f21a454e4ee1d2c5f9f Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Wed, 12 Jul 2023 16:03:53 -0600 Subject: [PATCH 04/80] ios files --- ios/Podfile.lock | 34 ++++++++++++---------------- ios/Runner.xcodeproj/project.pbxproj | 18 +++++++++++---- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 76dc00433..b2235ac27 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,6 +1,4 @@ PODS: - - "app_settings (3.0.0+1)": - - Flutter - barcode_scan2 (0.0.1): - Flutter - MTBBarcodeScanner @@ -112,7 +110,7 @@ PODS: - Flutter - flutter_native_splash (0.0.1): - Flutter - - flutter_secure_storage (3.3.1): + - flutter_secure_storage (6.0.0): - Flutter - integration_test (0.0.1): - Flutter @@ -149,7 +147,6 @@ PODS: - Flutter DEPENDENCIES: - - app_settings (from `.symlinks/plugins/app_settings/ios`) - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - cw_monero (from `.symlinks/plugins/cw_monero/ios`) @@ -169,10 +166,10 @@ DEPENDENCIES: - lelantus (from `.symlinks/plugins/lelantus/ios`) - local_auth (from `.symlinks/plugins/local_auth/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - stack_wallet_backup (from `.symlinks/plugins/stack_wallet_backup/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - wakelock (from `.symlinks/plugins/wakelock/ios`) @@ -188,8 +185,6 @@ SPEC REPOS: - SwiftyGif EXTERNAL SOURCES: - app_settings: - :path: ".symlinks/plugins/app_settings/ios" barcode_scan2: :path: ".symlinks/plugins/barcode_scan2/ios" connectivity_plus: @@ -229,13 +224,13 @@ EXTERNAL SOURCES: package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: - :path: ".symlinks/plugins/path_provider_foundation/ios" + :path: ".symlinks/plugins/path_provider_foundation/darwin" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" share_plus: :path: ".symlinks/plugins/share_plus/ios" shared_preferences_foundation: - :path: ".symlinks/plugins/shared_preferences_foundation/ios" + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" stack_wallet_backup: :path: ".symlinks/plugins/stack_wallet_backup/ios" url_launcher_ios: @@ -244,13 +239,12 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/wakelock/ios" SPEC CHECKSUMS: - app_settings: d103828c9f5d515c4df9ee754dabd443f7cedcf3 barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0 - connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e + connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a cw_monero: 9816991daff0e3ad0a8be140e31933b5526babd4 cw_shared_external: 2972d872b8917603478117c9957dfca611845a92 cw_wownero: ac53899fa5c6ff46b3fb490aa3b7ca36301fa832 - device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed + device_info_plus: 7545d84d8d1b896cb16a4ff98c19f07ec4b298ea devicelocale: b22617f40038496deffba44747101255cee005b0 DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 @@ -260,23 +254,23 @@ SPEC CHECKSUMS: flutter_libmonero: da68a616b73dd0374a8419c684fa6b6df2c44ffe flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743 flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef - flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec - integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5 + flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be + integration_test: 13825b8a9334a850581300559b8839134b124670 isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073 lelantus: 417f0221260013dfc052cae9cf4b741b6479edba local_auth: 1740f55d7af0a2e2a8684ce225fe79d8931e808c MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb - package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e - path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 + package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7 + path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 SDWebImage: 72f86271a6f3139cc7e4a89220946489d4b9a866 - share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 - shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca + share_plus: 599aa54e4ea31d4b4c0e9c911bcc26c55e791028 + shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c stack_wallet_backup: 5b8563aba5d8ffbf2ce1944331ff7294a0ec7c03 SwiftProtobuf: 6ef3f0e422ef90d6605ca20b21a94f6c1324d6b3 SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780 - url_launcher_ios: fb12c43172927bb5cf75aeebd073f883801f1993 + url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f PODFILE CHECKSUM: 57c8aed26fba39d3ec9424816221f294a07c58eb diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 4f2f20dc9..43e1486e6 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -242,6 +242,7 @@ files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -301,7 +302,6 @@ "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework", "${BUILT_PRODUCTS_DIR}/SwiftyGif/SwiftyGif.framework", - "${BUILT_PRODUCTS_DIR}/app_settings/app_settings.framework", "${BUILT_PRODUCTS_DIR}/barcode_scan2/barcode_scan2.framework", "${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework", "${BUILT_PRODUCTS_DIR}/cw_monero/cw_monero.framework", @@ -335,7 +335,6 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyGif.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/app_settings.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/barcode_scan2.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cw_monero.framework", @@ -505,7 +504,10 @@ ); INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -692,7 +694,10 @@ ); INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -771,7 +776,10 @@ ); INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", From 27d97ebf49dfa6a487073421b9859859a1c570f2 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Wed, 12 Jul 2023 16:06:06 -0600 Subject: [PATCH 05/80] number format hack/fix --- lib/services/locale_service.dart | 2 +- lib/utilities/amount/amount.dart | 9 +++------ lib/utilities/amount/amount_formatter.dart | 8 +++++--- lib/utilities/amount/amount_input_formatter.dart | 6 ++---- lib/utilities/amount/amount_unit.dart | 9 +++------ lib/utilities/util.dart | 10 ++++++++++ 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/lib/services/locale_service.dart b/lib/services/locale_service.dart index 7f5cde716..8cfb6f765 100644 --- a/lib/services/locale_service.dart +++ b/lib/services/locale_service.dart @@ -21,7 +21,7 @@ class LocaleService extends ChangeNotifier { Future loadLocale({bool notify = true}) async { _locale = Platform.isWindows ? "en_US" - : await Devicelocale.currentLocale ?? "en_US"; + : (await Devicelocale.currentAsLocale)?.toString() ?? "en_US"; if (notify) { notifyListeners(); } diff --git a/lib/utilities/amount/amount.dart b/lib/utilities/amount/amount.dart index 0e8790064..0014a4eab 100644 --- a/lib/utilities/amount/amount.dart +++ b/lib/utilities/amount/amount.dart @@ -11,8 +11,7 @@ import 'dart:convert'; import 'package:decimal/decimal.dart'; -import 'package:intl/number_symbols.dart'; -import 'package:intl/number_symbols_data.dart'; +import 'package:stackwallet/utilities/util.dart'; class Amount { Amount({ @@ -52,8 +51,7 @@ class Amount { } // get number symbols for decimal place and group separator - final numberSymbols = numberFormatSymbols[locale] as NumberSymbols? ?? - numberFormatSymbols[locale.substring(0, 2)] as NumberSymbols?; + final numberSymbols = Util.getSymbolsFor(locale: locale); final groupSeparator = numberSymbols?.GROUP_SEP ?? ","; final decimalSeparator = numberSymbols?.DECIMAL_SEP ?? "."; @@ -101,8 +99,7 @@ class Amount { final wholeNumber = decimal.truncate(); // get number symbols for decimal place and group separator - final numberSymbols = numberFormatSymbols[locale] as NumberSymbols? ?? - numberFormatSymbols[locale.substring(0, 2)] as NumberSymbols?; + final numberSymbols = Util.getSymbolsFor(locale: locale); final String separator = numberSymbols?.DECIMAL_SEP ?? "."; diff --git a/lib/utilities/amount/amount_formatter.dart b/lib/utilities/amount/amount_formatter.dart index 7c5a8f29b..6743bcd53 100644 --- a/lib/utilities/amount/amount_formatter.dart +++ b/lib/utilities/amount/amount_formatter.dart @@ -22,11 +22,13 @@ final pMaxDecimals = Provider.family( ); final pAmountFormatter = Provider.family((ref, coin) { + final locale = ref.watch( + localeServiceChangeNotifierProvider.select((value) => value.locale), + ); + return AmountFormatter( unit: ref.watch(pAmountUnit(coin)), - locale: ref.watch( - localeServiceChangeNotifierProvider.select((value) => value.locale), - ), + locale: locale, coin: coin, maxDecimals: ref.watch(pMaxDecimals(coin)), ); diff --git a/lib/utilities/amount/amount_input_formatter.dart b/lib/utilities/amount/amount_input_formatter.dart index dfc2b5732..2ac5d7871 100644 --- a/lib/utilities/amount/amount_input_formatter.dart +++ b/lib/utilities/amount/amount_input_formatter.dart @@ -1,9 +1,8 @@ import 'dart:math'; import 'package:flutter/services.dart'; -import 'package:intl/number_symbols.dart'; -import 'package:intl/number_symbols_data.dart'; import 'package:stackwallet/utilities/amount/amount_unit.dart'; +import 'package:stackwallet/utilities/util.dart'; class AmountInputFormatter extends TextInputFormatter { final int decimals; @@ -20,8 +19,7 @@ class AmountInputFormatter extends TextInputFormatter { TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue) { // get number symbols for decimal place and group separator - final numberSymbols = numberFormatSymbols[locale] as NumberSymbols? ?? - numberFormatSymbols[locale.substring(0, 2)] as NumberSymbols?; + final numberSymbols = Util.getSymbolsFor(locale: locale); final decimalSeparator = numberSymbols?.DECIMAL_SEP ?? "."; final groupSeparator = numberSymbols?.GROUP_SEP ?? ","; diff --git a/lib/utilities/amount/amount_unit.dart b/lib/utilities/amount/amount_unit.dart index 79b36130f..0c0600d7a 100644 --- a/lib/utilities/amount/amount_unit.dart +++ b/lib/utilities/amount/amount_unit.dart @@ -11,11 +11,10 @@ import 'dart:math' as math; import 'package:decimal/decimal.dart'; -import 'package:intl/number_symbols.dart'; -import 'package:intl/number_symbols_data.dart'; import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/util.dart'; // preserve index order as index is used to store value in preferences enum AmountUnit { @@ -188,8 +187,7 @@ extension AmountUnitExt on AmountUnit { } // get number symbols for decimal place and group separator - final numberSymbols = numberFormatSymbols[locale] as NumberSymbols? ?? - numberFormatSymbols[locale.substring(0, 2)] as NumberSymbols?; + final numberSymbols = Util.getSymbolsFor(locale: locale); final groupSeparator = numberSymbols?.GROUP_SEP ?? ","; final decimalSeparator = numberSymbols?.DECIMAL_SEP ?? "."; @@ -237,8 +235,7 @@ extension AmountUnitExt on AmountUnit { String returnValue = wholeNumber.toString(); // get number symbols for decimal place and group separator - final numberSymbols = numberFormatSymbols[locale] as NumberSymbols? ?? - numberFormatSymbols[locale.substring(0, 2)] as NumberSymbols?; + final numberSymbols = Util.getSymbolsFor(locale: locale); // insert group separator final regex = RegExp(r'\B(?=(\d{3})+(?!\d))'); diff --git a/lib/utilities/util.dart b/lib/utilities/util.dart index 265cd2e06..c73f697cc 100644 --- a/lib/utilities/util.dart +++ b/lib/utilities/util.dart @@ -14,11 +14,21 @@ import 'dart:io'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/material.dart'; +import 'package:intl/number_symbols.dart'; +import 'package:intl/number_symbols_data.dart'; abstract class Util { static Directory? libraryPath; static double? screenWidth; + static NumberSymbols? getSymbolsFor({required String locale}) { + return numberFormatSymbols[locale] as NumberSymbols? ?? + numberFormatSymbols[locale.replaceAll("-", "_")] as NumberSymbols? ?? + numberFormatSymbols[locale.substring(3).toLowerCase()] + as NumberSymbols? ?? + numberFormatSymbols[locale.substring(0, 2)] as NumberSymbols?; + } + static bool get isDesktop { // special check for running on linux based phones if (Platform.isLinux && screenWidth != null && screenWidth! < 800) { From 3273cf0e23174252b54cc2a2c7df36a3f6141493 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Thu, 13 Jul 2023 16:26:29 -0600 Subject: [PATCH 06/80] disable new wownero wallet unless platform is android --- .../create_wallet_button_group.dart | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_wallet_button_group.dart b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_wallet_button_group.dart index e8c7c711c..36c914fd8 100644 --- a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_wallet_button_group.dart +++ b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_wallet_button_group.dart @@ -8,6 +8,8 @@ * */ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:stackwallet/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart'; import 'package:stackwallet/themes/stack_colors.dart'; @@ -32,35 +34,37 @@ class CreateWalletButtonGroup extends StatelessWidget { crossAxisAlignment: isDesktop ? CrossAxisAlignment.center : CrossAxisAlignment.stretch, children: [ - ConstrainedBox( - constraints: BoxConstraints( - minHeight: isDesktop ? 70 : 0, - minWidth: isDesktop ? 480 : 0, - ), - child: TextButton( - style: Theme.of(context) - .extension()! - .getPrimaryEnabledButtonStyle(context), - onPressed: () { - Navigator.of(context).pushNamed( - NameYourWalletView.routeName, - arguments: Tuple2( - AddWalletType.New, - coin, - ), - ); - }, - child: Text( - "Create new wallet", - style: isDesktop - ? STextStyles.desktopButtonEnabled(context) - : STextStyles.button(context), + if (Platform.isAndroid || coin != Coin.wownero) + ConstrainedBox( + constraints: BoxConstraints( + minHeight: isDesktop ? 70 : 0, + minWidth: isDesktop ? 480 : 0, + ), + child: TextButton( + style: Theme.of(context) + .extension()! + .getPrimaryEnabledButtonStyle(context), + onPressed: () { + Navigator.of(context).pushNamed( + NameYourWalletView.routeName, + arguments: Tuple2( + AddWalletType.New, + coin, + ), + ); + }, + child: Text( + "Create new wallet", + style: isDesktop + ? STextStyles.desktopButtonEnabled(context) + : STextStyles.button(context), + ), ), ), - ), - SizedBox( - height: isDesktop ? 16 : 12, - ), + if (Platform.isAndroid || coin != Coin.wownero) + SizedBox( + height: isDesktop ? 16 : 12, + ), ConstrainedBox( constraints: BoxConstraints( minHeight: isDesktop ? 70 : 0, From 9ede1e9fc9507b54065224089f3015942652c208 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Mon, 17 Jul 2023 09:35:08 -0600 Subject: [PATCH 07/80] update refs --- crypto_plugins/flutter_libepiccash | 2 +- crypto_plugins/flutter_liblelantus | 2 +- crypto_plugins/flutter_libmonero | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index cd12741de..c99e2a00b 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit cd12741de19e4faef39a23b7d543a2452524990a +Subproject commit c99e2a00b6bb98d497e99858e75ffe75f5898133 diff --git a/crypto_plugins/flutter_liblelantus b/crypto_plugins/flutter_liblelantus index ec3cf5e8e..45d15a4d6 160000 --- a/crypto_plugins/flutter_liblelantus +++ b/crypto_plugins/flutter_liblelantus @@ -1 +1 @@ -Subproject commit ec3cf5e8e1b90e006188aa8c323d4cd52dbfa9b9 +Subproject commit 45d15a4d6f5aa276751dbf9fb3ae076ffbebab44 diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index 26a152fea..782c8d00c 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit 26a152fea3ca4b8c3f1130392a02f579c2ff218c +Subproject commit 782c8d00c10d9dde906c1da982b1be7d45767ae7 From aec991600d2cecc5f87a4957f41b0c00a44c5f19 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Mon, 17 Jul 2023 09:36:16 -0600 Subject: [PATCH 08/80] add macos build script --- scripts/macos/build_all.sh | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100755 scripts/macos/build_all.sh diff --git a/scripts/macos/build_all.sh b/scripts/macos/build_all.sh new file mode 100755 index 000000000..646274593 --- /dev/null +++ b/scripts/macos/build_all.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +(cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh ) & +(cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh ) & +(cd ../../crypto_plugins/flutter_libmonero/scripts/macos/ && ./build_all.sh ) & + +wait +echo "Done building" \ No newline at end of file From 047291353ee0ba3f2f5ce76a84e660951b204a37 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Mon, 17 Jul 2023 09:50:28 -0600 Subject: [PATCH 09/80] macos file changes --- macos/Flutter/GeneratedPluginRegistrant.swift | 8 ++- pubspec.lock | 58 +------------------ 2 files changed, 7 insertions(+), 59 deletions(-) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index b741c3c0a..7cb956395 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,6 +6,9 @@ import FlutterMacOS import Foundation import connectivity_plus +import cw_monero +import cw_shared_external +import cw_wownero import desktop_drop import device_info_plus import devicelocale @@ -16,7 +19,6 @@ import isar_flutter_libs import package_info_plus import path_provider_foundation import share_plus -import shared_preferences_foundation import stack_wallet_backup import url_launcher_macos import wakelock_macos @@ -24,6 +26,9 @@ import window_size func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + CwMoneroPlugin.register(with: registry.registrar(forPlugin: "CwMoneroPlugin")) + CwSharedExternalPlugin.register(with: registry.registrar(forPlugin: "CwSharedExternalPlugin")) + CwWowneroPlugin.register(with: registry.registrar(forPlugin: "CwWowneroPlugin")) DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) @@ -34,7 +39,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) - SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) StackWalletBackupPlugin.register(with: registry.registrar(forPlugin: "StackWalletBackupPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 2dcd3c598..9ec8db667 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1349,62 +1349,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - sha256: "16d3fb6b3692ad244a695c0183fca18cf81fd4b821664394a781de42386bf022" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - shared_preferences_android: - dependency: transitive - description: - name: shared_preferences_android - sha256: "6478c6bbbecfe9aced34c483171e90d7c078f5883558b30ec3163cf18402c749" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - shared_preferences_foundation: - dependency: transitive - description: - name: shared_preferences_foundation - sha256: e014107bb79d6d3297196f4f2d0db54b5d1f85b8ea8ff63b8e8b391a02700feb - url: "https://pub.dev" - source: hosted - version: "2.2.2" - shared_preferences_linux: - dependency: transitive - description: - name: shared_preferences_linux - sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa" - url: "https://pub.dev" - source: hosted - version: "2.2.0" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d - url: "https://pub.dev" - source: hosted - version: "2.2.0" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - shared_preferences_windows: - dependency: transitive - description: - name: shared_preferences_windows - sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173" - url: "https://pub.dev" - source: hosted - version: "2.2.0" shelf: dependency: transitive description: @@ -1887,4 +1831,4 @@ packages: version: "1.0.0" sdks: dart: ">=3.0.2 <4.0.0" - flutter: ">=3.10.0" + flutter: ">=3.10.3" From 407bdc4d925610b706f2a1248dc4f3291c9e14c3 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Mon, 17 Jul 2023 10:29:08 -0600 Subject: [PATCH 10/80] update macos xcode project files --- .metadata | 16 +- macos/Podfile | 5 +- macos/Podfile.lock | 134 ++++++++--- macos/Runner.xcodeproj/project.pbxproj | 219 +++++++++++++++--- .../xcshareddata/xcschemes/Runner.xcscheme | 11 + .../AppIcon.appiconset/Contents.json | 132 +++++------ .../AppIcon.appiconset/app_icon_1024.png | Bin 69450 -> 102994 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 4664 -> 5680 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 926 -> 520 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 10085 -> 14142 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 1441 -> 1066 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 26089 -> 36406 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 2443 -> 2218 bytes macos/Runner/Configs/AppInfo.xcconfig | 2 +- macos/Runner/MainFlutterWindow.swift | 2 +- macos/RunnerTests/RunnerTests.swift | 12 + test/widget_test.dart | 30 +++ 17 files changed, 421 insertions(+), 142 deletions(-) create mode 100644 macos/RunnerTests/RunnerTests.swift create mode 100644 test/widget_test.dart diff --git a/.metadata b/.metadata index d1551205d..675f4a740 100644 --- a/.metadata +++ b/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled. version: - revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + revision: f92f44110e87bad5ff168335c36da6f6053036e6 channel: stable project_type: app @@ -13,17 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - - platform: linux - create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + create_revision: f92f44110e87bad5ff168335c36da6f6053036e6 + base_revision: f92f44110e87bad5ff168335c36da6f6053036e6 - platform: macos - create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - - platform: windows - create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + create_revision: f92f44110e87bad5ff168335c36da6f6053036e6 + base_revision: f92f44110e87bad5ff168335c36da6f6053036e6 # User provided section diff --git a/macos/Podfile b/macos/Podfile index dade8dfad..c795730db 100644 --- a/macos/Podfile +++ b/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.14' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -31,6 +31,9 @@ target 'Runner' do use_modular_headers! flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end end post_install do |installer| diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 82579cd8e..2b6385a35 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -1,24 +1,74 @@ PODS: - - connectivity_plus_macos (0.0.1): + - connectivity_plus (0.0.1): - FlutterMacOS - ReachabilitySwift + - cw_monero (0.0.1): + - cw_monero/Boost (= 0.0.1) + - cw_monero/Monero (= 0.0.1) + - cw_monero/OpenSSL (= 0.0.1) + - cw_monero/Sodium (= 0.0.1) + - cw_monero/Unbound (= 0.0.1) + - FlutterMacOS + - cw_monero/Boost (0.0.1): + - FlutterMacOS + - cw_monero/Monero (0.0.1): + - FlutterMacOS + - cw_monero/OpenSSL (0.0.1): + - FlutterMacOS + - cw_monero/Sodium (0.0.1): + - FlutterMacOS + - cw_monero/Unbound (0.0.1): + - FlutterMacOS + - cw_shared_external (0.0.1): + - cw_shared_external/Boost (= 0.0.1) + - cw_shared_external/OpenSSL (= 0.0.1) + - cw_shared_external/Sodium (= 0.0.1) + - FlutterMacOS + - cw_shared_external/Boost (0.0.1): + - FlutterMacOS + - cw_shared_external/OpenSSL (0.0.1): + - FlutterMacOS + - cw_shared_external/Sodium (0.0.1): + - FlutterMacOS + - cw_wownero (0.0.1): + - cw_wownero/Boost (= 0.0.1) + - cw_wownero/OpenSSL (= 0.0.1) + - cw_wownero/Sodium (= 0.0.1) + - cw_wownero/Unbound (= 0.0.1) + - cw_wownero/Wownero (= 0.0.1) + - FlutterMacOS + - cw_wownero/Boost (0.0.1): + - FlutterMacOS + - cw_wownero/OpenSSL (0.0.1): + - FlutterMacOS + - cw_wownero/Sodium (0.0.1): + - FlutterMacOS + - cw_wownero/Unbound (0.0.1): + - FlutterMacOS + - cw_wownero/Wownero (0.0.1): + - FlutterMacOS + - desktop_drop (0.0.1): + - FlutterMacOS + - device_info_plus (0.0.1): + - FlutterMacOS + - devicelocale (0.0.1): + - FlutterMacOS - flutter_libepiccash (0.0.1): - FlutterMacOS - flutter_local_notifications (0.0.1): - FlutterMacOS - - flutter_secure_storage_macos (3.3.1): + - flutter_secure_storage_macos (6.1.1): - FlutterMacOS - FlutterMacOS (1.0.0) - isar_flutter_libs (1.0.0): - FlutterMacOS - - package_info_plus_macos (0.0.1): + - package_info_plus (0.0.1): - FlutterMacOS - - path_provider_macos (0.0.1): + - path_provider_foundation (0.0.1): + - Flutter - FlutterMacOS - ReachabilitySwift (5.0.0) - - share_plus_macos (0.0.1): - - FlutterMacOS - - shared_preferences_macos (0.0.1): + - share_plus (0.0.1): - FlutterMacOS - stack_wallet_backup (0.0.1): - FlutterMacOS @@ -30,16 +80,21 @@ PODS: - FlutterMacOS DEPENDENCIES: - - connectivity_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos`) + - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`) + - cw_monero (from `Flutter/ephemeral/.symlinks/plugins/cw_monero/macos`) + - cw_shared_external (from `Flutter/ephemeral/.symlinks/plugins/cw_shared_external/macos`) + - cw_wownero (from `Flutter/ephemeral/.symlinks/plugins/cw_wownero/macos`) + - desktop_drop (from `Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos`) + - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) + - devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`) - flutter_libepiccash (from `Flutter/ephemeral/.symlinks/plugins/flutter_libepiccash/macos`) - flutter_local_notifications (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos`) - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - isar_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos`) - - package_info_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos`) - - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) - - share_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos`) - - shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`) + - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) + - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - stack_wallet_backup (from `Flutter/ephemeral/.symlinks/plugins/stack_wallet_backup/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`) @@ -50,8 +105,20 @@ SPEC REPOS: - ReachabilitySwift EXTERNAL SOURCES: - connectivity_plus_macos: - :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos + connectivity_plus: + :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos + cw_monero: + :path: Flutter/ephemeral/.symlinks/plugins/cw_monero/macos + cw_shared_external: + :path: Flutter/ephemeral/.symlinks/plugins/cw_shared_external/macos + cw_wownero: + :path: Flutter/ephemeral/.symlinks/plugins/cw_wownero/macos + desktop_drop: + :path: Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos + device_info_plus: + :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos + devicelocale: + :path: Flutter/ephemeral/.symlinks/plugins/devicelocale/macos flutter_libepiccash: :path: Flutter/ephemeral/.symlinks/plugins/flutter_libepiccash/macos flutter_local_notifications: @@ -62,14 +129,12 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral isar_flutter_libs: :path: Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos - package_info_plus_macos: - :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos - path_provider_macos: - :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos - share_plus_macos: - :path: Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos - shared_preferences_macos: - :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos + package_info_plus: + :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos + path_provider_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin + share_plus: + :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos stack_wallet_backup: :path: Flutter/ephemeral/.symlinks/plugins/stack_wallet_backup/macos url_launcher_macos: @@ -80,22 +145,27 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/window_size/macos SPEC CHECKSUMS: - connectivity_plus_macos: f6e86fd000e971d361e54b5afcadc8c8fa773308 + connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747 + cw_monero: a3442556ad3c06365c912735e4a23942a28692b1 + cw_shared_external: 1f631d1132521baac5f4caed43176fa10d4e0d8b + cw_wownero: b4adb1e701fc363de27fa222fcaf4eff6f5fa63a + desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 + device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f + devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225 flutter_libepiccash: b33f7396504712b513b8ff019a3f6f3bdae54cfb flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4 - flutter_secure_storage_macos: 6ceee8fbc7f484553ad17f79361b556259df89aa - FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811 - isar_flutter_libs: 1948109973b6c2e46d6196b1537688a36a6edeac - package_info_plus_macos: f010621b07802a241d96d01876d6705f15e77c1c - path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19 + flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + isar_flutter_libs: 43385c99864c168fadba7c9adeddc5d38838ca6a + package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce + path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 - share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4 - shared_preferences_macos: a64dc611287ed6cbe28fd1297898db1336975727 + share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7 stack_wallet_backup: 6ebc60b1bdcf11cf1f1cbad9aa78332e1e15778c - url_launcher_macos: 597e05b8e514239626bcf4a850fcf9ef5c856ec3 + url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451 wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9 window_size: 339dafa0b27a95a62a843042038fa6c3c48de195 -PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c +PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367 COCOAPODS: 1.11.3 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 6506a5075..7b723f8a8 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -21,15 +21,24 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 36299DF6FDF6725B2B9C51D5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BB87EF657A3ADFB1CE3E959 /* Pods_Runner.framework */; }; + BFD0376C00E1FFD46376BB9D /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9206484E84CB0AD93E3E68CA /* Pods_RunnerTests.framework */; }; + F653CA022D33E8B60E11A9F3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E6036BF01BF05EA773C76D22 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 33CC10E52044A3C60003C045 /* Project object */; @@ -53,9 +62,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0FA914E59929120BA65E8403 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 174539D042E7AC2AB25A83EB /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 27CB73AACA5743180CC6CD50 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* Stack Wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Stack Wallet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* stack_wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = stack_wallet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -67,26 +81,43 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; - 6BB87EF657A3ADFB1CE3E959 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 41EE721BF40B8DE895352A2C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 937DF254AD7EDA15AFE96BD9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 9206484E84CB0AD93E3E68CA /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - BC4589C48A71C3A1A477DD76 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - EA2D897BC13EBFB1DE697D5C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + ACB8E553D75AA4AC9A7656CE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + BF5E76865ACB46314AC27D8F /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + E6036BF01BF05EA773C76D22 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BFD0376C00E1FFD46376BB9D /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10EA2044A3C60003C045 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 36299DF6FDF6725B2B9C51D5 /* Pods_Runner.framework in Frameworks */, + F653CA022D33E8B60E11A9F3 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; 33BA886A226E78AF003329D5 /* Configs */ = { isa = PBXGroup; children = ( @@ -103,16 +134,18 @@ children = ( 33FAB671232836740065AC1E /* Runner */, 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, - 9000119722579F22067B9BC0 /* Pods */, + F0D4A0626F78BE1EF2A1E0D6 /* Pods */, ); sourceTree = ""; }; 33CC10EE2044A3C60003C045 /* Products */ = { isa = PBXGroup; children = ( - 33CC10ED2044A3C60003C045 /* Stack Wallet.app */, + 33CC10ED2044A3C60003C045 /* stack_wallet.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, ); name = Products; sourceTree = ""; @@ -152,39 +185,62 @@ path = Runner; sourceTree = ""; }; - 9000119722579F22067B9BC0 /* Pods */ = { + D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( - EA2D897BC13EBFB1DE697D5C /* Pods-Runner.debug.xcconfig */, - 937DF254AD7EDA15AFE96BD9 /* Pods-Runner.release.xcconfig */, - BC4589C48A71C3A1A477DD76 /* Pods-Runner.profile.xcconfig */, + E6036BF01BF05EA773C76D22 /* Pods_Runner.framework */, + 9206484E84CB0AD93E3E68CA /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + F0D4A0626F78BE1EF2A1E0D6 /* Pods */ = { + isa = PBXGroup; + children = ( + 41EE721BF40B8DE895352A2C /* Pods-Runner.debug.xcconfig */, + 0FA914E59929120BA65E8403 /* Pods-Runner.release.xcconfig */, + ACB8E553D75AA4AC9A7656CE /* Pods-Runner.profile.xcconfig */, + BF5E76865ACB46314AC27D8F /* Pods-RunnerTests.debug.xcconfig */, + 174539D042E7AC2AB25A83EB /* Pods-RunnerTests.release.xcconfig */, + 27CB73AACA5743180CC6CD50 /* Pods-RunnerTests.profile.xcconfig */, ); name = Pods; path = Pods; sourceTree = ""; }; - D73912EC22F37F3D000D13A0 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6BB87EF657A3ADFB1CE3E959 /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + FF8CC09C83E12FC1C6EE6A8F /* [CP] Check Pods Manifest.lock */, + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 33CC10EC2044A3C60003C045 /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - DF80A3E256A63BF2D2008937 /* [CP] Check Pods Manifest.lock */, + AAFD86C9DC38B4393BC9D8E0 /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, - 8D7CC24E5AE846869656D4D1 /* [CP] Embed Pods Frameworks */, + 529691D83C3BADE14E2EAC03 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -193,7 +249,7 @@ ); name = Runner; productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* Stack Wallet.app */; + productReference = 33CC10ED2044A3C60003C045 /* stack_wallet.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -206,6 +262,10 @@ LastUpgradeCheck = 1300; ORGANIZATIONNAME = ""; TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; 33CC10EC2044A3C60003C045 = { CreatedOnToolsVersion = 9.2; LastSwiftMigration = 1100; @@ -236,12 +296,20 @@ projectRoot = ""; targets = ( 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, 33CC111A2044C6BA0003C045 /* Flutter Assemble */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10EB2044A3C60003C045 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -256,6 +324,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -291,7 +360,7 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; - 8D7CC24E5AE846869656D4D1 /* [CP] Embed Pods Frameworks */ = { + 529691D83C3BADE14E2EAC03 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -308,7 +377,7 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - DF80A3E256A63BF2D2008937 /* [CP] Check Pods Manifest.lock */ = { + AAFD86C9DC38B4393BC9D8E0 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -330,9 +399,39 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + FF8CC09C83E12FC1C6EE6A8F /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10E92044A3C60003C045 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -346,6 +445,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; @@ -366,6 +470,51 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BF5E76865ACB46314AC27D8F /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stackWallet.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/stack_wallet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/stack_wallet"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 174539D042E7AC2AB25A83EB /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stackWallet.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/stack_wallet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/stack_wallet"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 27CB73AACA5743180CC6CD50 /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stackWallet.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/stack_wallet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/stack_wallet"; + }; + name = Profile; + }; 338D0CE9231458BD00FA5F75 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; @@ -404,7 +553,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -483,7 +632,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -530,7 +679,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -596,6 +745,16 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c9216c9be..a9d38bc3b 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -37,6 +37,17 @@ + + + + o5nb1G~3xi~y`}h6XHx5j$(L*3|5S2UfkG$|UCNI>}4f?MfqZ+HW-sRW5RKHEm z^unW*Xx{AH_X3Xdvb%C(Bh6POqg==@d9j=5*}oEny_IS;M3==J`P0R!eD6s~N<36C z*%-OGYqd0AdWClO!Z!}Y1@@RkfeiQ$Ib_ z&fk%T;K9h`{`cX3Hu#?({4WgtmkR!u3ICS~|NqH^fdNz>51-9)OF{|bRLy*RBv#&1 z3Oi_gk=Y5;>`KbHf~w!`u}!&O%ou*Jzf|Sf?J&*f*K8cftMOKswn6|nb1*|!;qSrlw= zr-@X;zGRKs&T$y8ENnFU@_Z~puu(4~Ir)>rbYp{zxcF*!EPS6{(&J}qYpWeqrPWW< zfaApz%<-=KqxrqLLFeV3w0-a0rEaz9&vv^0ZfU%gt9xJ8?=byvNSb%3hF^X_n7`(fMA;C&~( zM$cQvQ|g9X)1AqFvbp^B{JEX$o;4iPi?+v(!wYrN{L}l%e#5y{j+1NMiT-8=2VrCP zmFX9=IZyAYA5c2!QO96Ea-6;v6*$#ZKM-`%JCJtrA3d~6h{u+5oaTaGE)q2b+HvdZ zvHlY&9H&QJ5|uG@wDt1h99>DdHy5hsx)bN`&G@BpxAHh$17yWDyw_jQhhjSqZ=e_k z_|r3=_|`q~uA47y;hv=6-o6z~)gO}ZM9AqDJsR$KCHKH;QIULT)(d;oKTSPDJ}Jx~G#w-(^r<{GcBC*~4bNjfwHBumoPbU}M)O za6Hc2ik)2w37Yyg!YiMq<>Aov?F2l}wTe+>h^YXcK=aesey^i)QC_p~S zp%-lS5%)I29WfywP(r4@UZ@XmTkqo51zV$|U|~Lcap##PBJ}w2b4*kt7x6`agP34^ z5fzu_8rrH+)2u*CPcr6I`gL^cI`R2WUkLDE5*PX)eJU@H3HL$~o_y8oMRoQ0WF9w| z6^HZDKKRDG2g;r8Z4bn+iJNFV(CG;K-j2>aj229gl_C6n12Jh$$h!}KVhn>*f>KcH z;^8s3t(ccVZ5<{>ZJK@Z`hn_jL{bP8Yn(XkwfRm?GlEHy=T($8Z1Mq**IM`zxN9>-yXTjfB18m_$E^JEaYn>pj`V?n#Xu;Z}#$- zw0Vw;T*&9TK$tKI7nBk9NkHzL++dZ^;<|F6KBYh2+XP-b;u`Wy{~79b%IBZa3h*3^ zF&BKfQ@Ej{7ku_#W#mNJEYYp=)bRMUXhLy2+SPMfGn;oBsiG_6KNL8{p1DjuB$UZB zA)a~BkL)7?LJXlCc}bB~j9>4s7tlnRHC5|wnycQPF_jLl!Avs2C3^lWOlHH&v`nGd zf&U!fn!JcZWha`Pl-B3XEe;(ks^`=Z5R zWyQR0u|do2`K3ec=YmWGt5Bwbu|uBW;6D8}J3{Uep7_>L6b4%(d=V4m#(I=gkn4HT zYni3cnn>@F@Wr<hFAY3Y~dW+3bte;70;G?kTn4Aw5nZ^s5|47 z4$rCHCW%9qa4)4vE%^QPMGf!ET!^LutY$G zqdT(ub5T5b+wi+OrV}z3msoy<4)`IPdHsHJggmog0K*pFYMhH!oZcgc5a)WmL?;TPSrerTVPp<#s+imF3v#!FuBNNa`#6 z!GdTCF|IIpz#(eV^mrYKThA4Bnv&vQet@%v9kuRu3EHx1-2-it@E`%9#u`)HRN#M? z7aJ{wzKczn#w^`OZ>Jb898^Xxq)0zd{3Tu7+{-sge-rQ z&0PME&wIo6W&@F|%Z8@@N3)@a_ntJ#+g{pUP7i?~3FirqU`rdf8joMG^ld?(9b7Iv z>TJgBg#)(FcW)h!_if#cWBh}f+V08GKyg|$P#KTS&%=!+0a%}O${0$i)kn9@G!}En zv)_>s?glPiLbbx)xk(lD-QbY(OP3;MSXM5E*P&_`Zks2@46n|-h$Y2L7B)iH{GAAq19h5-y0q>d^oy^y+soJu9lXxAe%jcm?=pDLFEG2kla40e!5a}mpe zdL=WlZ=@U6{>g%5a+y-lx)01V-x;wh%F{=qy#XFEAqcd+m}_!lQ)-9iiOL%&G??t| z?&NSdaLqdPdbQs%y0?uIIHY7rw1EDxtQ=DU!i{)Dkn~c$LG5{rAUYM1j5*G@oVn9~ zizz{XH(nbw%f|wI=4rw^6mNIahQpB)OQy10^}ACdLPFc2@ldVi|v@1nWLND?)53O5|fg`RZW&XpF&s3@c-R?aad!$WoH6u0B|}zt)L($E^@U- zO#^fxu9}Zw7Xl~nG1FVM6DZSR0*t!4IyUeTrnp@?)Z)*!fhd3)&s(O+3D^#m#bAem zpf#*aiG_0S^ofpm@9O7j`VfLU0+{$x!u^}3!zp=XST0N@DZTp!7LEVJgqB1g{psNr za0uVmh3_9qah14@M_pi~vAZ#jc*&aSm$hCNDsuQ-zPe&*Ii#2=2gP+DP4=DY z_Y0lUsyE6yaV9)K)!oI6+*4|spx2at*30CAx~6-5kfJzQ`fN8$!lz%hz^J6GY?mVH zbYR^JZ(Pmj6@vy-&!`$5soyy-NqB^8cCT40&R@|6s@m+ZxPs=Bu77-+Os7+bsz4nA3DrJ8#{f98ZMaj-+BD;M+Jk?pgFcZIb}m9N z{ct9T)Kye&2>l^39O4Q2@b%sY?u#&O9PO4@t0c$NUXG}(DZJ<;_oe2~e==3Z1+`Zo zFrS3ns-c}ZognVBHbg#e+1JhC(Yq7==rSJQ8J~}%94(O#_-zJKwnBXihl#hUd9B_>+T& z7eHHPRC?5ONaUiCF7w|{J`bCWS7Q&xw-Sa={j-f)n5+I=9s;E#fBQB$`DDh<^mGiF zu-m_k+)dkBvBO(VMe2O4r^sf3;sk9K!xgXJU>|t9Vm8Ty;fl5pZzw z9j|}ZD}6}t;20^qrS?YVPuPRS<39d^y0#O1o_1P{tN0?OX!lc-ICcHI@2#$cY}_CY zev|xdFcRTQ_H)1fJ7S0*SpPs8e{d+9lR~IZ^~dKx!oxz?=Dp!fD`H=LH{EeC8C&z-zK$e=!5z8NL=4zx2{hl<5z*hEmO=b-7(k5H`bA~5gT30Sjy`@-_C zKM}^so9Ti1B;DovHByJkTK87cfbF16sk-G>`Q4-txyMkyQS$d}??|Aytz^;0GxvOs zPgH>h>K+`!HABVT{sYgzy3CF5ftv6hI-NRfgu613d|d1cg^jh+SK7WHWaDX~hlIJ3 z>%WxKT0|Db1N-a4r1oPKtF--^YbP=8Nw5CNt_ZnR{N(PXI>Cm$eqi@_IRmJ9#)~ZHK_UQ8mi}w^`+4$OihUGVz!kW^qxnCFo)-RIDbA&k-Y=+*xYv5y4^VQ9S)4W5Pe?_RjAX6lS6Nz#!Hry=+PKx2|o_H_3M`}Dq{Bl_PbP(qel~P@=m}VGW*pK96 zI@fVag{DZHi}>3}<(Hv<7cVfWiaVLWr@WWxk5}GDEbB<+Aj;(c>;p1qmyAIj+R!`@#jf$ zy4`q23L-72Zs4j?W+9lQD;CYIULt%;O3jPWg2a%Zs!5OW>5h1y{Qof!p&QxNt5=T( zd5fy&7=hyq;J8%86YBOdc$BbIFxJx>dUyTh`L z-oKa=OhRK9UPVRWS`o2x53bAv+py)o)kNL6 z9W1Dlk-g6Ht@-Z^#6%`9S9`909^EMj?9R^4IxssCY-hYzei^TLq7Cj>z$AJyaU5=z zl!xiWvz0U8kY$etrcp8mL;sYqGZD!Hs-U2N{A|^oEKA482v1T%cs%G@X9M?%lX)p$ zZoC7iYTPe8yxY0Jne|s)fCRe1mU=Vb1J_&WcIyP|x4$;VSVNC`M+e#oOA`#h>pyU6 z?7FeVpk`Hsu`~T3i<_4<5fu?RkhM;@LjKo6nX>pa%8dSdgPO9~Jze;5r>Tb1Xqh5q z&SEdTXevV@PT~!O6z|oypTk7Qq+BNF5IQ(8s18c=^0@sc8Gi|3e>VKCsaZ?6=rrck zl@oF5Bd0zH?@15PxSJIRroK4Wa?1o;An;p0#%ZJ^tI=(>AJ2OY0GP$E_3(+Zz4$AQ zW)QWl<4toIJ5TeF&gNXs>_rl}glkeG#GYbHHOv-G!%dJNoIKxn)FK$5&2Zv*AFic! z@2?sY&I*PSfZ8bU#c9fdIJQa_cQijnj39-+hS@+~e*5W3bj%A}%p9N@>*tCGOk+cF zlcSzI6j%Q|2e>QG3A<86w?cx6sBtLNWF6_YR?~C)IC6_10SNoZUHrCpp6f^*+*b8` zlx4ToZZuI0XW1W)24)92S)y0QZa);^NRTX6@gh8@P?^=#2dV9s4)Q@K+gnc{6|C}& zDLHr7nDOLrsH)L@Zy{C_2UrYdZ4V{|{c8&dRG;wY`u>w%$*p>PO_}3`Y21pk?8Wtq zGwIXTulf7AO2FkPyyh2TZXM1DJv>hI`}x`OzQI*MBc#=}jaua&czSkI2!s^rOci|V zFkp*Vbiz5vWa9HPFXMi=BV&n3?1?%8#1jq?p^3wAL`jgcF)7F4l<(H^!i=l-(OTDE zxf2p71^WRIExLf?ig0FRO$h~aA23s#L zuZPLkm>mDwBeIu*C7@n@_$oSDmdWY7*wI%aL73t~`Yu7YwE-hxAATmOi0dmB9|D5a zLsR7OQcA0`vN9m0L|5?qZ|jU+cx3_-K2!K$zDbJ$UinQy<9nd5ImWW5n^&=Gg>Gsh zY0u?m1e^c~Ug39M{{5q2L~ROq#c{eG8Oy#5h_q=#AJj2Yops|1C^nv0D1=fBOdfAG z%>=vl*+_w`&M7{qE#$xJJp_t>bSh7Mpc(RAvli9kk3{KgG5K@a-Ue{IbU{`umXrR3ra5Y7xiX42+Q%N&-0#`ae_ z#$Y6Wa++OPEDw@96Zz##PFo9sADepQe|hUy!Zzc2C(L`k9&=a8XFr+!hIS>D2{pdGP1SzwyaGLiH3j--P>U#TWw90t8{8Bt%m7Upspl#=*hS zhy|(XL6HOqBW}Og^tLX7 z+`b^L{O&oqjwbxDDTg2B;Yh2(fW>%S5Pg8^u1p*EFb z`(fbUM0`afawYt%VBfD&b3MNJ39~Ldc@SAuzsMiN%E}5{uUUBc7hc1IUE~t-Y9h@e7PC|sv$xGx=hZiMXNJxz5V(np%6u{n24iWX#!8t#>Ob$in<>dw96H)oGdTHnU zSM+BPss*5)Wz@+FkooMxxXZP1{2Nz7a6BB~-A_(c&OiM)UUNoa@J8FGxtr$)`9;|O z(Q?lq1Q+!E`}d?KemgC!{nB1JJ!B>6J@XGQp9NeQvtbM2n7F%v|IS=XWPVZY(>oq$ zf=}8O_x`KOxZoGnp=y24x}k6?gl_0dTF!M!T`={`Ii{GnT1jrG9gPh)R=RZG8lIR| z{ZJ6`x8n|y+lZuy${fuEDTAf`OP!tGySLXD}ATJO5UoZv|Xo3%7O~L63+kw}v)Ci=&tWx3bQJfL@5O18CbPlkR^IcKA zy1=^Vl-K-QBP?9^R`@;czcUw;Enbbyk@vJQB>BZ4?;DM%BUf^eZE+sOy>a){qCY6Y znYy;KGpch-zf=5|p#SoAV+ie8M5(Xg-{FoLx-wZC9IutT!(9rJ8}=!$!h%!J+vE2e z(sURwqCC35v?1>C1L)swfA^sr16{yj7-zbT6Rf26-JoEt%U?+|rQ zeBuGohE?@*!zR9)1P|3>KmJSgK*fOt>N>j}LJB`>o(G#Dduvx7@DY7};W7K;Yj|8O zGF<+gTuoIKe7Rf+LQG3-V1L^|E;F*}bQ-{kuHq}| ze_NwA7~US19sAZ)@a`g*zkl*ykv2v3tPrb4Og2#?k6Lc7@1I~+ew48N&03hW^1Cx+ zfk5Lr4-n=#HYg<7ka5i>2A@ZeJ60gl)IDX!!p zzfXZQ?GrT>JEKl7$SH!otzK6=0dIlqN)c23YLB&Krf9v-{@V8p+-e2`ujFR!^M%*; ze_7(Jh$QgoqwB!HbX=S+^wqO15O_TQ0-qX8f-|&SOuo3ZE{{9Jw5{}>MhY}|GBhO& zv48s_B=9aYQfa;d>~1Z$y^oUUaDer>7ve5+Gf?rIG4GZ!hRKERlRNgg_C{W_!3tsI2TWbX8f~MY)1Q`6Wj&JJ~*;ay_0@e zzx+mE-pu8{cEcVfBqsnm=jFU?H}xj@%CAx#NO>3 z_re3Rq%d1Y7VkKy{=S73&p;4^Praw6Y59VCP6M?!Kt7{v#DG#tz?E)`K95gH_mEvb z%$<~_mQ$ad?~&T=O0i0?`YSp?E3Dj?V>n+uTRHAXn`l!pH9Mr}^D1d@mkf+;(tV45 zH_yfs^kOGLXlN*0GU;O&{=awxd?&`{JPRr$z<1HcAO2K`K}92$wC}ky&>;L?#!(`w z68avZGvb728!vgw>;8Z8I@mLtI`?^u6R>sK4E7%=y)jpmE$fH!Dj*~(dy~-2A5Cm{ zl{1AZw`jaDmfvaB?jvKwz!GC}@-Dz|bFm1OaPw(ia#?>vF7Y5oh{NVbyD~cHB1KFn z9C@f~X*Wk3>sQH9#D~rLPslAd26@AzMh=_NkH_yTNXx6-AdbAb z{Ul89YPHslD?xAGzOlQ*aMYUl6#efCT~WI zOvyiewT=~l1W(_2cEd(8rDywOwjM-7P9!8GCL-1<9KXXO=6%!9=W++*l1L~gRSxLVd8K=A7&t52ql=J&BMQu{fa6y zXO_e>d?4X)xp2V8e3xIQGbq@+vo#&n>-_WreTTW0Yr?|YRPP43cDYACMQ(3t6(?_k zfgDOAU^-pew_f5U#WxRXB30wcfDS3;k~t@b@w^GG&<5n$Ku?tT(%bQH(@UHQGN)N|nfC~7?(etU`}XB)$>KY;s=bYGY#kD%i9fz= z2nN9l?UPMKYwn9bX*^xX8Y@%LNPFU>s#Ea1DaP%bSioqRWi9JS28suTdJycYQ+tW7 zrQ@@=13`HS*dVKaVgcem-45+buD{B;mUbY$YYULhxK)T{S?EB<8^YTP$}DA{(&)@S zS#<8S96y9K2!lG^VW-+CkfXJIH;Vo6wh)N}!08bM$I7KEW{F6tqEQ?H@(U zAqfi%KCe}2NUXALo;UN&k$rU0BLNC$24T_mcNY(a@lxR`kqNQ0z%8m>`&1ro40HX} z{{3YQ;2F9JnVTvDY<4)x+88i@MtXE6TBd7POk&QfKU-F&*C`isS(T_Q@}K)=zW#K@ zbXpcAkTT-T5k}Wj$dMZl7=GvlcCMt}U`#Oon1QdPq%>9J$rKTY8#OmlnNWBYwafhx zqFnym@okL#Xw>4SeRFejBnZzY$jbO)e^&&sHBgMP%Ygfi!9_3hp17=AwLBNFTimf0 zw6BHNXw19Jg_Ud6`5n#gMpqe%9!QB^_7wAYv8nrW94A{*t8XZu0UT&`ZHfkd(F{Px zD&NbRJP#RX<=+sEeGs2`9_*J2OlECpR;4uJie-d__m*(aaGE}HIo+3P{my@;a~9Y$ zHBXVJ83#&@o6{M+pE9^lI<4meLLFN_3rwgR4IRyp)~OF0n+#ORrcJ2_On9-78bWbG zuCO0esc*n1X3@p1?lN{qWS?l7J$^jbpeel{w~51*0CM+q9@9X=>%MF(ce~om(}?td zjkUmdUR@LOn-~6LX#=@a%rvj&>DFEoQscOvvC@&ZB5jVZ-;XzAshwx$;Qf@U41W=q zOSSjQGQV8Qi3*4DngNMIM&Cxm7z*-K`~Bl(TcEUxjQ1c=?)?wF8W1g;bAR%sM#LK( z_Op?=P%)Z+J!>vpN`By0$?B~Out%P}kCriDq@}In&fa_ZyKV+nLM0E?hfxuu%ciUz z>yAk}OydbWNl7{)#112j&qmw;*Uj&B;>|;Qwfc?5wIYIHH}s6Mve@5c5r+y)jK9i( z_}@uC(98g)==AGkVN?4>o@w=7x9qhW^ zB(b5%%4cHSV?3M?k&^py)j*LK16T^Ef4tb05-h-tyrjt$5!oo4spEfXFK7r_Gfv7#x$bsR7T zs;dqxzUg9v&GjsQGKTP*=B(;)be2aN+6>IUz+Hhw-n>^|`^xu*xvjGPaDoFh2W4-n z@Wji{5Y$m>@Vt7TE_QVQN4*vcfWv5VY-dT0SV=l=8LAEq1go*f zkjukaDV=3kMAX6GAf0QOQHwP^{Z^=#Lc)sh`QB)Ftl&31jABvq?8!3bt7#8vxB z53M{4{GR4Hl~;W3r}PgXSNOt477cO62Yj(HcK&30zsmWpvAplCtpp&mC{`2Ue*Bwu zF&UX1;w%`Bs1u%RtGPFl=&sHu@Q1nT`z={;5^c^^S~^?2-?<|F9RT*KQmfgF!7=wD@hytxbD;=9L6PZrK*1<4HMObNWehA62DtTy)q5H|57 z9dePuC!1;0MMRRl!S@VJ8qG=v^~aEU+}2Qx``h1LII!y{crP2ky*R;Cb;g|r<#ryo zju#s4dE?5CTIZKc*O4^3qWflsQ(voX>(*_JP7>Q&$%zCAIBTtKC^JUi@&l6u&t0hXMXjz_y!;r@?k|OU9aD%938^TZ>V? zqJmom_6dz4DBb4Cgs_Ef@}F%+cRCR%UMa9pi<-KHN;t#O@cA%(LO1Rb=h?5jiTs93 zPLR78p+3t>z4|j=<>2i4b`ketv}9Ax#B0)hn7@bFl;rDfP8p7u9XcEb!5*PLKB(s7wQC2kzI^@ae)|DhNDmSy1bOLid%iIap@24A(q2XI!z_hkl-$1T10 z+KKugG4-}@u8(P^S3PW4x>an;XWEF-R^gB{`t8EiP{ZtAzoZ!JRuMRS__-Gg#Qa3{<;l__CgsF+nfmFNi}p z>rV!Y6B@cC>1up)KvaEQiAvQF!D>GCb+WZsGHjDeWFz?WVAHP65aIA8u6j6H35XNYlyy8>;cWe3ekr};b;$9)0G`zsc9LNsQ&D?hvuHRpBxH)r-1t9|Stc*u<}Ol&2N+wPMom}d15_TA=Aprp zjN-X3*Af$7cDWMWp##kOH|t;c2Pa9Ml4-)o~+7P;&q8teF-l}(Jt zTGKOQqJTeT!L4d}Qw~O0aanA$Vn9Rocp-MO4l*HK)t%hcp@3k0%&_*wwpKD6ThM)R z8k}&7?)YS1ZYKMiy?mn>VXiuzX7$Ixf7EW8+C4K^)m&eLYl%#T=MC;YPvD&w#$MMf zQ=>`@rh&&r!@X&v%ZlLF42L_c=5dSU^uymKVB>5O?AouR3vGv@ei%Z|GX5v1GK2R* zi!!}?+-8>J$JH^fPu@)E6(}9$d&9-j51T^n-e0Ze%Q^)lxuex$IL^XJ&K2oi`wG}QVGk2a7vC4X?+o^z zsCK*7`EUfSuQA*K@Plsi;)2GrayQOG9OYF82Hc@6aNN5ulqs1Of-(iZQdBI^U5of^ zZg2g=Xtad7$hfYu6l~KDQ}EU;oIj(3nO#u9PDz=eO3(iax7OCmgT2p_7&^3q zg7aQ;Vpng*)kb6=sd5?%j5Dm|HczSChMo8HHq_L8R;BR5<~DVyU$8*Tk5}g0eW5x7 z%d)JFZ{(Y<#OTKLBA1fwLM*fH7Q~7Sc2Ne;mVWqt-*o<;| z^1@vo_KTYaMnO$7fbLL+qh#R$9bvnpJ$RAqG+z8h|} z3F5iwG*(sCn9Qbyg@t0&G}3fE0jGq3J!JmG2K&$urx^$z95) z7h?;4vE4W=v)uZ*Eg3M^6f~|0&T)2D;f+L_?M*21-I1pnK(pT$5l#QNlT`SidYw~o z{`)G)Asv#cue)Ax1RNWiRUQ(tQ(bzd-f2U4xlJK+)ZWBxdq#fp=A>+Qc%-tl(c)`t z$e2Ng;Rjvnbu7((;v4LF9Y1?0el9hi!g>G{^37{ z`^s-03Z5jlnD%#Mix19zkU_OS|86^_x4<0(*YbPN}mi-$L?Z4K(M|2&VV*n*ZYN_UqI?eKZi3!b)i z%n3dzUPMc-dc|q}TzvPy!VqsEWCZL(-eURDRG4+;Eu!LugSSI4Fq$Ji$Dp08`pfP_C5Yx~`YKcywlMG;$F z)R5!kVml_Wv6MSpeXjG#g?kJ0t_MEgbXlUN3k|JJ%N>|2xn8yN>>4qxh!?dGI}s|Y zDTKd^JCrRSN+%w%D_uf=Tj6wIV$c*g8D96jb^Kc#>5Fe-XxKC@!pIJw0^zu;`_yeb zhUEm-G*C=F+jW%cP(**b61fTmPn2WllBr4SWNdKe*P8VabZsh0-R|?DO=0x`4_QY) zR7sthW^*BofW7{Sak&S1JdiG?e=SfL24Y#w_)xrBVhGB-13q$>mFU|wd9Xqe-o3{6 zSn@@1@&^)M$rxb>UmFuC+pkio#T;mSnroMVZJ%nZ!uImi?%KsIX#@JU2VY(`kGb1A z7+1MEG)wd@)m^R|a2rXeviv$!emwcY(O|M*xV!9%tBzarBOG<4%gI9SW;Um_gth4=gznYzOFd)y8e+3APCkL)i-OI`;@7-mCJgE`js(M} z;~ZcW{{FMVVO)W>VZ}ILouF#lWGb%Couu}TI4kubUUclW@jEn6B_^v!Ym*(T*4HF9 zWhNKi8%sS~viSdBtnrq!-Dc5(G^XmR>DFx8jhWvR%*8!m*b*R8e1+`7{%FACAK`7 zzdy8TmBh?FVZ0vtw6npnWwM~XjF2fNvV#ZlGG z?FxHkXHN>JqrBYoPo$)zNC7|XrQfcqmEXWud~{j?La6@kbHG@W{xsa~l1=%eLly8B z4gCIH05&Y;6O2uFSopNqP|<$ml$N40^ikxw0`o<~ywS1(qKqQN!@?Ykl|bE4M?P+e zo$^Vs_+x)iuw?^>>`$&lOQOUkZ5>+OLnRA)FqgpDjW&q*WAe(_mAT6IKS9;iZBl8M z<@=Y%zcQUaSBdrs27bVK`c$)h6A1GYPS$y(FLRD5Yl8E3j0KyH08#8qLrsc_qlws; znMV%Zq8k+&T2kf%6ZO^2=AE9>?a587g%-={X}IS~P*I(NeCF9_9&`)|ok0iiIun zo+^odT0&Z4k;rn7I1v87=z!zKU(%gfB$(1mrRYeO$sbqM22Kq68z9wgdg8HBxp>_< zn9o%`f?sVO=IN#5jSX&CGODWlZfQ9A)njK2O{JutYwRZ?n0G_p&*uwpE`Md$iQxrd zoQfF^b8Ou)+3BO_3_K5y*~?<(BF@1l+@?Z6;^;U>qlB)cdro;rxOS1M{Az$s^9o5sXDCg8yD<=(pKI*0e zLk>@lo#&s0)^*Q+G)g}C0IErqfa9VbL*Qe=OT@&+N8m|GJF7jd83vY#SsuEv2s{Q> z>IpoubNs>D_5?|kXGAPgF@mb_9<%hjU;S0C8idI)a=F#lPLuQJ^7OnjJlH_Sks9JD zMl1td%YsWq3YWhc;E$H1<0P$YbSTqs`JKY%(}svsifz|h8BHguL82dBl+z0^YvWk8 zGy;7Z0v5_FJ2A$P0wIr)lD?cPR%cz>kde!=W%Ta^ih+Dh4UKdf7ip?rBz@%y2&>`6 zM#q{JXvW9ZlaSk1oD!n}kSmcDa2v6T^Y-dy+#fW^y>eS8_%<7tWXUp8U@s$^{JFfKMjDAvR z$YmVB;n3ofl!ro9RNT!TpQpcycXCR}$9k5>IPWDXEenQ58os?_weccrT+Bh5sLoiH zZ_7~%t(vT)ZTEO= zb0}@KaD{&IyK_sd8b$`Qz3%UA`nSo zn``!BdCeN!#^G;lK@G2ron*0jQhbdw)%m$2;}le@z~PSLnU-z@tL)^(p%P>OO^*Ff zNRR9oQ`W+x^+EU+3BpluwK77|B3=8QyT|$V;02bn_LF&3LhLA<#}{{)jE)}CiW%VEU~9)SW+=F%7U-iYlQ&q!#N zwI2{(h|Pi&<8_fqvT*}FLN^0CxN}#|3I9G_xmVg$gbn2ZdhbmGk7Q5Q2Tm*ox8NMo zv`iaZW|ZEOMyQga5fts?&T-eCCC9pS0mj7v0SDkD=*^MxurP@89v&Z#3q{FM!a_nr zb?KzMv`BBFOew>4!ft@A&(v-kWXny-j#egKef|#!+3>26Qq0 zv!~8ev4G`7Qk>V1TaMT-&ziqoY3IJp8_S*%^1j73D|=9&;tDZH^!LYFMmME4*Wj(S zRt~Q{aLb_O;wi4u&=}OYuj}Lw*j$@z*3>4&W{)O-oi@9NqdoU!=U%d|se&h?^$Ip# z)BY+(1+cwJz!yy4%l(aLC;T!~Ci>yAtXJb~b*yr&v7f{YCU8P|N1v~H`xmGsG)g)y z4%mv=cPd`s7a*#OR7f0lpD$ueP>w8qXj0J&*7xX+U!uat5QNk>zwU$0acn5p=$88L=jn_QCSYkTV;1~(yUem#0gB`FeqY98sf=>^@ z_MCdvylv~WL%y_%y_FE1)j;{Szj1+K7Lr_y=V+U zk6Tr;>XEqlEom~QGL!a+wOf(@ZWoxE<$^qHYl*H1a~kk^BLPn785%nQb$o;Cuz0h& za9LMx^bKEbPS%e8NM33Jr|1T|ELC(iE!FUci38xW_Y7kdHid#2ie+XZhP;2!Z;ZAM zB_cXKm)VrPK!SK|PY00Phwrpd+x0_Aa;}cDQvWKrwnQrqz##_gvHX2ja?#_{f#;bz`i>C^^ zTLDy;6@HZ~XQi7rph!mz9k!m;KchA)uMd`RK4WLK7)5Rl48m#l>b(#`WPsl<0j z-sFkSF6>Nk|LKnHtZ`W_NnxZP62&w)S(aBmmjMDKzF%G;3Y?FUbo?>b5;0j8Lhtc4 zr*8d5Y9>g@FFZaViw7c16VsHcy0u7M%6>cG1=s=Dtx?xMJSKIu9b6GU8$uSzf43Y3 zYq|U+IWfH;SM~*N1v`KJo!|yfLxTFS?oHsr3qvzeVndVV^%BWmW6re_S!2;g<|Oao z+N`m#*i!)R%i1~NO-xo{qpwL0ZrL7hli;S z3L0lQ_z}z`fdK39Mg~Zd*%mBdD;&5EXa~@H(!###L`ycr7gW`f)KRuqyHL3|uyy3h zSS^td#E&Knc$?dXs*{EnPYOp^-vjAc-h4z#XkbG&REC7;0>z^^Z}i8MxGKerEY z>l?(wReOlXEsNE5!DO&ZWyxY)gG#FSZs%fXuzA~XIAPVp-%yb2XLSV{1nH6{)5opg z(dZKckn}Q4Li-e=eUDs1Psg~5zdn1>ql(*(nn6)iD*OcVkwmKL(A{fix(JhcVB&}V zVt*Xb!{gzvV}dc446>(D=SzfCu7KB`oMjv6kPzSv&B>>HLSJP|wN`H;>oRw*tl#N) z*zZ-xwM7D*AIsBfgqOjY1Mp9aq$kRa^dZU_xw~KxP;|q(m+@e+YSn~`wEJzM|Ippb zzb@%;hB7iH4op9SqmX?j!KP2chsb79(mFossBO-Zj8~L}9L%R%Bw<`^X>hjkCY5SG z7lY!8I2mB#z)1o;*3U$G)3o0A&{0}#B;(zPd2`OF`Gt~8;0Re8nIseU z_yzlf$l+*-wT~_-cYk$^wTJ@~7i@u(CZs9FVkJCru<*yK8&>g+t*!JqCN6RH%8S-P zxH8+Cy#W?!;r?cLMC(^BtAt#xPNnwboI*xWw#T|IW^@3|q&QYY6Ehxoh@^URylR|T zne-Y6ugE^7p5bkRDWIh)?JH5V^ub82l-LuVjDr7UT^g`q4dB&mBFRWGL_C?hoeL(% zo}ocH5t7|1Mda}T!^{Qt9vmA2ep4)dQSZO>?Eq8}qRp&ZJ?-`Tnw+MG(eDswP(L*X3ahC2Ad0_wD^ff9hfzb%Jd`IXx5 zae@NMzBXJDwJS?7_%!TB^E$N8pvhOHDK$7YiOelTY`6KX8hK6YyT$tk*adwN>s^Kp zwM3wGVPhwKU*Yq-*BCs}l`l#Tej(NQ>jg*S0TN%D+GcF<14Ms6J`*yMY;W<-mMN&-K>((+P}+t+#0KPGrzjP zJ~)=Bcz%-K!L5ozIWqO(LM)l_9lVOc4*S65&DKM#TqsiWNG{(EZQw!bc>qLW`=>p-gVJ;T~aN2D_- z{>SZC=_F+%hNmH6ub%Ykih0&YWB!%sd%W5 zHC2%QMP~xJgt4>%bU>%6&uaDtSD?;Usm}ari0^fcMhi_)JZgb1g5j zFl4`FQ*%ROfYI}e7RIq^&^a>jZF23{WB`T>+VIxj%~A-|m=J7Va9FxXV^%UwccSZd zuWINc-g|d6G5;95*%{e;9S(=%yngpfy+7ao|M7S|Jb0-4+^_q-uIqVS&ufU880UDH*>(c)#lt2j zzvIEN>>$Y(PeALC-D?5JfH_j+O-KWGR)TKunsRYKLgk7eu4C{iF^hqSz-bx5^{z0h ze2+u>Iq0J4?)jIo)}V!!m)%)B;a;UfoJ>VRQ*22+ncpe9f4L``?v9PH&;5j{WF?S_C>Lq>nkChZB zjF8(*v0c(lU^ZI-)_uGZnnVRosrO4`YinzI-RSS-YwjYh3M`ch#(QMNw*)~Et7Qpy z{d<3$4FUAKILq9cCZpjvKG#yD%-juhMj>7xIO&;c>_7qJ%Ae8Z^m)g!taK#YOW3B0 zKKSMOd?~G4h}lrZbtPk)n*iOC1~mDhASGZ@N{G|dF|Q^@1ljhe=>;wusA&NvY*w%~ zl+R6B^1yZiF)YN>0ms%}qz-^U-HVyiN3R9k1q4)XgDj#qY4CE0)52%evvrrOc898^ z*^)XFR?W%g0@?|6Mxo1ZBp%(XNv_RD-<#b^?-Fs+NL^EUW=iV|+Vy*F%;rBz~pN7%-698U-VMfGEVnmEz7fL1p)-5sLT zL;Iz>FCLM$p$c}g^tbkGK1G$IALq1Gd|We@&TtW!?4C7x4l*=4oF&&sr0Hu`x<5!m zhX&&Iyjr?AkNXU_5P_b^Q3U9sy#f6ZF@2C96$>1k*E-E%DjwvA{VL0PdU~suN~DZo zm{T!>sRdp`Ldpp9olrH@(J$QyGq!?#o1bUo=XP2OEuT3`XzI>s^0P{manUaE4pI%! zclQq;lbT;nx7v3tR9U)G39h?ryrxzd0xq4KX7nO?piJZbzT_CU&O=T(Vt;>jm?MgC z2vUL#*`UcMsx%w#vvjdamHhmN!(y-hr~byCA-*iCD};#l+bq;gkwQ0oN=AyOf@8ow>Pj<*A~2*dyjK}eYdN);%!t1 z6Y=|cuEv-|5BhA?n2Db@4s%y~(%Wse4&JXw=HiO48%c6LB~Z0SL1(k^9y?ax%oj~l zf7(`iAYLdPRq*ztFC z7VtAb@s{as%&Y;&WnyYl+6Wm$ru*u!MKIg_@01od-iQft0rMjIj8e7P9eKvFnx_X5 zd%pDg-|8<>T2Jdqw>AII+fe?CgP+fL(m0&U??QL8YzSjV{SFi^vW~;wN@or_(q<0Y zRt~L}#JRcHOvm$CB)T1;;7U>m%)QYBLTR)KTARw%zoDxgssu5#v{UEVIa<>{8dtkm zXgbCGp$tfue+}#SD-PgiNT{Zu^YA9;4BnM(wZ9-biRo_7pN}=aaimjYgC=;9@g%6< zxol5sT_$<8{LiJ6{l1+sV)Z_QdbsfEAEMw!5*zz6)Yop?T0DMtR_~wfta)E6_G@k# zZRP11D}$ir<`IQ`<(kGfAS?O-DzCyuzBq6dxGTNNTK?r^?zT30mLY!kQ=o~Hv*k^w zvq!LBjW=zzIi%UF@?!g9vt1CqdwV(-2LYy2=E@Z?B}JDyVkluHtzGsWuI1W5svX~K z&?UJ45$R7g>&}SFnLnmw09R2tUgmr_w6mM9C}8GvQX>nL&5R#xBqnp~Se(I>R42`T zqZe9p6G(VzNB3QD><8+y%{e%6)sZDRXTR|MI zM#eZmao-~_`N|>Yf;a;7yvd_auTG#B?Vz5D1AHx=zpVUFe7*hME z+>KH5h1In8hsVhrstc>y0Q!FHR)hzgl+*Q&5hU9BVJlNGRkXiS&06eOBV^dz3;4d5 zeYX%$62dNOprZV$px~#h1RH?_E%oD6y;J;pF%~y8M)8pQ0olYKj6 zE+hd|7oY3ot=j9ZZ))^CCPADL6Jw%)F@A{*coMApcA$7fZ{T@3;WOQ352F~q6`Mgi z$RI6$8)a`Aaxy<8Bc;{wlDA%*%(msBh*xy$L-cBJvQ8hj#FCyT^%+Phw1~PaqyDou^JR0rxDkSrmAdjeYDFDZ`E z)G3>XtpaSPDlydd$RGHg;#4|4{aP5c_Om z2u5xgnhnA)K%8iU==}AxPxZCYC)lyOlj9as#`5hZ=<6<&DB%i_XCnt5=pjh?iusH$ z>)E`@HNZcAG&RW3Ys@`Ci{;8PNzE-ZsPw$~Wa!cP$ye+X6;9ceE}ah+3VY7Mx}#0x zbqYa}eO*FceiY2jNS&2cH9Y}(;U<^^cWC5Ob&)dZedvZA9HewU3R;gRQ)}hUdf+~Q zS_^4ds*W1T#bxS?%RH&<739q*n<6o|mV;*|1s>ly-Biu<2*{!!0#{_234&9byvn0* z5=>{95Zfb{(?h_Jk#ocR$FZ78O*UTOxld~0UF!kyGM|nH%B*qf)Jy}N!uT9NGeM19 z-@=&Y0yGGo_dw!FD>juk%P$6$qJkj}TwLBoefi;N-$9LAeV|)|-ET&culW9Sb_pc_ zp{cXI0>I0Jm_i$nSvGnYeLSSj{ccVS2wyL&0x~&5v;3Itc82 z5lIAkfn~wcY-bQB$G!ufWt%qO;P%&2B_R5UKwYxMemIaFm)qF1rA zc>gEihb=jBtsXCi0T%J37s&kt*3$s7|6)L(%UiY)6axuk{6RWIS8^+u;)6!R?Sgap z9|6<0bx~AgVi|*;zL@2x>Pbt2Bz*uv4x-`{F)XatTs`S>unZ#P^ZiyjpfL_q2z^fqgR-fbOcG=Y$q>ozkw1T6dH8-)&ww+z?E0 zR|rV(9bi6zpX3Ub>PrPK!{X>e$C66qCXAeFm)Y+lX8n2Olt7PNs*1^si)j!QmFV#t z0P2fyf$N^!dyTot&`Ew5{i5u<8D`8U`qs(KqaWq5iOF3x2!-z65-|HsyYz(MAKZ?< zCpQR;E)wn%s|&q(LVm0Ab>gdmCFJeKwVTnv@Js%!At;I=A>h=l=p^&<4;Boc{$@h< z38v`3&2wJtka@M}GS%9!+SpJ}sdtoYzMevVbnH+d_eMxN@~~ zZq@k)7V5f8u!yAX2qF3qjS7g%n$JuGrMhQF!&S^7(%Y{rP*w2FWj(v_J{+Hg*}wdWOd~pHQ19&n3RWeljK9W%sz&Y3Tm3 zR`>6YR54%qBHGa)2xbs`9cs_EsNHxsfraEgZ)?vrtooeA0sPKJK7an){ngtV@{SBa zkO6ORr1_Xqp+`a0e}sC*_y(|RKS13ikmHp3C^XkE@&wjbGWrt^INg^9lDz#B;bHiW zkK4{|cg08b!yHFSgPca5)vF&gqCgeu+c82%&FeM^Bb}GUxLy-zo)}N;#U?sJ2?G2BNe*9u_7kE5JeY!it=f`A_4gV3} z`M!HXZy#gN-wS!HvHRqpCHUmjiM;rVvpkC!voImG%OFVN3k(QG@X%e``VJSJ@Z7tb z*Onlf>z^D+&$0!4`IE$;2-NSO9HQWd+UFW(r;4hh;(j^p4H-~6OE!HQp^96v?{9Zt z;@!ZcccV%C2s6FMP#qvo4kG6C04A>XILt>JW}%0oE&HM5f6 zYLD!;My>CW+j<~=Wzev{aYtx2ZNw|ptTFV(4;9`6Tmbz6K1)fv4qPXa2mtoPt&c?P zhmO+*o8uP3ykL6E$il00@TDf6tOW7fmo?Oz_6GU^+5J=c22bWyuH#aNj!tT-^IHrJ zu{aqTYw@q;&$xDE*_kl50Jb*dp`(-^p={z}`rqECTi~3 z>0~A7L6X)=L5p#~$V}gxazgGT7$3`?a)zen>?TvAuQ+KAIAJ-s_v}O6@`h9n-sZk> z`3{IJeb2qu9w=P*@q>iC`5wea`KxCxrx{>(4{5P+!cPg|pn~;n@DiZ0Y>;k5mnKeS z!LIfT4{Lgd=MeysR5YiQKCeNhUQ;Os1kAymg6R!u?j%LF z4orCszIq_n52ulpes{(QN|zirdtBsc{9^Z72Ycb2ht?G^opkT_#|4$wa9`)8k3ilU z%ntAi`nakS1r10;#k^{-ZGOD&Z2|k=p40hRh5D7(&JG#Cty|ECOvwsSHkkSa)36$4 z?;v#%@D(=Raw(HP5s>#4Bm?f~n1@ebH}2tv#7-0l-i^H#H{PC|F@xeNS+Yw{F-&wH z07)bj8MaE6`|6NoqKM~`4%X> zKFl&7g1$Z3HB>lxn$J`P`6GSb6CE6_^NA1V%=*`5O!zP$a7Vq)IwJAki~XBLf=4TF zPYSL}>4nOGZ`fyHChq)jy-f{PKFp6$plHB2=;|>%Z^%)ecVue(*mf>EH_uO^+_zm? zJATFa9SF~tFwR#&0xO{LLf~@}s_xvCPU8TwIJgBs%FFzjm`u?1699RTui;O$rrR{# z1^MqMl5&6)G%@_k*$U5Kxq84!AdtbZ!@8FslBML}<`(Jr zenXrC6bFJP=R^FMBg7P?Pww-!a%G@kJH_zezKvuWU0>m1uyy}#Vf<$>u?Vzo3}@O% z1JR`B?~Tx2)Oa|{DQ_)y9=oY%haj!80GNHw3~qazgU-{|q+Bl~H94J!a%8UR?XsZ@ z0*ZyQugyru`V9b(0OrJOKISfi89bSVR zQy<+i_1XY}4>|D%X_`IKZUPz6=TDb)t1mC9eg(Z=tv zq@|r37AQM6A%H%GaH3szv1L^ku~H%5_V*fv$UvHl*yN4iaqWa69T2G8J2f3kxc7UE zOia@p0YNu_q-IbT%RwOi*|V|&)e5B-u>4=&n@`|WzH}BK4?33IPpXJg%`b=dr_`hU z8JibW_3&#uIN_#D&hX<)x(__jUT&lIH$!txEC@cXv$7yB&Rgu){M`9a`*PH} zRcU)pMWI2O?x;?hzR{WdzKt^;_pVGJAKKd)F$h;q=Vw$MP1XSd<;Mu;EU5ffyKIg+ z&n-Nb?h-ERN7(fix`htopPIba?0Gd^y(4EHvfF_KU<4RpN0PgVxt%7Yo99X*Pe|zR z?ytK&5qaZ$0KSS$3ZNS$$k}y(2(rCl=cuYZg{9L?KVgs~{?5adxS))Upm?LDo||`H zV)$`FF3icFmxcQshXX*1k*w3O+NjBR-AuE70=UYM*7>t|I-oix=bzDwp2*RoIwBp@r&vZukG; zyi-2zdyWJ3+E?{%?>e2Ivk`fAn&Ho(KhGSVE4C-zxM-!j01b~mTr>J|5={PrZHOgO zw@ND3=z(J7D>&C7aw{zT>GHhL2BmUX0GLt^=31RRPSnjoUO9LYzh_yegyPoAKhAQE z>#~O27dR4&LdQiak6={9_{LN}Z>;kyVYKH^d^*!`JVSXJlx#&r4>VnP$zb{XoTb=> zZsLvh>keP3fkLTIDdpf-@(ADfq4=@X=&n>dyU0%dwD{zsjCWc;r`-e~X$Q3NTz_TJ zOXG|LMQQIjGXY3o5tBm9>k6y<6XNO<=9H@IXF;63rzsC=-VuS*$E{|L_i;lZmHOD< zY92;>4spdeRn4L6pY4oUKZG<~+8U-q7ZvNOtW0i*6Q?H`9#U3M*k#4J;ek(MwF02x zUo1wgq9o6XG#W^mxl>pAD)Ll-V5BNsdVQ&+QS0+K+?H-gIBJ-ccB1=M_hxB6qcf`C zJ?!q!J4`kLhAMry4&a_0}up{CFevcjBl|N(uDM^N5#@&-nQt2>z*U}eJGi}m5f}l|IRVj-Q;a>wcLpK5RRWJ> zysdd$)Nv0tS?b~bw1=gvz3L_ZAIdDDPj)y|bp1;LE`!av!rODs-tlc}J#?erTgXRX z$@ph%*~_wr^bQYHM7<7=Q=45v|Hk7T=mDpW@OwRy3A_v`ou@JX5h!VI*e((v*5Aq3 zVYfB4<&^Dq5%^?~)NcojqK`(VXP$`#w+&VhQOn%;4pCkz;NEH6-FPHTQ+7I&JE1+Ozq-g43AEZV>ceQ^9PCx zZG@OlEF~!Lq@5dttlr%+gNjRyMwJdJU(6W_KpuVnd{3Yle(-p#6erIRc${l&qx$HA z89&sp=rT7MJ=DuTL1<5{)wtUfpPA|Gr6Q2T*=%2RFm@jyo@`@^*{5{lFPgv>84|pv z%y{|cVNz&`9C*cUely>-PRL)lHVErAKPO!NQ3<&l5(>Vp(MuJnrOf^4qpIa!o3D7( z1bjn#Vv$#or|s7Hct5D@%;@48mM%ISY7>7@ft8f?q~{s)@BqGiupoK1BAg?PyaDQ1 z`YT8{0Vz{zBwJ={I4)#ny{RP{K1dqzAaQN_aaFC%Z>OZ|^VhhautjDavGtsQwx@WH zr|1UKk^+X~S*RjCY_HN!=Jx>b6J8`Q(l4y|mc<6jnkHVng^Wk(A13-;AhawATsmmE#H%|8h}f1frs2x@Fwa_|ea+$tdG2Pz{7 z!ox^w^>^Cv4e{Xo7EQ7bxCe8U+LZG<_e$RnR?p3t?s^1Mb!ieB z#@45r*PTc_yjh#P=O8Zogo+>1#|a2nJvhOjIqKK1U&6P)O%5s~M;99O<|Y9zomWTL z666lK^QW`)cXV_^Y05yQZH3IRCW%25BHAM$c0>w`x!jh^15Zp6xYb!LoQ zr+RukTw0X2mxN%K0%=8|JHiaA3pg5+GMfze%9o5^#upx0M?G9$+P^DTx7~qq9$Qoi zV$o)yy zuUq>3c{_q+HA5OhdN*@*RkxRuD>Bi{Ttv_hyaaB;XhB%mJ2Cb{yL;{Zu@l{N?!GKE7es6_9J{9 zO(tmc0ra2;@oC%SS-8|D=omQ$-Dj>S)Utkthh{ovD3I%k}HoranSepC_yco2Q8 zY{tAuPIhD{X`KbhQIr%!t+GeH%L%q&p z3P%<-S0YY2Emjc~Gb?!su85}h_qdu5XN2XJUM}X1k^!GbwuUPT(b$Ez#LkG6KEWQB z7R&IF4srHe$g2R-SB;inW9T{@+W+~wi7VQd?}7||zi!&V^~o0kM^aby7YE_-B63^d zf_uo8#&C77HBautt_YH%v6!Q>H?}(0@4pv>cM6_7dHJ)5JdyV0Phi!)vz}dv{*n;t zf(+#Hdr=f8DbJqbMez)(n>@QT+amJ7g&w6vZ-vG^H1v~aZqG~u!1D(O+jVAG0EQ*aIsr*bsBdbD`)i^FNJ z&B@yxqPFCRGT#}@dmu-{0vp47xk(`xNM6E=7QZ5{tg6}#zFrd8Pb_bFg7XP{FsYP8 zbvWqG6#jfg*4gvY9!gJxJ3l2UjP}+#QMB(*(?Y&Q4PO`EknE&Cb~Yb@lCbk;-KY)n zzbjS~W5KZ3FV%y>S#$9Sqi$FIBCw`GfPDP|G=|y32VV-g@a1D&@%_oAbB@cAUx#aZ zlAPTJ{iz#Qda8(aNZE&0q+8r3&z_Ln)b=5a%U|OEcc3h1f&8?{b8ErEbilrun}mh3 z$1o^$-XzIiH|iGoJA`w`o|?w3m*NX|sd$`Mt+f*!hyJvQ2fS*&!SYn^On-M|pHGlu z4SC5bM7f6BAkUhGuN*w`97LLkbCx=p@K5RL2p>YpDtf{WTD|d3ucb6iVZ-*DRtoEA zCC5(x)&e=giR_id>5bE^l%Mxx>0@FskpCD4oq@%-Fg$8IcdRwkfn;DsjoX(v;mt3d z_4Mnf#Ft4x!bY!7Hz?RRMq9;5FzugD(sbt4up~6j?-or+ch~y_PqrM2hhTToJjR_~ z)E1idgt7EW>G*9%Q^K;o_#uFjX!V2pwfpgi>}J&p_^QlZki!@#dkvR`p?bckC`J*g z=%3PkFT3HAX2Q+dShHUbb1?ZcK8U7oaufLTCB#1W{=~k0Jabgv>q|H+GU=f-y|{p4 zwN|AE+YbCgx=7vlXE?@gkXW9PaqbO#GB=4$o0FkNT#EI?aLVd2(qnPK$Yh%YD%v(mdwn}bgsxyIBI^)tY?&G zi^2JfClZ@4b{xFjyTY?D61w@*ez2@5rWLpG#34id?>>oPg{`4F-l`7Lg@D@Hc}On} zx%BO4MsLYosLGACJ-d?ifZ35r^t*}wde>AAWO*J-X%jvD+gL9`u`r=kP zyeJ%FqqKfz8e_3K(M1RmB?gIYi{W7Z<THP2ihue0mbpu5n(x_l|e1tw(q!#m5lmef6ktqIb${ zV+ee#XRU}_dDDUiV@opHZ@EbQ<9qIZJMDsZDkW0^t3#j`S)G#>N^ZBs8k+FJhAfu< z%u!$%dyP3*_+jUvCf-%{x#MyDAK?#iPfE<(@Q0H7;a125eD%I(+!x1f;Sy`e<9>nm zQH4czZDQmW7^n>jL)@P@aAuAF$;I7JZE5a8~AJI5CNDqyf$gjloKR7C?OPt9yeH}n5 zNF8Vhmd%1O>T4EZD&0%Dt7YWNImmEV{7QF(dy!>q5k>Kh&Xy8hcBMUvVV~Xn8O&%{ z&q=JCYw#KlwM8%cu-rNadu(P~i3bM<_a{3!J*;vZhR6dln6#eW0^0kN)Vv3!bqM`w z{@j*eyzz=743dgFPY`Cx3|>ata;;_hQ3RJd+kU}~p~aphRx`03B>g4*~f%hUV+#D9rYRbsGD?jkB^$3XcgB|3N1L& zrmk9&Dg450mAd=Q_p?gIy5Zx7vRL?*rpNq76_rysFo)z)tp0B;7lSb9G5wX1vC9Lc z5Q8tb-alolVNWFsxO_=12o}X(>@Mwz1mkYh1##(qQwN=7VKz?61kay8A9(94Ky(4V zq6qd2+4a20Z0QRrmp6C?4;%U?@MatfXnkj&U6bP_&2Ny}BF%4{QhNx*Tabik9Y-~Z z@0WV6XD}aI(%pN}oW$X~Qo_R#+1$@J8(31?zM`#e`#(0f<-AZ^={^NgH#lc?oi(Mu zMk|#KR^Q;V@?&(sh5)D;-fu)rx%gXZ1&5)MR+Mhssy+W>V%S|PRNyTAd}74<(#J>H zR(1BfM%eIv0+ngHH6(i`?-%_4!6PpK*0X)79SX0X$`lv_q>9(E2kkkP;?c@rW2E^Q zs<;`9dg|lDMNECFrD3jTM^Mn-C$44}9d9Kc z#>*k&e#25;D^%82^1d@Yt{Y91MbEu0C}-;HR4+IaCeZ`l?)Q8M2~&E^FvJ?EBJJ(% zz1>tCW-E~FB}DI}z#+fUo+=kQME^=eH>^%V8w)dh*ugPFdhMUi3R2Cg}Zak4!k_8YW(JcR-)hY8C zXja}R7@%Q0&IzQTk@M|)2ViZDNCDRLNI)*lH%SDa^2TG4;%jE4n`8`aQAA$0SPH2@ z)2eWZuP26+uGq+m8F0fZn)X^|bNe z#f{qYZS!(CdBdM$N2(JH_a^b#R2=>yVf%JI_ieRFB{w&|o9txwMrVxv+n78*aXFGb z>Rkj2yq-ED<)A46T9CL^$iPynv`FoEhUM10@J+UZ@+*@_gyboQ>HY9CiwTUo7OM=w zd~$N)1@6U8H#Zu(wGLa_(Esx%h@*pmm5Y9OX@CY`3kPYPQx@z8yAgtm(+agDU%4?c zy8pR4SYbu8vY?JX6HgVq7|f=?w(%`m-C+a@E{euXo>XrGmkmFGzktI*rj*8D z)O|CHKXEzH{~iS+6)%ybRD|JRQ6j<+u_+=SgnJP%K+4$st+~XCVcAjI9e5`RYq$n{ zzy!X9Nv7>T4}}BZpSj9G9|(4ei-}Du<_IZw+CB`?fd$w^;=j8?vlp(#JOWiHaXJjB0Q00RHJ@sG6N#y^H7t^&V} z;VrDI4?75G$q5W9mV=J2iP24NHJy&d|HWHva>FaS#3AO?+ohh1__FMx;?`f{HG3v0 ztiO^Wanb>U4m9eLhoc_2B(ca@YdnHMB*~aYO+AE(&qh@?WukLbf_y z>*3?Xt-lxr?#}y%kTv+l8;!q?Hq8XSU+1E8x~o@9$)zO2z9K#(t`vPDri`mKhv|sh z{KREcy`#pnV>cTT7dm7M9B@9qJRt3lfo(C`CNkIq@>|2<(yn!AmVN?ST zbX_`JjtWa3&N*U{K7FYX8})*D#2@KBae` zhKS~s!r%SrXdhCsv~sF}7?ocyS?afya6%rDBu6g^b2j#TOGp^1zrMR}|70Z>CeYq- z1o|-=FBKlu{@;pm@QQJ_^!&hzi;0Z_Ho){x3O1KQ#TYk=rAt9`YKC0Y^}8GWIN{QW znYJyVTrmNvl!L=YS1G8BAxGmMUPi+Q7yb0XfG`l+L1NQVSbe^BICYrD;^(rke{jWCEZOtVv3xFze!=Z&(7}!)EcN;v0Dbit?RJ6bOr;N$ z=nk8}H<kCEE+IK3z<+3mkn4q!O7TMWpKShWWWM)X*)m6k%3luF6c>zOsFccvfLWf zH+mNkh!H@vR#~oe=ek}W3!71z$Dlj0c(%S|sJr>rvw!x;oCek+8f8s!U{DmfHcNpO z9>(IKOMfJwv?ey`V2ysSx2Npeh_x#bMh)Ngdj$al;5~R7Ac5R2?*f{hI|?{*$0qU- zY$6}ME%OGh^zA^z9zJUs-?a4ni8cw_{cYED*8x{bWg!Fn9)n;E9@B+t;#k}-2_j@# zg#b%R(5_SJAOtfgFCBZc`n<&z6)%nOIu@*yo!a% zpLg#36KBN$01W{b;qWN`Tp(T#jh%;Zp_zpS64lvBVY2B#UK)p`B4Oo)IO3Z&D6<3S zfF?ZdeNEnzE{}#gyuv)>;z6V{!#bx)` zY;hL*f(WVD*D9A4$WbRKF2vf;MoZVdhfWbWhr{+Db5@M^A4wrFReuWWimA4qp`GgoL2`W4WPUL5A=y3Y3P z%G?8lLUhqo@wJW8VDT`j&%YY7xh51NpVYlsrk_i4J|pLO(}(b8_>%U2M`$iVRDc-n zQiOdJbroQ%*vhN{!{pL~N|cfGooK_jTJCA3g_qs4c#6a&_{&$OoSQr_+-O^mKP=Fu zGObEx`7Qyu{nHTGNj(XSX*NPtAILL(0%8Jh)dQh+rtra({;{W2=f4W?Qr3qHi*G6B zOEj7%nw^sPy^@05$lOCjAI)?%B%&#cZ~nC|=g1r!9W@C8T0iUc%T*ne z)&u$n>Ue3FN|hv+VtA+WW)odO-sdtDcHfJ7s&|YCPfWaVHpTGN46V7Lx@feE#Od%0XwiZy40plD%{xl+K04*se zw@X4&*si2Z_0+FU&1AstR)7!Th(fdaOlsWh`d!y=+3m!QC$Zlkg8gnz!}_B7`+wSz z&kD?6{zPnE3uo~Tv8mLP%RaNt2hcCJBq=0T>%MW~Q@Tpt2pPP1?KcywH>in5@ zx+5;xu-ltFfo5vLU;2>r$-KCHjwGR&1XZ0YNyrXXAUK!FLM_7mV&^;;X^*YH(FLRr z`0Jjg7wiq2bisa`CG%o9i)o1`uG?oFjU_Zrv1S^ipz$G-lc^X@~6*)#%nn+RbgksJfl{w=k31(q>7a!PCMp5YY{+Neh~mo zG-3dd!0cy`F!nWR?=9f_KP$X?Lz&cLGm_ohy-|u!VhS1HG~e7~xKpYOh=GmiiU;nu zrZ5tWfan3kp-q_vO)}vY6a$19Q6UL0r znJ+iSHN-&w@vDEZ0V%~?(XBr|jz&vrBNLOngULxtH(Rp&U*rMY42n;05F11xh?k;n_DX2$4|vWIkXnbwfC z=ReH=(O~a;VEgVO?>qsP*#eOC9Y<_9Yt<6X}X{PyF7UXIA$f)>NR5P&4G_Ygq(9TwwQH*P>Rq>3T4I+t2X(b5ogXBAfNf!xiF#Gilm zp2h{&D4k!SkKz-SBa%F-ZoVN$7GX2o=(>vkE^j)BDSGXw?^%RS9F)d_4}PN+6MlI8*Uk7a28CZ)Gp*EK)`n5i z){aq=0SFSO-;sw$nAvJU-$S-cW?RSc7kjEBvWDr1zxb1J7i;!i+3PQwb=)www?7TZ zE~~u)vO>#55eLZW;)F(f0KFf8@$p)~llV{nO7K_Nq-+S^h%QV_CnXLi)p*Pq&`s!d zK2msiR;Hk_rO8`kqe_jfTmmv|$MMo0ll}mI)PO4!ikVd(ZThhi&4ZwK?tD-}noj}v zBJ?jH-%VS|=t)HuTk?J1XaDUjd_5p1kPZi6y#F6$lLeRQbj4hsr=hX z4tXkX2d5DeLMcAYTeYm|u(XvG5JpW}hcOs4#s8g#ihK%@hVz|kL=nfiBqJ{*E*WhC zht3mi$P3a(O5JiDq$Syu9p^HY&9~<#H89D8 zJm84@%TaL_BZ+qy8+T3_pG7Q%z80hnjN;j>S=&WZWF48PDD%55lVuC0%#r5(+S;WH zS7!HEzmn~)Ih`gE`faPRjPe^t%g=F ztpGVW=Cj5ZkpghCf~`ar0+j@A=?3(j@7*pq?|9)n*B4EQTA1xj<+|(Y72?m7F%&&& zdO44owDBPT(8~RO=dT-K4#Ja@^4_0v$O3kn73p6$s?mCmVDUZ+Xl@QcpR6R3B$=am z%>`r9r2Z79Q#RNK?>~lwk^nQlR=Hr-ji$Ss3ltbmB)x@0{VzHL-rxVO(++@Yr@Iu2 zTEX)_9sVM>cX$|xuqz~Y8F-(n;KLAfi*63M7mh&gsPR>N0pd9h!0bm%nA?Lr zS#iEmG|wQd^BSDMk0k?G>S-uE$vtKEF8Dq}%vLD07zK4RLoS?%F1^oZZI$0W->7Z# z?v&|a`u#UD=_>i~`kzBGaPj!mYX5g?3RC4$5EV*j0sV)>H#+$G6!ci=6`)85LWR=FCp-NUff`;2zG9nU6F~ z;3ZyE*>*LvUgae+uMf}aV}V*?DCM>{o31+Sx~6+sz;TI(VmIpDrN3z+BUj`oGGgLP z>h9~MP}Pw#YwzfGP8wSkz`V#}--6}7S9yZvb{;SX?6PM_KuYpbi~*=teZr-ga2QqIz{QrEyZ@>eN*qmy;N@FCBbRNEeeoTmQyrX;+ zCkaJ&vOIbc^2BD6_H+Mrcl?Nt7O{xz9R_L0ZPV_u!sz+TKbXmhK)0QWoe-_HwtKJ@@7=L+ z+K8hhf=4vbdg3GqGN<;v-SMIzvX=Z`WUa_91Yf89^#`G(f-Eq>odB^p-Eqx}ENk#&MxJ+%~Ad2-*`1LNT>2INPw?*V3&kE;tt?rQyBw? zI+xJD04GTz1$7~KMnfpkPRW>f%n|0YCML@ODe`10;^DXX-|Hb*IE%_Vi#Pn9@#ufA z_8NY*1U%VseqYrSm?%>F@`laz+f?+2cIE4Jg6 z_VTcx|DSEA`g!R%RS$2dSRM|9VQClsW-G<~=j5T`pTbu-x6O`R z98b;}`rPM(2={YiytrqX+uh65f?%XiPp`;4CcMT*E*dQJ+if9^D>c_Dk8A(cE<#r=&!& z_`Z01=&MEE+2@yr!|#El=yM}v>i=?w^2E_FLPy(*4A9XmCNy>cBWdx3U>1RylsItO z4V8T$z3W-qqq*H`@}lYpfh=>C!tieKhoMGUi)EpWDr;yIL&fy};Y&l|)f^QE*k~4C zH>y`Iu%#S)z)YUqWO%el*Z)ME#p{1_8-^~6UF;kBTW zMQ!eXQuzkR#}j{qb(y9^Y!X7&T}}-4$%4w@w=;w+>Z%uifR9OoQ>P?0d9xpcwa>7kTv2U zT-F?3`Q`7xOR!gS@j>7In>_h){j#@@(ynYh;nB~}+N6qO(JO1xA z@59Pxc#&I~I64slNR?#hB-4XE>EFU@lUB*D)tu%uEa))B#eJ@ZOX0hIulfnDQz-y8 z`CX@(O%_VC{Ogh&ot``jlDL%R!f>-8yq~oLGxBO?+tQb5%k@a9zTs!+=NOwSVH-cR zqFo^jHeXDA_!rx$NzdP;>{-j5w3QUrR<;}=u2|FBJ;D#v{SK@Z6mjeV7_kFmWt95$ zeGaF{IU?U>?W`jzrG_9=9}yN*LKyzz))PLE+)_jc#4Rd$yFGol;NIk(qO1$5VXR)+ zxF7%f4=Q!NzR>DVXUB&nUT&>Nyf+5QRF+Z`X-bB*7=`|Go5D1&h~ zflKLw??kpiRm0h3|1GvySC2^#kcFz^5{79KKlq@`(leBa=_4CgV9sSHr{RIJ^KwR_ zY??M}-x^=MD+9`v@I3jue=OCn0kxno#6i>b(XKk_XTp_LpI}X*UA<#* zsgvq@yKTe_dTh>q1aeae@8yur08S(Q^8kXkP_ty48V$pX#y9)FQa~E7P7}GP_CbCm zc2dQxTeW(-~Y6}im24*XOC8ySfH*HMEnW3 z4CXp8iK(Nk<^D$g0kUW`8PXn2kdcDk-H@P0?G8?|YVlIFb?a>QunCx%B9TzsqQQ~HD!UO7zq^V!v9jho_FUob&Hxi ztU1nNOK)a!gkb-K4V^QVX05*>-^i|{b`hhvQLyj`E1vAnj0fbqqO%r z6Q;X1x0dL~GqMv%8QindZ4CZ%7pYQW~ z9)I*#Gjref-q(4Z*E#1c&rE0-_(4;_M(V7rgH_7H;ps1s%GBmU z{4a|X##j#XUF2n({v?ZUUAP5k>+)^F)7n-npbV3jAlY8V3*W=fwroDS$c&r$>8aH` zH+irV{RG3^F3oW2&E%5hXgMH9>$WlqX76Cm+iFmFC-DToTa`AcuN9S!SB+BT-IA#3P)JW1m~Cuwjs`Ep(wDXE4oYmt*aU z!Naz^lM}B)JFp7ejro7MU9#cI>wUoi{lylR2~s)3M!6a=_W~ITXCPd@U9W)qA5(mdOf zd3PntGPJyRX<9cgX?(9~TZB5FdEHW~gkJXY51}?s4ZT_VEdwOwD{T2E-B>oC8|_ZwsPNj=-q(-kwy%xX2K0~H z{*+W`-)V`7@c#Iuaef=?RR2O&x>W0A^xSwh5MsjTz(DVG-EoD@asu<>72A_h<39_# zawWVU<9t{r*e^u-5Q#SUI6dV#p$NYEGyiowT>>d*or=Ps!H$-3={bB|An$GPkP5F1 zTnu=ktmF|6E*>ZQvk^~DX(k!N`tiLut*?3FZhs$NUEa4ccDw66-~P;x+0b|<!ZN7Z%A`>2tN#CdoG>((QR~IV_Gj^Yh%!HdA~4C3jOXaqb6Ou z21T~Wmi9F6(_K0@KR@JDTh3-4mv2=T7&ML<+$4;b9SAtv*Uu`0>;VVZHB{4?aIl3J zL(rMfk?1V@l)fy{J5DhVlj&cWKJCcrpOAad(7mC6#%|Sn$VwMjtx6RDx1zbQ|Ngg8N&B56DGhu;dYg$Z{=YmCNn+?ceDclp65c_RnKs4*vefnhudSlrCy6-96vSB4_sFAj# zftzECwmNEOtED^NUt{ZDjT7^g>k1w<=af>+0)%NA;IPq6qx&ya7+QAu=pk8t>KTm` zEBj9J*2t|-(h)xc>Us*jHs)w9qmA>8@u21UqzKk*Ei#0kCeW6o z-2Q+Tvt25IUkb}-_LgD1_FUJ!U8@8OC^9(~Kd*0#zr*8IQkD)6Keb(XFai5*DYf~` z@U?-{)9X&BTf!^&@^rjmvea#9OE~m(D>qfM?CFT9Q4RxqhO0sA7S)=--^*Q=kNh7Y zq%2mu_d_#23d`+v`Ol263CZ<;D%D8Njj6L4T`S*^{!lPL@pXSm>2;~Da- zBX97TS{}exvSva@J5FJVCM$j4WDQuME`vTw>PWS0!;J7R+Kq zVUy6%#n5f7EV(}J#FhDpts;>=d6ow!yhJj8j>MJ@Wr_?x30buuutIG97L1A*QFT$c ziC5rBS;#qj=~yP-yWm-p(?llTwDuhS^f&<(9vA9@UhMH2-Fe_YAG$NvK6X{!mvPK~ zuEA&PA}meylmaIbbJXDOzuIn8cJNCV{tUA<$Vb?57JyAM`*GpEfMmFq>)6$E(9e1@W`l|R%-&}38#bl~levA#fx2wiBk^)mPj?<=S&|gv zQO)4*91$n08@W%2b|QxEiO0KxABAZC{^4BX^6r>Jm?{!`ZId9jjz<%pl(G5l));*`UU3KfnuXSDj2aP>{ zRIB$9pm7lj3*Xg)c1eG!cb+XGt&#?7yJ@C)(Ik)^OZ5><4u$VLCqZ#q2NMCt5 z6$|VN(RWM;5!JV?-h<JkEZ(SZF zC(6J+>A6Am9H7OlOFq6S62-2&z^Np=#xXsOq0WUKr zY_+Ob|CQd1*!Hirj5rn*=_bM5_zKmq6lG zn*&_=x%?ATxZ8ZTzd%biKY_qyNC#ZQ1vX+vc48N>aJXEjs{Y*3Op`Q7-oz8jyAh>d zNt_qvn`>q9aO~7xm{z`ree%lJ3YHCyC`q`-jUVCn*&NIml!uuMNm|~u3#AV?6kC+B z?qrT?xu2^mobSlzb&m(8jttB^je0mx;TT8}`_w(F11IKz83NLj@OmYDpCU^u?fD{) z&=$ptwVw#uohPb2_PrFX;X^I=MVXPDpqTuYhRa>f-=wy$y3)40-;#EUDYB1~V9t%$ z^^<7Zbs0{eB93Pcy)96%XsAi2^k`Gmnypd-&x4v9rAq<>a(pG|J#+Q>E$FvMLmy7T z5_06W=*ASUyPRfgCeiPIe{b47Hjqpb`9Xyl@$6*ntH@SV^bgH&Fk3L9L=6VQb)Uqa z33u#>ecDo&bK(h1WqSH)b_Th#Tvk&%$NXC@_pg5f-Ma#7q;&0QgtsFO~`V&{1b zbSP*X)jgLtd@9XdZ#2_BX4{X~pS8okF7c1xUhEV9>PZco>W-qz7YMD`+kCGULdK|^ zE7VwQ-at{%&fv`a+b&h`TjzxsyQX05UB~a0cuU-}{*%jR48J+yGWyl3Kdz5}U>;lE zgkba*yI5>xqIPz*Y!-P$#_mhHB!0Fpnv{$k-$xxjLAc`XdmHd1k$V@2QlblfJPrly z*~-4HVCq+?9vha>&I6aRGyq2VUon^L1a)g`-Xm*@bl2|hi2b|UmVYW|b+Gy?!aS-p z86a}Jep6Mf>>}n^*Oca@Xz}kxh)Y&pX$^CFAmi#$YVf57X^}uQD!IQSN&int=D> zJ>_|au3Be?hmPKK)1^JQ(O29eTf`>-x^jF2xYK6j_9d_qFkWHIan5=7EmDvZoQWz5 zZGb<{szHc9Nf@om)K_<=FuLR<&?5RKo3LONFQZ@?dyjemAe4$yDrnD zglU#XYo6|~L+YpF#?deK6S{8A*Ou;9G`cdC4S0U74EW18bc5~4>)<*}?Z!1Y)j;Ot zosEP!pc$O^wud(={WG%hY07IE^SwS-fGbvpP?;l8>H$;}urY2JF$u#$q}E*ZG%fR# z`p{xslcvG)kBS~B*^z6zVT@e}imYcz_8PRzM4GS52#ms5Jg9z~ME+uke`(Tq1w3_6 zxUa{HerS7!Wq&y(<9yyN@P^PrQT+6ij_qW3^Q)I53iIFCJE?MVyGLID!f?QHUi1tq z0)RNIMGO$2>S%3MlBc09l!6_(ECxXTU>$KjWdZX^3R~@3!SB zah5Za2$63;#y!Y}(wg1#shMePQTzfQfXyJ-Tf`R05KYcyvo8UW9-IWGWnzxR6Vj8_la;*-z5vWuwUe7@sKr#Tr51d z2PWn5h@|?QU3>k=s{pZ9+(}oye zc*95N_iLmtmu}H-t$smi49Y&ovX}@mKYt2*?C-i3Lh4*#q5YDg1Mh`j9ovRDf9&& zp_UMQh`|pC!|=}1uWoMK5RAjdTg3pXPCsYmRkWW}^m&)u-*c_st~gcss(`haA)xVw zAf=;s>$`Gq_`A}^MjY_BnCjktBNHY1*gzh(i0BFZ{Vg^F?Pbf`8_clvdZ)5(J4EWzAP}Ba5zX=S(2{gDugTQ3`%!q`h7kYSnwC`zEWeuFlODKiityMaM9u{Z%E@@y1jmZA#ⅅ8MglG&ER{i5lN315cO?EdHNLrg? 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 z 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 Pe7HEdAEg|=c=LY&YVNkY literal 69450 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 PKlPC5u>%Drr*HfpG~rAC diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index c8ba3b1a21bf014a0ed55ac2169dc48b4abb240f..13b35eba55c6dabc3aac36f33d859266c18fa0d0 100644 GIT binary patch literal 5680 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 literal 4664 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 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png index e85f014180ccfa3df01d669e08620973393bc259..0a3f5fa40fb3d1e0710331a48de5d256da3f275d 100644 GIT binary patch delta 495 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 QaR2}S07*qoM6N<$g1Eli`~Uy| delta 1424 zcmV;B1#kMQ2%!s*BYy#eX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmKpe$iQ%hA^6zm}4 zkfAzR5EXIMDionYs1;guFuC*#nlvOSE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JW zDYS_7;J6>}?mh0_0YbgZG^=YI&~)2OCE{WxyDA1>5kwgM2!EhQW|lE0NlA1ZU-$6w z^)AMqI0G~)a%M8;d-XNadv<=St#1U4MRpN8vF_SJx{K$31<2TL)mj#{~ zG1IAe;s~)=Xk(>~S<%#pr--Afrc=I<@mS@&#aSy?S@WL!g`u3jvdndw!$@EeOOPN! zK@}yGVIxMXPJfDp6z#`5_=jA-L@tF~B`|Uj(dX-`!gI$q6qh6bAw?j`J}B z1b2Z(&2heu9j9>u_@99*z2&deftgRzYb`B$1oUkK7uPLK*#jS%3kmA?tkv~-u^w)?C%HcSaNYixY~^X z00Y=bL_t(|0qs{=C}v?8esJuRec#taaxcwDjZ%u#Fg2q@8C(#GJC`UUxp5sNZ+{Q_`}?rAwuX(3&A%hCxw(n)@o`*ST!_DKZf@Y{=!l@8AXr#f{5=B4$H(aI z?#95t0AgZdU}$J4{%>GlfUT`9Y;SMF%gYPCzP^wo{oAW1aCv!&zP>(mb#)06mX?;c z!L`9mEG#Twb!7$q0ReDxa}(sAO@JGYjg6tLt$$6VU4zrpQ(RwPKS+W&mrFA-F@eR! zMFa;2!`9aJ=>(RRmeAVTikX=iol{(0T?s;PCJe!^6XHa&kgoU?9xR&Gi%5 z+ucQbM+b(6hC~LGQaCj=C4{Gx1#N6>YzU1|A3i=lxB9q4fOYQa=@BA3KR?&IDO+%K zbbl1#;o+)Cuw?V|^H^P7MS!di7Z;a51p52?(a_LV;NSpZVPT4O zz7NJ=Htg-~e-o&vs6c&v{p|u*S6BG^`@_`KRMm#Na>;sod*R{Xfsl|8n3P&!3QapW!4$D(-rnA#W=2Lvs)%qezJJRA^a1VnjE#*&+V8iew6?bP;AT|$+}s>i zFEhSKfec!Ng|`il+J#q576g%GNw=sj*gDd+1V)! ztEi|*(G?{!WZfnwCm-FAbsiiXguA=DIE{&kiQ-!J{`B-Tc6N5e!IF}ako@r@vVU`O zbOx5h1-ZGo$jZu6b+YB`|#IkXXc2-%I#-=88$QjAb&PH-_@?9T@ zii$#BULLBds#KAnU(g*Hi0)=*XD5DVa6VH4eWSFr6wS@eqAZb-k$-$3BO^nUqP)CZ zY@`MpN+Tm9LgAXRtOm2Qv-mD|9)IKAQ3e^cw6vf}PFGD$jW8HBcuH`#bzxy4qNAfl ziFBmN)1;=RB0fGI)z#I45H0kj;3eg2W+py=`Ep0ViqnuzRZ>!dPbn!VEh`fppvDL8 zgYP6HBnY89I5_A$*Lxobl4p5cT^)Y@_FMb@ z7mrsVpaJJXnXHQxSs(mKtB#d3R8UYLhRsv(qVEFMxUsQOTrz0S&%uj7OlZZ=4gM+w eUWzv-@C)B~n#-8vW6l5o00{s|MNUMnLSTXcsKg8a diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png index f24fbe65de8627a88836014c48b7f8156a627594..326c0e72c9d820600887813b3b98d0dd69c5d4e8 100644 GIT binary patch literal 36406 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 literal 26089 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

?wGKN5P>m=1%)sND3~`BjaS)39faeQ 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

Ap^y&bmSMNJSYOXrydf$x0rnWoG%}(S)YINx{WS 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 delta 2433 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 z Date: Mon, 17 Jul 2023 10:36:08 -0600 Subject: [PATCH 11/80] update ref --- crypto_plugins/flutter_libmonero | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index 782c8d00c..c206a1434 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit 782c8d00c10d9dde906c1da982b1be7d45767ae7 +Subproject commit c206a1434f138a20c38b7abf8d94b9dd4d14b57e From bc85b97f5fb9cc5a2c3b3c0498df5a0ff2f9a1e6 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Mon, 17 Jul 2023 10:36:33 -0600 Subject: [PATCH 12/80] null error fix on isar exchange data cache instance --- lib/services/exchange/exchange_data_loading_service.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/services/exchange/exchange_data_loading_service.dart b/lib/services/exchange/exchange_data_loading_service.dart index 6fefba289..ee0ed50a0 100644 --- a/lib/services/exchange/exchange_data_loading_service.dart +++ b/lib/services/exchange/exchange_data_loading_service.dart @@ -135,6 +135,9 @@ class ExchangeDataLoadingService { Future loadAll() async { if (!_locked) { _locked = true; + if (_isar == null) { + await initDB(); + } Logging.instance.log( "ExchangeDataLoadingService.loadAll starting...", level: LogLevel.Info, From 27c2f34a33e039446f71b3f3260ae43907dcfd18 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Mon, 17 Jul 2023 10:36:45 -0600 Subject: [PATCH 13/80] macos specific notifications fix --- lib/services/notifications_api.dart | 10 ++++++++-- lib/utilities/stack_file_system.dart | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/services/notifications_api.dart b/lib/services/notifications_api.dart index e1c42fabe..41e95387b 100644 --- a/lib/services/notifications_api.dart +++ b/lib/services/notifications_api.dart @@ -26,6 +26,7 @@ class NotificationApi { priority: Priority.high, ticker: 'ticker'), iOS: IOSNotificationDetails(), + macOS: MacOSNotificationDetails(), ); } @@ -34,8 +35,13 @@ class NotificationApi { const iOS = IOSInitializationSettings(); const linux = LinuxInitializationSettings( defaultActionName: "temporary_stack_wallet"); - const settings = - InitializationSettings(android: android, iOS: iOS, linux: linux); + const macOS = MacOSInitializationSettings(); + const settings = InitializationSettings( + android: android, + iOS: iOS, + linux: linux, + macOS: macOS, + ); await _notifications.initialize( settings, onSelectNotification: (payload) async { diff --git a/lib/utilities/stack_file_system.dart b/lib/utilities/stack_file_system.dart index 843bb1b71..f36fadf01 100644 --- a/lib/utilities/stack_file_system.dart +++ b/lib/utilities/stack_file_system.dart @@ -27,8 +27,8 @@ abstract class StackFileSystem { } else if (Platform.isWindows) { appDirectory = await getApplicationSupportDirectory(); } else if (Platform.isMacOS) { - // currently run in ipad mode?? - throw Exception("Unsupported platform"); + appDirectory = await getLibraryDirectory(); + appDirectory = Directory("${appDirectory.path}/stackwallet"); } else if (Platform.isIOS) { // todo: check if we need different behaviour here if (Util.isDesktop) { From d966964cf85fa0127a4f96919295c2d03f4dabc8 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Mon, 17 Jul 2023 10:40:43 -0600 Subject: [PATCH 14/80] macos app network entitlements --- macos/Runner/DebugProfile.entitlements | 2 ++ macos/Runner/Release.entitlements | 2 ++ 2 files changed, 4 insertions(+) diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements index dddb8a30c..c946719a1 100644 --- a/macos/Runner/DebugProfile.entitlements +++ b/macos/Runner/DebugProfile.entitlements @@ -8,5 +8,7 @@ com.apple.security.network.server + com.apple.security.network.client + diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements index 852fa1a47..48271acc9 100644 --- a/macos/Runner/Release.entitlements +++ b/macos/Runner/Release.entitlements @@ -4,5 +4,7 @@ com.apple.security.app-sandbox + com.apple.security.network.client + From faf88542f24601bcc309907d1ae0e1b41c52d54b Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Mon, 17 Jul 2023 14:21:28 -0600 Subject: [PATCH 15/80] macos app name --- macos/Runner.xcodeproj/project.pbxproj | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 7b723f8a8..21cf855f6 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -69,7 +69,7 @@ 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* stack_wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = stack_wallet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* Stack Wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Stack Wallet.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -144,7 +144,7 @@ 33CC10EE2044A3C60003C045 /* Products */ = { isa = PBXGroup; children = ( - 33CC10ED2044A3C60003C045 /* stack_wallet.app */, + 33CC10ED2044A3C60003C045 /* Stack Wallet.app */, 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, ); name = Products; @@ -204,7 +204,6 @@ 174539D042E7AC2AB25A83EB /* Pods-RunnerTests.release.xcconfig */, 27CB73AACA5743180CC6CD50 /* Pods-RunnerTests.profile.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -249,7 +248,7 @@ ); name = Runner; productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* stack_wallet.app */; + productReference = 33CC10ED2044A3C60003C045 /* Stack Wallet.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -481,7 +480,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stackWallet.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/stack_wallet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/stack_wallet"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Stack Wallet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/stack_wallet"; }; name = Debug; }; @@ -496,7 +495,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stackWallet.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/stack_wallet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/stack_wallet"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Stack Wallet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/stack_wallet"; }; name = Release; }; @@ -511,7 +510,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stackWallet.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/stack_wallet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/stack_wallet"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Stack Wallet.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/stack_wallet"; }; name = Profile; }; @@ -556,6 +555,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; + STRIP_INSTALLED_PRODUCT = NO; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; }; @@ -636,6 +636,7 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; + STRIP_INSTALLED_PRODUCT = NO; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; @@ -682,6 +683,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; + STRIP_INSTALLED_PRODUCT = NO; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; }; From 72e36caf1e0370ce751a6360d917c664479715fe Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Tue, 18 Jul 2023 15:18:29 -0600 Subject: [PATCH 16/80] update macos refs --- crypto_plugins/flutter_libepiccash | 2 +- crypto_plugins/flutter_liblelantus | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index c99e2a00b..1cb5373a8 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit c99e2a00b6bb98d497e99858e75ffe75f5898133 +Subproject commit 1cb5373a8aec7ba171173a75449e40dd040206ea diff --git a/crypto_plugins/flutter_liblelantus b/crypto_plugins/flutter_liblelantus index 45d15a4d6..abe199d51 160000 --- a/crypto_plugins/flutter_liblelantus +++ b/crypto_plugins/flutter_liblelantus @@ -1 +1 @@ -Subproject commit 45d15a4d6f5aa276751dbf9fb3ae076ffbebab44 +Subproject commit abe199d519746831f9b852af5a90da4b7deab154 From c60721872a28273ce382543b388c35701d5738a0 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Tue, 18 Jul 2023 15:57:55 -0600 Subject: [PATCH 17/80] macos alpha --- macos/Podfile.lock | 8 ++- macos/Runner.xcodeproj/project.pbxproj | 82 ++++++++++++++++++++++++++ pubspec.lock | 2 +- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 2b6385a35..69c91af48 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -62,6 +62,8 @@ PODS: - FlutterMacOS (1.0.0) - isar_flutter_libs (1.0.0): - FlutterMacOS + - lelantus (0.0.1): + - FlutterMacOS - package_info_plus (0.0.1): - FlutterMacOS - path_provider_foundation (0.0.1): @@ -92,6 +94,7 @@ DEPENDENCIES: - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - isar_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos`) + - lelantus (from `Flutter/ephemeral/.symlinks/plugins/lelantus/macos`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) @@ -129,6 +132,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral isar_flutter_libs: :path: Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos + lelantus: + :path: Flutter/ephemeral/.symlinks/plugins/lelantus/macos package_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos path_provider_foundation: @@ -152,11 +157,12 @@ SPEC CHECKSUMS: desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225 - flutter_libepiccash: b33f7396504712b513b8ff019a3f6f3bdae54cfb + flutter_libepiccash: 9113ac75dd325f8bcf00bc3ab583c7fc2780cf3c flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4 flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 isar_flutter_libs: 43385c99864c168fadba7c9adeddc5d38838ca6a + lelantus: 3dfbf92b1e66b3573494dfe3d6a21c4988b5361b package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 21cf855f6..9b99a3480 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,9 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + B98151812A674022009D013C /* mobileliblelantus.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B98151802A674022009D013C /* mobileliblelantus.framework */; }; + B98151822A67402A009D013C /* mobileliblelantus.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = B98151802A674022009D013C /* mobileliblelantus.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + B98151842A674143009D013C /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = B98151832A674143009D013C /* libsqlite3.0.tbd */; }; BFD0376C00E1FFD46376BB9D /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9206484E84CB0AD93E3E68CA /* Pods_RunnerTests.framework */; }; F653CA022D33E8B60E11A9F3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E6036BF01BF05EA773C76D22 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ @@ -55,6 +58,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + B98151822A67402A009D013C /* mobileliblelantus.framework in Bundle Framework */, ); name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; @@ -86,6 +90,8 @@ 9206484E84CB0AD93E3E68CA /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; ACB8E553D75AA4AC9A7656CE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + B98151802A674022009D013C /* mobileliblelantus.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mobileliblelantus.framework; path = ../crypto_plugins/flutter_liblelantus/scripts/macos/mobileliblelantus/mobileliblelantus.framework; sourceTree = ""; }; + B98151832A674143009D013C /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; }; BF5E76865ACB46314AC27D8F /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; E6036BF01BF05EA773C76D22 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -103,6 +109,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B98151842A674143009D013C /* libsqlite3.0.tbd in Frameworks */, + B98151812A674022009D013C /* mobileliblelantus.framework in Frameworks */, F653CA022D33E8B60E11A9F3 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -188,6 +196,8 @@ D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + B98151832A674143009D013C /* libsqlite3.0.tbd */, + B98151802A674022009D013C /* mobileliblelantus.framework */, E6036BF01BF05EA773C76D22 /* Pods_Runner.framework */, 9206484E84CB0AD93E3E68CA /* Pods_RunnerTests.framework */, ); @@ -570,6 +580,30 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_CONFIGURATION_BUILD_DIR}/ReachabilitySwift\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/connectivity_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_monero\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_shared_external\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_wownero\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/desktop_drop\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/device_info_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/devicelocale\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_libepiccash\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_local_notifications\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_secure_storage_macos\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/isar_flutter_libs\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/lelantus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/package_info_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/path_provider_foundation\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/share_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/stack_wallet_backup\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/url_launcher_macos\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/wakelock_macos\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/window_size\"", + "\"${PROJECT_DIR}/../crypto_plugins/flutter_liblelantus/scripts/macos/mobileliblelantus\"", + ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -698,6 +732,30 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_CONFIGURATION_BUILD_DIR}/ReachabilitySwift\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/connectivity_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_monero\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_shared_external\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_wownero\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/desktop_drop\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/device_info_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/devicelocale\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_libepiccash\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_local_notifications\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_secure_storage_macos\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/isar_flutter_libs\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/lelantus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/package_info_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/path_provider_foundation\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/share_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/stack_wallet_backup\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/url_launcher_macos\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/wakelock_macos\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/window_size\"", + "\"${PROJECT_DIR}/../crypto_plugins/flutter_liblelantus/scripts/macos/mobileliblelantus\"", + ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -718,6 +776,30 @@ CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_CONFIGURATION_BUILD_DIR}/ReachabilitySwift\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/connectivity_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_monero\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_shared_external\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_wownero\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/desktop_drop\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/device_info_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/devicelocale\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_libepiccash\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_local_notifications\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_secure_storage_macos\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/isar_flutter_libs\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/lelantus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/package_info_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/path_provider_foundation\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/share_plus\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/stack_wallet_backup\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/url_launcher_macos\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/wakelock_macos\"", + "\"${PODS_CONFIGURATION_BUILD_DIR}/window_size\"", + "\"${PROJECT_DIR}/../crypto_plugins/flutter_liblelantus/scripts/macos/mobileliblelantus\"", + ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/pubspec.lock b/pubspec.lock index 9ec8db667..1ad96c7a7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -948,7 +948,7 @@ packages: path: "crypto_plugins/flutter_liblelantus" relative: true source: path - version: "0.0.1" + version: "0.0.2" lints: dependency: transitive description: From e74b0babf6c66bf1283932b7351950f635e6d80c Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 19 Jul 2023 07:49:49 -0600 Subject: [PATCH 18/80] update plugin refs --- crypto_plugins/flutter_libepiccash | 2 +- crypto_plugins/flutter_liblelantus | 2 +- crypto_plugins/flutter_libmonero | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index 1cb5373a8..686559344 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit 1cb5373a8aec7ba171173a75449e40dd040206ea +Subproject commit 686559344a58f77732c3d0134fbf44d271a55229 diff --git a/crypto_plugins/flutter_liblelantus b/crypto_plugins/flutter_liblelantus index abe199d51..cdccef0e8 160000 --- a/crypto_plugins/flutter_liblelantus +++ b/crypto_plugins/flutter_liblelantus @@ -1 +1 @@ -Subproject commit abe199d519746831f9b852af5a90da4b7deab154 +Subproject commit cdccef0e8dc10b7fe703b5bb9b41b59b25177e83 diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index c206a1434..66f9ad2a6 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit c206a1434f138a20c38b7abf8d94b9dd4d14b57e +Subproject commit 66f9ad2a6f41dd1f5f2748e7ff01c402835cb042 From d867270aaca54ab927090838dcc3cea1680761dc Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Wed, 19 Jul 2023 08:30:15 -0600 Subject: [PATCH 19/80] exchange view amount string provider fix --- lib/pages/exchange_view/exchange_form.dart | 30 +++++---------- .../exchange_form_state_provider.dart | 38 ++++++++++++++++++- lib/utilities/amount/amount_unit.dart | 5 ++- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart index e65242fbd..c4b92a714 100644 --- a/lib/pages/exchange_view/exchange_form.dart +++ b/lib/pages/exchange_view/exchange_form.dart @@ -35,6 +35,7 @@ import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart'; import 'package:stackwallet/services/exchange/trocador/trocador_exchange.dart'; import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/amount/amount_unit.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -160,26 +161,15 @@ class _ExchangeFormState extends ConsumerState { if (value == null) { return null; } - try { - // wtf Dart????? - // This turns "99999999999999999999" into 100000000000000000000.0 - // final numFromLocalised = NumberFormat.decimalPattern( - // ref.read(localeServiceChangeNotifierProvider).locale) - // .parse(value); - // return Decimal.tryParse(numFromLocalised.toString()); - try { - return Decimal.parse(value); - } catch (_) { - try { - return Decimal.parse(value.replaceAll(",", ".")); - } catch (_) { - rethrow; - } - } - } catch (_) { - return null; - } + return AmountUnit.normal + .tryParse( + value, + locale: ref.read(localeServiceChangeNotifierProvider).locale, + coin: Coin.bitcoin, // dummy value (not used due to override) + overrideWithDecimalPlacesFromString: true, + ) + ?.decimal; } Future _getAggregateCurrency(Currency currency) async { @@ -824,7 +814,7 @@ class _ExchangeFormState extends ConsumerState { }); ref.listen(efEstimateProvider.notifier, (previous, next) { - final estimate = (next as StateController).state; + final estimate = (next).state; if (ref.read(efReversedProvider)) { updateSend(estimate); } else { diff --git a/lib/providers/exchange/exchange_form_state_provider.dart b/lib/providers/exchange/exchange_form_state_provider.dart index 07447f169..b4a923b78 100644 --- a/lib/providers/exchange/exchange_form_state_provider.dart +++ b/lib/providers/exchange/exchange_form_state_provider.dart @@ -13,8 +13,12 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/models/exchange/active_pair.dart'; import 'package:stackwallet/models/exchange/response_objects/estimate.dart'; import 'package:stackwallet/models/exchange/response_objects/range.dart'; +import 'package:stackwallet/providers/global/locale_provider.dart'; import 'package:stackwallet/services/exchange/exchange.dart'; import 'package:stackwallet/services/exchange/exchange_response.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; +import 'package:stackwallet/utilities/amount/amount_unit.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart'; import 'package:tuple/tuple.dart'; @@ -44,7 +48,22 @@ final efSendAmountStringProvider = StateProvider((ref) { if (refreshing && reversed) { return "-"; } else { - return ref.watch(efSendAmountProvider)?.toString() ?? ""; + final decimal = ref.watch(efSendAmountProvider); + String string = ""; + if (decimal != null) { + final amount = Amount.fromDecimal(decimal, fractionDigits: decimal.scale); + final locale = ref.watch(localeServiceChangeNotifierProvider).locale; + string = AmountUnit.normal.displayAmount( + amount: amount, + locale: locale, + coin: Coin + .nano, // use nano just to ensure decimal.scale < Coin.value.decimals + withUnitName: false, + maxDecimalPlaces: decimal.scale, + ); + } + + return string; } }); final efReceiveAmountStringProvider = StateProvider((ref) { @@ -54,7 +73,22 @@ final efReceiveAmountStringProvider = StateProvider((ref) { if (refreshing && reversed == false) { return "-"; } else { - return ref.watch(efReceiveAmountProvider)?.toString() ?? ""; + final decimal = ref.watch(efReceiveAmountProvider); + String string = ""; + if (decimal != null) { + final amount = Amount.fromDecimal(decimal, fractionDigits: decimal.scale); + final locale = ref.watch(localeServiceChangeNotifierProvider).locale; + string = AmountUnit.normal.displayAmount( + amount: amount, + locale: locale, + coin: Coin + .nano, // use nano just to ensure decimal.scale < Coin.value.decimals + withUnitName: false, + maxDecimalPlaces: decimal.scale, + ); + } + + return string; } }); diff --git a/lib/utilities/amount/amount_unit.dart b/lib/utilities/amount/amount_unit.dart index 0c0600d7a..91fef8bc7 100644 --- a/lib/utilities/amount/amount_unit.dart +++ b/lib/utilities/amount/amount_unit.dart @@ -168,6 +168,7 @@ extension AmountUnitExt on AmountUnit { required String locale, required Coin coin, EthContract? tokenContract, + bool overrideWithDecimalPlacesFromString = false, }) { final precisionLost = value.startsWith("~"); @@ -201,7 +202,9 @@ extension AmountUnitExt on AmountUnit { return null; } - final decimalPlaces = tokenContract?.decimals ?? coin.decimals; + final decimalPlaces = overrideWithDecimalPlacesFromString + ? decimal.scale + : tokenContract?.decimals ?? coin.decimals; final realShift = math.min(shift, decimalPlaces); return decimal.shift(0 - realShift).toAmount(fractionDigits: decimalPlaces); From f2a872c44cf4df50f06b7ba9899c20a296592e99 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Wed, 19 Jul 2023 08:54:56 -0600 Subject: [PATCH 20/80] ensure cursor stays at end on exchange/swap form --- lib/pages/exchange_view/exchange_form.dart | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart index c4b92a714..a15e13843 100644 --- a/lib/pages/exchange_view/exchange_form.dart +++ b/lib/pages/exchange_view/exchange_form.dart @@ -799,6 +799,14 @@ class _ExchangeFormState extends ConsumerState { // if (_swapLock) { _sendController.text = ref.read(efSendAmountStringProvider); // } + + if (_sendFocusNode.hasFocus) { + _sendController.selection = TextSelection.fromPosition( + TextPosition( + offset: _sendController.text.length, + ), + ); + } } }); ref.listen(efSendAmountStringProvider, (previous, String next) { @@ -810,6 +818,14 @@ class _ExchangeFormState extends ConsumerState { ? "-" : ref.read(efReceiveAmountStringProvider); // } + + if (_receiveFocusNode.hasFocus) { + _receiveController.selection = TextSelection.fromPosition( + TextPosition( + offset: _receiveController.text.length, + ), + ); + } } }); From 35f3a05fc5c4d9a9f7b2001fc57502a83ccab64c Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Wed, 19 Jul 2023 08:58:00 -0600 Subject: [PATCH 21/80] macos file --- macos/Flutter/GeneratedPluginRegistrant.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 7cb956395..b044b4b00 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -16,6 +16,7 @@ import flutter_libepiccash import flutter_local_notifications import flutter_secure_storage_macos import isar_flutter_libs +import lelantus import package_info_plus import path_provider_foundation import share_plus @@ -36,6 +37,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin")) + LelantusPlugin.register(with: registry.registrar(forPlugin: "LelantusPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) From 2c5e021783f9ce7490eecb2c89937e25d2c54a7e Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Wed, 19 Jul 2023 09:21:26 -0600 Subject: [PATCH 22/80] update monero ref --- crypto_plugins/flutter_libmonero | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index 66f9ad2a6..c920c09df 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit 66f9ad2a6f41dd1f5f2748e7ff01c402835cb042 +Subproject commit c920c09df5e415bba4bbe95dd50e1f0085f040e6 From e47e861273ba55578c0ce1c5eca32fe54540e494 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 19 Jul 2023 10:22:18 -0600 Subject: [PATCH 23/80] delete unused file --- test/widget_test.dart | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 test/widget_test.dart diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index 81dacd980..000000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility in the flutter_test package. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:stack_wallet/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} From db1e34d745e2b6036303dc8a0eb0679cae01ce80 Mon Sep 17 00:00:00 2001 From: Diego Salazar Date: Wed, 19 Jul 2023 11:30:50 -0600 Subject: [PATCH 24/80] Bump version (1.7.16, build 182) --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index fd5eac1dc..3621d787c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.7.15+181 +version: 1.7.16+182 environment: sdk: ">=3.0.2 <4.0.0" From 43d7f39f6f551c6178bb040c64b8c10ed64aeb38 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Wed, 19 Jul 2023 12:43:42 -0600 Subject: [PATCH 25/80] macos app icon --- assets/icon/macos-icon.png | Bin 0 -> 14912 bytes .../AppIcon.appiconset/Contents.json | 132 +++++++++--------- .../AppIcon.appiconset/app_icon_1024.png | Bin 102994 -> 63944 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 5680 -> 4698 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 520 -> 577 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 14142 -> 8830 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 1066 -> 1158 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 36406 -> 16189 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 2218 -> 2283 bytes pubspec.lock | 20 +-- pubspec.yaml | 6 +- 11 files changed, 79 insertions(+), 79 deletions(-) create mode 100644 assets/icon/macos-icon.png diff --git a/assets/icon/macos-icon.png b/assets/icon/macos-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e4a26302216d12d5dfd46677e28f18746ead7e8b GIT binary patch literal 14912 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 QLJ_)W&S~XoTz&X|0N}vPSpWb4 literal 0 HcmV?d00001 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index a2ec33f19..96d3fee1a 100644 --- a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,68 +1,68 @@ { - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_16.png", - "scale" : "1x" + "info": { + "version": 1, + "author": "xcode" }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} + "images": [ + { + "size": "16x16", + "idiom": "mac", + "filename": "app_icon_16.png", + "scale": "1x" + }, + { + "size": "16x16", + "idiom": "mac", + "filename": "app_icon_32.png", + "scale": "2x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "app_icon_32.png", + "scale": "1x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "app_icon_64.png", + "scale": "2x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "app_icon_128.png", + "scale": "1x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "app_icon_256.png", + "scale": "2x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "app_icon_256.png", + "scale": "1x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "app_icon_512.png", + "scale": "2x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "app_icon_512.png", + "scale": "1x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "app_icon_1024.png", + "scale": "2x" + } + ] +} \ No newline at end of file diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png index 82b6f9d9a33e198f5747104729e1fcef999772a5..65564e63bdf156cffeafd776cb0c9c1a8d59ade6 100644 GIT binary patch literal 63944 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 literal 102994 zcmeEugo5nb1G~3xi~y`}h6XHx5j$(L*3|5S2UfkG$|UCNI>}4f?MfqZ+HW-sRW5RKHEm z^unW*Xx{AH_X3Xdvb%C(Bh6POqg==@d9j=5*}oEny_IS;M3==J`P0R!eD6s~N<36C z*%-OGYqd0AdWClO!Z!}Y1@@RkfeiQ$Ib_ z&fk%T;K9h`{`cX3Hu#?({4WgtmkR!u3ICS~|NqH^fdNz>51-9)OF{|bRLy*RBv#&1 z3Oi_gk=Y5;>`KbHf~w!`u}!&O%ou*Jzf|Sf?J&*f*K8cftMOKswn6|nb1*|!;qSrlw= zr-@X;zGRKs&T$y8ENnFU@_Z~puu(4~Ir)>rbYp{zxcF*!EPS6{(&J}qYpWeqrPWW< zfaApz%<-=KqxrqLLFeV3w0-a0rEaz9&vv^0ZfU%gt9xJ8?=byvNSb%3hF^X_n7`(fMA;C&~( zM$cQvQ|g9X)1AqFvbp^B{JEX$o;4iPi?+v(!wYrN{L}l%e#5y{j+1NMiT-8=2VrCP zmFX9=IZyAYA5c2!QO96Ea-6;v6*$#ZKM-`%JCJtrA3d~6h{u+5oaTaGE)q2b+HvdZ zvHlY&9H&QJ5|uG@wDt1h99>DdHy5hsx)bN`&G@BpxAHh$17yWDyw_jQhhjSqZ=e_k z_|r3=_|`q~uA47y;hv=6-o6z~)gO}ZM9AqDJsR$KCHKH;QIULT)(d;oKTSPDJ}Jx~G#w-(^r<{GcBC*~4bNjfwHBumoPbU}M)O za6Hc2ik)2w37Yyg!YiMq<>Aov?F2l}wTe+>h^YXcK=aesey^i)QC_p~S zp%-lS5%)I29WfywP(r4@UZ@XmTkqo51zV$|U|~Lcap##PBJ}w2b4*kt7x6`agP34^ z5fzu_8rrH+)2u*CPcr6I`gL^cI`R2WUkLDE5*PX)eJU@H3HL$~o_y8oMRoQ0WF9w| z6^HZDKKRDG2g;r8Z4bn+iJNFV(CG;K-j2>aj229gl_C6n12Jh$$h!}KVhn>*f>KcH z;^8s3t(ccVZ5<{>ZJK@Z`hn_jL{bP8Yn(XkwfRm?GlEHy=T($8Z1Mq**IM`zxN9>-yXTjfB18m_$E^JEaYn>pj`V?n#Xu;Z}#$- zw0Vw;T*&9TK$tKI7nBk9NkHzL++dZ^;<|F6KBYh2+XP-b;u`Wy{~79b%IBZa3h*3^ zF&BKfQ@Ej{7ku_#W#mNJEYYp=)bRMUXhLy2+SPMfGn;oBsiG_6KNL8{p1DjuB$UZB zA)a~BkL)7?LJXlCc}bB~j9>4s7tlnRHC5|wnycQPF_jLl!Avs2C3^lWOlHH&v`nGd zf&U!fn!JcZWha`Pl-B3XEe;(ks^`=Z5R zWyQR0u|do2`K3ec=YmWGt5Bwbu|uBW;6D8}J3{Uep7_>L6b4%(d=V4m#(I=gkn4HT zYni3cnn>@F@Wr<hFAY3Y~dW+3bte;70;G?kTn4Aw5nZ^s5|47 z4$rCHCW%9qa4)4vE%^QPMGf!ET!^LutY$G zqdT(ub5T5b+wi+OrV}z3msoy<4)`IPdHsHJggmog0K*pFYMhH!oZcgc5a)WmL?;TPSrerTVPp<#s+imF3v#!FuBNNa`#6 z!GdTCF|IIpz#(eV^mrYKThA4Bnv&vQet@%v9kuRu3EHx1-2-it@E`%9#u`)HRN#M? z7aJ{wzKczn#w^`OZ>Jb898^Xxq)0zd{3Tu7+{-sge-rQ z&0PME&wIo6W&@F|%Z8@@N3)@a_ntJ#+g{pUP7i?~3FirqU`rdf8joMG^ld?(9b7Iv z>TJgBg#)(FcW)h!_if#cWBh}f+V08GKyg|$P#KTS&%=!+0a%}O${0$i)kn9@G!}En zv)_>s?glPiLbbx)xk(lD-QbY(OP3;MSXM5E*P&_`Zks2@46n|-h$Y2L7B)iH{GAAq19h5-y0q>d^oy^y+soJu9lXxAe%jcm?=pDLFEG2kla40e!5a}mpe zdL=WlZ=@U6{>g%5a+y-lx)01V-x;wh%F{=qy#XFEAqcd+m}_!lQ)-9iiOL%&G??t| z?&NSdaLqdPdbQs%y0?uIIHY7rw1EDxtQ=DU!i{)Dkn~c$LG5{rAUYM1j5*G@oVn9~ zizz{XH(nbw%f|wI=4rw^6mNIahQpB)OQy10^}ACdLPFc2@ldVi|v@1nWLND?)53O5|fg`RZW&XpF&s3@c-R?aad!$WoH6u0B|}zt)L($E^@U- zO#^fxu9}Zw7Xl~nG1FVM6DZSR0*t!4IyUeTrnp@?)Z)*!fhd3)&s(O+3D^#m#bAem zpf#*aiG_0S^ofpm@9O7j`VfLU0+{$x!u^}3!zp=XST0N@DZTp!7LEVJgqB1g{psNr za0uVmh3_9qah14@M_pi~vAZ#jc*&aSm$hCNDsuQ-zPe&*Ii#2=2gP+DP4=DY z_Y0lUsyE6yaV9)K)!oI6+*4|spx2at*30CAx~6-5kfJzQ`fN8$!lz%hz^J6GY?mVH zbYR^JZ(Pmj6@vy-&!`$5soyy-NqB^8cCT40&R@|6s@m+ZxPs=Bu77-+Os7+bsz4nA3DrJ8#{f98ZMaj-+BD;M+Jk?pgFcZIb}m9N z{ct9T)Kye&2>l^39O4Q2@b%sY?u#&O9PO4@t0c$NUXG}(DZJ<;_oe2~e==3Z1+`Zo zFrS3ns-c}ZognVBHbg#e+1JhC(Yq7==rSJQ8J~}%94(O#_-zJKwnBXihl#hUd9B_>+T& z7eHHPRC?5ONaUiCF7w|{J`bCWS7Q&xw-Sa={j-f)n5+I=9s;E#fBQB$`DDh<^mGiF zu-m_k+)dkBvBO(VMe2O4r^sf3;sk9K!xgXJU>|t9Vm8Ty;fl5pZzw z9j|}ZD}6}t;20^qrS?YVPuPRS<39d^y0#O1o_1P{tN0?OX!lc-ICcHI@2#$cY}_CY zev|xdFcRTQ_H)1fJ7S0*SpPs8e{d+9lR~IZ^~dKx!oxz?=Dp!fD`H=LH{EeC8C&z-zK$e=!5z8NL=4zx2{hl<5z*hEmO=b-7(k5H`bA~5gT30Sjy`@-_C zKM}^so9Ti1B;DovHByJkTK87cfbF16sk-G>`Q4-txyMkyQS$d}??|Aytz^;0GxvOs zPgH>h>K+`!HABVT{sYgzy3CF5ftv6hI-NRfgu613d|d1cg^jh+SK7WHWaDX~hlIJ3 z>%WxKT0|Db1N-a4r1oPKtF--^YbP=8Nw5CNt_ZnR{N(PXI>Cm$eqi@_IRmJ9#)~ZHK_UQ8mi}w^`+4$OihUGVz!kW^qxnCFo)-RIDbA&k-Y=+*xYv5y4^VQ9S)4W5Pe?_RjAX6lS6Nz#!Hry=+PKx2|o_H_3M`}Dq{Bl_PbP(qel~P@=m}VGW*pK96 zI@fVag{DZHi}>3}<(Hv<7cVfWiaVLWr@WWxk5}GDEbB<+Aj;(c>;p1qmyAIj+R!`@#jf$ zy4`q23L-72Zs4j?W+9lQD;CYIULt%;O3jPWg2a%Zs!5OW>5h1y{Qof!p&QxNt5=T( zd5fy&7=hyq;J8%86YBOdc$BbIFxJx>dUyTh`L z-oKa=OhRK9UPVRWS`o2x53bAv+py)o)kNL6 z9W1Dlk-g6Ht@-Z^#6%`9S9`909^EMj?9R^4IxssCY-hYzei^TLq7Cj>z$AJyaU5=z zl!xiWvz0U8kY$etrcp8mL;sYqGZD!Hs-U2N{A|^oEKA482v1T%cs%G@X9M?%lX)p$ zZoC7iYTPe8yxY0Jne|s)fCRe1mU=Vb1J_&WcIyP|x4$;VSVNC`M+e#oOA`#h>pyU6 z?7FeVpk`Hsu`~T3i<_4<5fu?RkhM;@LjKo6nX>pa%8dSdgPO9~Jze;5r>Tb1Xqh5q z&SEdTXevV@PT~!O6z|oypTk7Qq+BNF5IQ(8s18c=^0@sc8Gi|3e>VKCsaZ?6=rrck zl@oF5Bd0zH?@15PxSJIRroK4Wa?1o;An;p0#%ZJ^tI=(>AJ2OY0GP$E_3(+Zz4$AQ zW)QWl<4toIJ5TeF&gNXs>_rl}glkeG#GYbHHOv-G!%dJNoIKxn)FK$5&2Zv*AFic! z@2?sY&I*PSfZ8bU#c9fdIJQa_cQijnj39-+hS@+~e*5W3bj%A}%p9N@>*tCGOk+cF zlcSzI6j%Q|2e>QG3A<86w?cx6sBtLNWF6_YR?~C)IC6_10SNoZUHrCpp6f^*+*b8` zlx4ToZZuI0XW1W)24)92S)y0QZa);^NRTX6@gh8@P?^=#2dV9s4)Q@K+gnc{6|C}& zDLHr7nDOLrsH)L@Zy{C_2UrYdZ4V{|{c8&dRG;wY`u>w%$*p>PO_}3`Y21pk?8Wtq zGwIXTulf7AO2FkPyyh2TZXM1DJv>hI`}x`OzQI*MBc#=}jaua&czSkI2!s^rOci|V zFkp*Vbiz5vWa9HPFXMi=BV&n3?1?%8#1jq?p^3wAL`jgcF)7F4l<(H^!i=l-(OTDE zxf2p71^WRIExLf?ig0FRO$h~aA23s#L zuZPLkm>mDwBeIu*C7@n@_$oSDmdWY7*wI%aL73t~`Yu7YwE-hxAATmOi0dmB9|D5a zLsR7OQcA0`vN9m0L|5?qZ|jU+cx3_-K2!K$zDbJ$UinQy<9nd5ImWW5n^&=Gg>Gsh zY0u?m1e^c~Ug39M{{5q2L~ROq#c{eG8Oy#5h_q=#AJj2Yops|1C^nv0D1=fBOdfAG z%>=vl*+_w`&M7{qE#$xJJp_t>bSh7Mpc(RAvli9kk3{KgG5K@a-Ue{IbU{`umXrR3ra5Y7xiX42+Q%N&-0#`ae_ z#$Y6Wa++OPEDw@96Zz##PFo9sADepQe|hUy!Zzc2C(L`k9&=a8XFr+!hIS>D2{pdGP1SzwyaGLiH3j--P>U#TWw90t8{8Bt%m7Upspl#=*hS zhy|(XL6HOqBW}Og^tLX7 z+`b^L{O&oqjwbxDDTg2B;Yh2(fW>%S5Pg8^u1p*EFb z`(fbUM0`afawYt%VBfD&b3MNJ39~Ldc@SAuzsMiN%E}5{uUUBc7hc1IUE~t-Y9h@e7PC|sv$xGx=hZiMXNJxz5V(np%6u{n24iWX#!8t#>Ob$in<>dw96H)oGdTHnU zSM+BPss*5)Wz@+FkooMxxXZP1{2Nz7a6BB~-A_(c&OiM)UUNoa@J8FGxtr$)`9;|O z(Q?lq1Q+!E`}d?KemgC!{nB1JJ!B>6J@XGQp9NeQvtbM2n7F%v|IS=XWPVZY(>oq$ zf=}8O_x`KOxZoGnp=y24x}k6?gl_0dTF!M!T`={`Ii{GnT1jrG9gPh)R=RZG8lIR| z{ZJ6`x8n|y+lZuy${fuEDTAf`OP!tGySLXD}ATJO5UoZv|Xo3%7O~L63+kw}v)Ci=&tWx3bQJfL@5O18CbPlkR^IcKA zy1=^Vl-K-QBP?9^R`@;czcUw;Enbbyk@vJQB>BZ4?;DM%BUf^eZE+sOy>a){qCY6Y znYy;KGpch-zf=5|p#SoAV+ie8M5(Xg-{FoLx-wZC9IutT!(9rJ8}=!$!h%!J+vE2e z(sURwqCC35v?1>C1L)swfA^sr16{yj7-zbT6Rf26-JoEt%U?+|rQ zeBuGohE?@*!zR9)1P|3>KmJSgK*fOt>N>j}LJB`>o(G#Dduvx7@DY7};W7K;Yj|8O zGF<+gTuoIKe7Rf+LQG3-V1L^|E;F*}bQ-{kuHq}| ze_NwA7~US19sAZ)@a`g*zkl*ykv2v3tPrb4Og2#?k6Lc7@1I~+ew48N&03hW^1Cx+ zfk5Lr4-n=#HYg<7ka5i>2A@ZeJ60gl)IDX!!p zzfXZQ?GrT>JEKl7$SH!otzK6=0dIlqN)c23YLB&Krf9v-{@V8p+-e2`ujFR!^M%*; ze_7(Jh$QgoqwB!HbX=S+^wqO15O_TQ0-qX8f-|&SOuo3ZE{{9Jw5{}>MhY}|GBhO& zv48s_B=9aYQfa;d>~1Z$y^oUUaDer>7ve5+Gf?rIG4GZ!hRKERlRNgg_C{W_!3tsI2TWbX8f~MY)1Q`6Wj&JJ~*;ay_0@e zzx+mE-pu8{cEcVfBqsnm=jFU?H}xj@%CAx#NO>3 z_re3Rq%d1Y7VkKy{=S73&p;4^Praw6Y59VCP6M?!Kt7{v#DG#tz?E)`K95gH_mEvb z%$<~_mQ$ad?~&T=O0i0?`YSp?E3Dj?V>n+uTRHAXn`l!pH9Mr}^D1d@mkf+;(tV45 zH_yfs^kOGLXlN*0GU;O&{=awxd?&`{JPRr$z<1HcAO2K`K}92$wC}ky&>;L?#!(`w z68avZGvb728!vgw>;8Z8I@mLtI`?^u6R>sK4E7%=y)jpmE$fH!Dj*~(dy~-2A5Cm{ zl{1AZw`jaDmfvaB?jvKwz!GC}@-Dz|bFm1OaPw(ia#?>vF7Y5oh{NVbyD~cHB1KFn z9C@f~X*Wk3>sQH9#D~rLPslAd26@AzMh=_NkH_yTNXx6-AdbAb z{Ul89YPHslD?xAGzOlQ*aMYUl6#efCT~WI zOvyiewT=~l1W(_2cEd(8rDywOwjM-7P9!8GCL-1<9KXXO=6%!9=W++*l1L~gRSxLVd8K=A7&t52ql=J&BMQu{fa6y zXO_e>d?4X)xp2V8e3xIQGbq@+vo#&n>-_WreTTW0Yr?|YRPP43cDYACMQ(3t6(?_k zfgDOAU^-pew_f5U#WxRXB30wcfDS3;k~t@b@w^GG&<5n$Ku?tT(%bQH(@UHQGN)N|nfC~7?(etU`}XB)$>KY;s=bYGY#kD%i9fz= z2nN9l?UPMKYwn9bX*^xX8Y@%LNPFU>s#Ea1DaP%bSioqRWi9JS28suTdJycYQ+tW7 zrQ@@=13`HS*dVKaVgcem-45+buD{B;mUbY$YYULhxK)T{S?EB<8^YTP$}DA{(&)@S zS#<8S96y9K2!lG^VW-+CkfXJIH;Vo6wh)N}!08bM$I7KEW{F6tqEQ?H@(U zAqfi%KCe}2NUXALo;UN&k$rU0BLNC$24T_mcNY(a@lxR`kqNQ0z%8m>`&1ro40HX} z{{3YQ;2F9JnVTvDY<4)x+88i@MtXE6TBd7POk&QfKU-F&*C`isS(T_Q@}K)=zW#K@ zbXpcAkTT-T5k}Wj$dMZl7=GvlcCMt}U`#Oon1QdPq%>9J$rKTY8#OmlnNWBYwafhx zqFnym@okL#Xw>4SeRFejBnZzY$jbO)e^&&sHBgMP%Ygfi!9_3hp17=AwLBNFTimf0 zw6BHNXw19Jg_Ud6`5n#gMpqe%9!QB^_7wAYv8nrW94A{*t8XZu0UT&`ZHfkd(F{Px zD&NbRJP#RX<=+sEeGs2`9_*J2OlECpR;4uJie-d__m*(aaGE}HIo+3P{my@;a~9Y$ zHBXVJ83#&@o6{M+pE9^lI<4meLLFN_3rwgR4IRyp)~OF0n+#ORrcJ2_On9-78bWbG zuCO0esc*n1X3@p1?lN{qWS?l7J$^jbpeel{w~51*0CM+q9@9X=>%MF(ce~om(}?td zjkUmdUR@LOn-~6LX#=@a%rvj&>DFEoQscOvvC@&ZB5jVZ-;XzAshwx$;Qf@U41W=q zOSSjQGQV8Qi3*4DngNMIM&Cxm7z*-K`~Bl(TcEUxjQ1c=?)?wF8W1g;bAR%sM#LK( z_Op?=P%)Z+J!>vpN`By0$?B~Out%P}kCriDq@}In&fa_ZyKV+nLM0E?hfxuu%ciUz z>yAk}OydbWNl7{)#112j&qmw;*Uj&B;>|;Qwfc?5wIYIHH}s6Mve@5c5r+y)jK9i( z_}@uC(98g)==AGkVN?4>o@w=7x9qhW^ zB(b5%%4cHSV?3M?k&^py)j*LK16T^Ef4tb05-h-tyrjt$5!oo4spEfXFK7r_Gfv7#x$bsR7T zs;dqxzUg9v&GjsQGKTP*=B(;)be2aN+6>IUz+Hhw-n>^|`^xu*xvjGPaDoFh2W4-n z@Wji{5Y$m>@Vt7TE_QVQN4*vcfWv5VY-dT0SV=l=8LAEq1go*f zkjukaDV=3kMAX6GAf0QOQHwP^{Z^=#Lc)sh`QB)Ftl&31jABvq?8!3bt7#8vxB z53M{4{GR4Hl~;W3r}PgXSNOt477cO62Yj(HcK&30zsmWpvAplCtpp&mC{`2Ue*Bwu zF&UX1;w%`Bs1u%RtGPFl=&sHu@Q1nT`z={;5^c^^S~^?2-?<|F9RT*KQmfgF!7=wD@hytxbD;=9L6PZrK*1<4HMObNWehA62DtTy)q5H|57 z9dePuC!1;0MMRRl!S@VJ8qG=v^~aEU+}2Qx``h1LII!y{crP2ky*R;Cb;g|r<#ryo zju#s4dE?5CTIZKc*O4^3qWflsQ(voX>(*_JP7>Q&$%zCAIBTtKC^JUi@&l6u&t0hXMXjz_y!;r@?k|OU9aD%938^TZ>V? zqJmom_6dz4DBb4Cgs_Ef@}F%+cRCR%UMa9pi<-KHN;t#O@cA%(LO1Rb=h?5jiTs93 zPLR78p+3t>z4|j=<>2i4b`ketv}9Ax#B0)hn7@bFl;rDfP8p7u9XcEb!5*PLKB(s7wQC2kzI^@ae)|DhNDmSy1bOLid%iIap@24A(q2XI!z_hkl-$1T10 z+KKugG4-}@u8(P^S3PW4x>an;XWEF-R^gB{`t8EiP{ZtAzoZ!JRuMRS__-Gg#Qa3{<;l__CgsF+nfmFNi}p z>rV!Y6B@cC>1up)KvaEQiAvQF!D>GCb+WZsGHjDeWFz?WVAHP65aIA8u6j6H35XNYlyy8>;cWe3ekr};b;$9)0G`zsc9LNsQ&D?hvuHRpBxH)r-1t9|Stc*u<}Ol&2N+wPMom}d15_TA=Aprp zjN-X3*Af$7cDWMWp##kOH|t;c2Pa9Ml4-)o~+7P;&q8teF-l}(Jt zTGKOQqJTeT!L4d}Qw~O0aanA$Vn9Rocp-MO4l*HK)t%hcp@3k0%&_*wwpKD6ThM)R z8k}&7?)YS1ZYKMiy?mn>VXiuzX7$Ixf7EW8+C4K^)m&eLYl%#T=MC;YPvD&w#$MMf zQ=>`@rh&&r!@X&v%ZlLF42L_c=5dSU^uymKVB>5O?AouR3vGv@ei%Z|GX5v1GK2R* zi!!}?+-8>J$JH^fPu@)E6(}9$d&9-j51T^n-e0Ze%Q^)lxuex$IL^XJ&K2oi`wG}QVGk2a7vC4X?+o^z zsCK*7`EUfSuQA*K@Plsi;)2GrayQOG9OYF82Hc@6aNN5ulqs1Of-(iZQdBI^U5of^ zZg2g=Xtad7$hfYu6l~KDQ}EU;oIj(3nO#u9PDz=eO3(iax7OCmgT2p_7&^3q zg7aQ;Vpng*)kb6=sd5?%j5Dm|HczSChMo8HHq_L8R;BR5<~DVyU$8*Tk5}g0eW5x7 z%d)JFZ{(Y<#OTKLBA1fwLM*fH7Q~7Sc2Ne;mVWqt-*o<;| z^1@vo_KTYaMnO$7fbLL+qh#R$9bvnpJ$RAqG+z8h|} z3F5iwG*(sCn9Qbyg@t0&G}3fE0jGq3J!JmG2K&$urx^$z95) z7h?;4vE4W=v)uZ*Eg3M^6f~|0&T)2D;f+L_?M*21-I1pnK(pT$5l#QNlT`SidYw~o z{`)G)Asv#cue)Ax1RNWiRUQ(tQ(bzd-f2U4xlJK+)ZWBxdq#fp=A>+Qc%-tl(c)`t z$e2Ng;Rjvnbu7((;v4LF9Y1?0el9hi!g>G{^37{ z`^s-03Z5jlnD%#Mix19zkU_OS|86^_x4<0(*YbPN}mi-$L?Z4K(M|2&VV*n*ZYN_UqI?eKZi3!b)i z%n3dzUPMc-dc|q}TzvPy!VqsEWCZL(-eURDRG4+;Eu!LugSSI4Fq$Ji$Dp08`pfP_C5Yx~`YKcywlMG;$F z)R5!kVml_Wv6MSpeXjG#g?kJ0t_MEgbXlUN3k|JJ%N>|2xn8yN>>4qxh!?dGI}s|Y zDTKd^JCrRSN+%w%D_uf=Tj6wIV$c*g8D96jb^Kc#>5Fe-XxKC@!pIJw0^zu;`_yeb zhUEm-G*C=F+jW%cP(**b61fTmPn2WllBr4SWNdKe*P8VabZsh0-R|?DO=0x`4_QY) zR7sthW^*BofW7{Sak&S1JdiG?e=SfL24Y#w_)xrBVhGB-13q$>mFU|wd9Xqe-o3{6 zSn@@1@&^)M$rxb>UmFuC+pkio#T;mSnroMVZJ%nZ!uImi?%KsIX#@JU2VY(`kGb1A z7+1MEG)wd@)m^R|a2rXeviv$!emwcY(O|M*xV!9%tBzarBOG<4%gI9SW;Um_gth4=gznYzOFd)y8e+3APCkL)i-OI`;@7-mCJgE`js(M} z;~ZcW{{FMVVO)W>VZ}ILouF#lWGb%Couu}TI4kubUUclW@jEn6B_^v!Ym*(T*4HF9 zWhNKi8%sS~viSdBtnrq!-Dc5(G^XmR>DFx8jhWvR%*8!m*b*R8e1+`7{%FACAK`7 zzdy8TmBh?FVZ0vtw6npnWwM~XjF2fNvV#ZlGG z?FxHkXHN>JqrBYoPo$)zNC7|XrQfcqmEXWud~{j?La6@kbHG@W{xsa~l1=%eLly8B z4gCIH05&Y;6O2uFSopNqP|<$ml$N40^ikxw0`o<~ywS1(qKqQN!@?Ykl|bE4M?P+e zo$^Vs_+x)iuw?^>>`$&lOQOUkZ5>+OLnRA)FqgpDjW&q*WAe(_mAT6IKS9;iZBl8M z<@=Y%zcQUaSBdrs27bVK`c$)h6A1GYPS$y(FLRD5Yl8E3j0KyH08#8qLrsc_qlws; znMV%Zq8k+&T2kf%6ZO^2=AE9>?a587g%-={X}IS~P*I(NeCF9_9&`)|ok0iiIun zo+^odT0&Z4k;rn7I1v87=z!zKU(%gfB$(1mrRYeO$sbqM22Kq68z9wgdg8HBxp>_< zn9o%`f?sVO=IN#5jSX&CGODWlZfQ9A)njK2O{JutYwRZ?n0G_p&*uwpE`Md$iQxrd zoQfF^b8Ou)+3BO_3_K5y*~?<(BF@1l+@?Z6;^;U>qlB)cdro;rxOS1M{Az$s^9o5sXDCg8yD<=(pKI*0e zLk>@lo#&s0)^*Q+G)g}C0IErqfa9VbL*Qe=OT@&+N8m|GJF7jd83vY#SsuEv2s{Q> z>IpoubNs>D_5?|kXGAPgF@mb_9<%hjU;S0C8idI)a=F#lPLuQJ^7OnjJlH_Sks9JD zMl1td%YsWq3YWhc;E$H1<0P$YbSTqs`JKY%(}svsifz|h8BHguL82dBl+z0^YvWk8 zGy;7Z0v5_FJ2A$P0wIr)lD?cPR%cz>kde!=W%Ta^ih+Dh4UKdf7ip?rBz@%y2&>`6 zM#q{JXvW9ZlaSk1oD!n}kSmcDa2v6T^Y-dy+#fW^y>eS8_%<7tWXUp8U@s$^{JFfKMjDAvR z$YmVB;n3ofl!ro9RNT!TpQpcycXCR}$9k5>IPWDXEenQ58os?_weccrT+Bh5sLoiH zZ_7~%t(vT)ZTEO= zb0}@KaD{&IyK_sd8b$`Qz3%UA`nSo zn``!BdCeN!#^G;lK@G2ron*0jQhbdw)%m$2;}le@z~PSLnU-z@tL)^(p%P>OO^*Ff zNRR9oQ`W+x^+EU+3BpluwK77|B3=8QyT|$V;02bn_LF&3LhLA<#}{{)jE)}CiW%VEU~9)SW+=F%7U-iYlQ&q!#N zwI2{(h|Pi&<8_fqvT*}FLN^0CxN}#|3I9G_xmVg$gbn2ZdhbmGk7Q5Q2Tm*ox8NMo zv`iaZW|ZEOMyQga5fts?&T-eCCC9pS0mj7v0SDkD=*^MxurP@89v&Z#3q{FM!a_nr zb?KzMv`BBFOew>4!ft@A&(v-kWXny-j#egKef|#!+3>26Qq0 zv!~8ev4G`7Qk>V1TaMT-&ziqoY3IJp8_S*%^1j73D|=9&;tDZH^!LYFMmME4*Wj(S zRt~Q{aLb_O;wi4u&=}OYuj}Lw*j$@z*3>4&W{)O-oi@9NqdoU!=U%d|se&h?^$Ip# z)BY+(1+cwJz!yy4%l(aLC;T!~Ci>yAtXJb~b*yr&v7f{YCU8P|N1v~H`xmGsG)g)y z4%mv=cPd`s7a*#OR7f0lpD$ueP>w8qXj0J&*7xX+U!uat5QNk>zwU$0acn5p=$88L=jn_QCSYkTV;1~(yUem#0gB`FeqY98sf=>^@ z_MCdvylv~WL%y_%y_FE1)j;{Szj1+K7Lr_y=V+U zk6Tr;>XEqlEom~QGL!a+wOf(@ZWoxE<$^qHYl*H1a~kk^BLPn785%nQb$o;Cuz0h& za9LMx^bKEbPS%e8NM33Jr|1T|ELC(iE!FUci38xW_Y7kdHid#2ie+XZhP;2!Z;ZAM zB_cXKm)VrPK!SK|PY00Phwrpd+x0_Aa;}cDQvWKrwnQrqz##_gvHX2ja?#_{f#;bz`i>C^^ zTLDy;6@HZ~XQi7rph!mz9k!m;KchA)uMd`RK4WLK7)5Rl48m#l>b(#`WPsl<0j z-sFkSF6>Nk|LKnHtZ`W_NnxZP62&w)S(aBmmjMDKzF%G;3Y?FUbo?>b5;0j8Lhtc4 zr*8d5Y9>g@FFZaViw7c16VsHcy0u7M%6>cG1=s=Dtx?xMJSKIu9b6GU8$uSzf43Y3 zYq|U+IWfH;SM~*N1v`KJo!|yfLxTFS?oHsr3qvzeVndVV^%BWmW6re_S!2;g<|Oao z+N`m#*i!)R%i1~NO-xo{qpwL0ZrL7hli;S z3L0lQ_z}z`fdK39Mg~Zd*%mBdD;&5EXa~@H(!###L`ycr7gW`f)KRuqyHL3|uyy3h zSS^td#E&Knc$?dXs*{EnPYOp^-vjAc-h4z#XkbG&REC7;0>z^^Z}i8MxGKerEY z>l?(wReOlXEsNE5!DO&ZWyxY)gG#FSZs%fXuzA~XIAPVp-%yb2XLSV{1nH6{)5opg z(dZKckn}Q4Li-e=eUDs1Psg~5zdn1>ql(*(nn6)iD*OcVkwmKL(A{fix(JhcVB&}V zVt*Xb!{gzvV}dc446>(D=SzfCu7KB`oMjv6kPzSv&B>>HLSJP|wN`H;>oRw*tl#N) z*zZ-xwM7D*AIsBfgqOjY1Mp9aq$kRa^dZU_xw~KxP;|q(m+@e+YSn~`wEJzM|Ippb zzb@%;hB7iH4op9SqmX?j!KP2chsb79(mFossBO-Zj8~L}9L%R%Bw<`^X>hjkCY5SG z7lY!8I2mB#z)1o;*3U$G)3o0A&{0}#B;(zPd2`OF`Gt~8;0Re8nIseU z_yzlf$l+*-wT~_-cYk$^wTJ@~7i@u(CZs9FVkJCru<*yK8&>g+t*!JqCN6RH%8S-P zxH8+Cy#W?!;r?cLMC(^BtAt#xPNnwboI*xWw#T|IW^@3|q&QYY6Ehxoh@^URylR|T zne-Y6ugE^7p5bkRDWIh)?JH5V^ub82l-LuVjDr7UT^g`q4dB&mBFRWGL_C?hoeL(% zo}ocH5t7|1Mda}T!^{Qt9vmA2ep4)dQSZO>?Eq8}qRp&ZJ?-`Tnw+MG(eDswP(L*X3ahC2Ad0_wD^ff9hfzb%Jd`IXx5 zae@NMzBXJDwJS?7_%!TB^E$N8pvhOHDK$7YiOelTY`6KX8hK6YyT$tk*adwN>s^Kp zwM3wGVPhwKU*Yq-*BCs}l`l#Tej(NQ>jg*S0TN%D+GcF<14Ms6J`*yMY;W<-mMN&-K>((+P}+t+#0KPGrzjP zJ~)=Bcz%-K!L5ozIWqO(LM)l_9lVOc4*S65&DKM#TqsiWNG{(EZQw!bc>qLW`=>p-gVJ;T~aN2D_- z{>SZC=_F+%hNmH6ub%Ykih0&YWB!%sd%W5 zHC2%QMP~xJgt4>%bU>%6&uaDtSD?;Usm}ari0^fcMhi_)JZgb1g5j zFl4`FQ*%ROfYI}e7RIq^&^a>jZF23{WB`T>+VIxj%~A-|m=J7Va9FxXV^%UwccSZd zuWINc-g|d6G5;95*%{e;9S(=%yngpfy+7ao|M7S|Jb0-4+^_q-uIqVS&ufU880UDH*>(c)#lt2j zzvIEN>>$Y(PeALC-D?5JfH_j+O-KWGR)TKunsRYKLgk7eu4C{iF^hqSz-bx5^{z0h ze2+u>Iq0J4?)jIo)}V!!m)%)B;a;UfoJ>VRQ*22+ncpe9f4L``?v9PH&;5j{WF?S_C>Lq>nkChZB zjF8(*v0c(lU^ZI-)_uGZnnVRosrO4`YinzI-RSS-YwjYh3M`ch#(QMNw*)~Et7Qpy z{d<3$4FUAKILq9cCZpjvKG#yD%-juhMj>7xIO&;c>_7qJ%Ae8Z^m)g!taK#YOW3B0 zKKSMOd?~G4h}lrZbtPk)n*iOC1~mDhASGZ@N{G|dF|Q^@1ljhe=>;wusA&NvY*w%~ zl+R6B^1yZiF)YN>0ms%}qz-^U-HVyiN3R9k1q4)XgDj#qY4CE0)52%evvrrOc898^ z*^)XFR?W%g0@?|6Mxo1ZBp%(XNv_RD-<#b^?-Fs+NL^EUW=iV|+Vy*F%;rBz~pN7%-698U-VMfGEVnmEz7fL1p)-5sLT zL;Iz>FCLM$p$c}g^tbkGK1G$IALq1Gd|We@&TtW!?4C7x4l*=4oF&&sr0Hu`x<5!m zhX&&Iyjr?AkNXU_5P_b^Q3U9sy#f6ZF@2C96$>1k*E-E%DjwvA{VL0PdU~suN~DZo zm{T!>sRdp`Ldpp9olrH@(J$QyGq!?#o1bUo=XP2OEuT3`XzI>s^0P{manUaE4pI%! zclQq;lbT;nx7v3tR9U)G39h?ryrxzd0xq4KX7nO?piJZbzT_CU&O=T(Vt;>jm?MgC z2vUL#*`UcMsx%w#vvjdamHhmN!(y-hr~byCA-*iCD};#l+bq;gkwQ0oN=AyOf@8ow>Pj<*A~2*dyjK}eYdN);%!t1 z6Y=|cuEv-|5BhA?n2Db@4s%y~(%Wse4&JXw=HiO48%c6LB~Z0SL1(k^9y?ax%oj~l zf7(`iAYLdPRq*ztFC z7VtAb@s{as%&Y;&WnyYl+6Wm$ru*u!MKIg_@01od-iQft0rMjIj8e7P9eKvFnx_X5 zd%pDg-|8<>T2Jdqw>AII+fe?CgP+fL(m0&U??QL8YzSjV{SFi^vW~;wN@or_(q<0Y zRt~L}#JRcHOvm$CB)T1;;7U>m%)QYBLTR)KTARw%zoDxgssu5#v{UEVIa<>{8dtkm zXgbCGp$tfue+}#SD-PgiNT{Zu^YA9;4BnM(wZ9-biRo_7pN}=aaimjYgC=;9@g%6< zxol5sT_$<8{LiJ6{l1+sV)Z_QdbsfEAEMw!5*zz6)Yop?T0DMtR_~wfta)E6_G@k# zZRP11D}$ir<`IQ`<(kGfAS?O-DzCyuzBq6dxGTNNTK?r^?zT30mLY!kQ=o~Hv*k^w zvq!LBjW=zzIi%UF@?!g9vt1CqdwV(-2LYy2=E@Z?B}JDyVkluHtzGsWuI1W5svX~K z&?UJ45$R7g>&}SFnLnmw09R2tUgmr_w6mM9C}8GvQX>nL&5R#xBqnp~Se(I>R42`T zqZe9p6G(VzNB3QD><8+y%{e%6)sZDRXTR|MI zM#eZmao-~_`N|>Yf;a;7yvd_auTG#B?Vz5D1AHx=zpVUFe7*hME z+>KH5h1In8hsVhrstc>y0Q!FHR)hzgl+*Q&5hU9BVJlNGRkXiS&06eOBV^dz3;4d5 zeYX%$62dNOprZV$px~#h1RH?_E%oD6y;J;pF%~y8M)8pQ0olYKj6 zE+hd|7oY3ot=j9ZZ))^CCPADL6Jw%)F@A{*coMApcA$7fZ{T@3;WOQ352F~q6`Mgi z$RI6$8)a`Aaxy<8Bc;{wlDA%*%(msBh*xy$L-cBJvQ8hj#FCyT^%+Phw1~PaqyDou^JR0rxDkSrmAdjeYDFDZ`E z)G3>XtpaSPDlydd$RGHg;#4|4{aP5c_Om z2u5xgnhnA)K%8iU==}AxPxZCYC)lyOlj9as#`5hZ=<6<&DB%i_XCnt5=pjh?iusH$ z>)E`@HNZcAG&RW3Ys@`Ci{;8PNzE-ZsPw$~Wa!cP$ye+X6;9ceE}ah+3VY7Mx}#0x zbqYa}eO*FceiY2jNS&2cH9Y}(;U<^^cWC5Ob&)dZedvZA9HewU3R;gRQ)}hUdf+~Q zS_^4ds*W1T#bxS?%RH&<739q*n<6o|mV;*|1s>ly-Biu<2*{!!0#{_234&9byvn0* z5=>{95Zfb{(?h_Jk#ocR$FZ78O*UTOxld~0UF!kyGM|nH%B*qf)Jy}N!uT9NGeM19 z-@=&Y0yGGo_dw!FD>juk%P$6$qJkj}TwLBoefi;N-$9LAeV|)|-ET&culW9Sb_pc_ zp{cXI0>I0Jm_i$nSvGnYeLSSj{ccVS2wyL&0x~&5v;3Itc82 z5lIAkfn~wcY-bQB$G!ufWt%qO;P%&2B_R5UKwYxMemIaFm)qF1rA zc>gEihb=jBtsXCi0T%J37s&kt*3$s7|6)L(%UiY)6axuk{6RWIS8^+u;)6!R?Sgap z9|6<0bx~AgVi|*;zL@2x>Pbt2Bz*uv4x-`{F)XatTs`S>unZ#P^ZiyjpfL_q2z^fqgR-fbOcG=Y$q>ozkw1T6dH8-)&ww+z?E0 zR|rV(9bi6zpX3Ub>PrPK!{X>e$C66qCXAeFm)Y+lX8n2Olt7PNs*1^si)j!QmFV#t z0P2fyf$N^!dyTot&`Ew5{i5u<8D`8U`qs(KqaWq5iOF3x2!-z65-|HsyYz(MAKZ?< zCpQR;E)wn%s|&q(LVm0Ab>gdmCFJeKwVTnv@Js%!At;I=A>h=l=p^&<4;Boc{$@h< z38v`3&2wJtka@M}GS%9!+SpJ}sdtoYzMevVbnH+d_eMxN@~~ zZq@k)7V5f8u!yAX2qF3qjS7g%n$JuGrMhQF!&S^7(%Y{rP*w2FWj(v_J{+Hg*}wdWOd~pHQ19&n3RWeljK9W%sz&Y3Tm3 zR`>6YR54%qBHGa)2xbs`9cs_EsNHxsfraEgZ)?vrtooeA0sPKJK7an){ngtV@{SBa zkO6ORr1_Xqp+`a0e}sC*_y(|RKS13ikmHp3C^XkE@&wjbGWrt^INg^9lDz#B;bHiW zkK4{|cg08b!yHFSgPca5)vF&gqCgeu+c82%&FeM^Bb}GUxLy-zo)}N;#U?sJ2?G2BNe*9u_7kE5JeY!it=f`A_4gV3} z`M!HXZy#gN-wS!HvHRqpCHUmjiM;rVvpkC!voImG%OFVN3k(QG@X%e``VJSJ@Z7tb z*Onlf>z^D+&$0!4`IE$;2-NSO9HQWd+UFW(r;4hh;(j^p4H-~6OE!HQp^96v?{9Zt z;@!ZcccV%C2s6FMP#qvo4kG6C04A>XILt>JW}%0oE&HM5f6 zYLD!;My>CW+j<~=Wzev{aYtx2ZNw|ptTFV(4;9`6Tmbz6K1)fv4qPXa2mtoPt&c?P zhmO+*o8uP3ykL6E$il00@TDf6tOW7fmo?Oz_6GU^+5J=c22bWyuH#aNj!tT-^IHrJ zu{aqTYw@q;&$xDE*_kl50Jb*dp`(-^p={z}`rqECTi~3 z>0~A7L6X)=L5p#~$V}gxazgGT7$3`?a)zen>?TvAuQ+KAIAJ-s_v}O6@`h9n-sZk> z`3{IJeb2qu9w=P*@q>iC`5wea`KxCxrx{>(4{5P+!cPg|pn~;n@DiZ0Y>;k5mnKeS z!LIfT4{Lgd=MeysR5YiQKCeNhUQ;Os1kAymg6R!u?j%LF z4orCszIq_n52ulpes{(QN|zirdtBsc{9^Z72Ycb2ht?G^opkT_#|4$wa9`)8k3ilU z%ntAi`nakS1r10;#k^{-ZGOD&Z2|k=p40hRh5D7(&JG#Cty|ECOvwsSHkkSa)36$4 z?;v#%@D(=Raw(HP5s>#4Bm?f~n1@ebH}2tv#7-0l-i^H#H{PC|F@xeNS+Yw{F-&wH z07)bj8MaE6`|6NoqKM~`4%X> zKFl&7g1$Z3HB>lxn$J`P`6GSb6CE6_^NA1V%=*`5O!zP$a7Vq)IwJAki~XBLf=4TF zPYSL}>4nOGZ`fyHChq)jy-f{PKFp6$plHB2=;|>%Z^%)ecVue(*mf>EH_uO^+_zm? zJATFa9SF~tFwR#&0xO{LLf~@}s_xvCPU8TwIJgBs%FFzjm`u?1699RTui;O$rrR{# z1^MqMl5&6)G%@_k*$U5Kxq84!AdtbZ!@8FslBML}<`(Jr zenXrC6bFJP=R^FMBg7P?Pww-!a%G@kJH_zezKvuWU0>m1uyy}#Vf<$>u?Vzo3}@O% z1JR`B?~Tx2)Oa|{DQ_)y9=oY%haj!80GNHw3~qazgU-{|q+Bl~H94J!a%8UR?XsZ@ z0*ZyQugyru`V9b(0OrJOKISfi89bSVR zQy<+i_1XY}4>|D%X_`IKZUPz6=TDb)t1mC9eg(Z=tv zq@|r37AQM6A%H%GaH3szv1L^ku~H%5_V*fv$UvHl*yN4iaqWa69T2G8J2f3kxc7UE zOia@p0YNu_q-IbT%RwOi*|V|&)e5B-u>4=&n@`|WzH}BK4?33IPpXJg%`b=dr_`hU z8JibW_3&#uIN_#D&hX<)x(__jUT&lIH$!txEC@cXv$7yB&Rgu){M`9a`*PH} zRcU)pMWI2O?x;?hzR{WdzKt^;_pVGJAKKd)F$h;q=Vw$MP1XSd<;Mu;EU5ffyKIg+ z&n-Nb?h-ERN7(fix`htopPIba?0Gd^y(4EHvfF_KU<4RpN0PgVxt%7Yo99X*Pe|zR z?ytK&5qaZ$0KSS$3ZNS$$k}y(2(rCl=cuYZg{9L?KVgs~{?5adxS))Upm?LDo||`H zV)$`FF3icFmxcQshXX*1k*w3O+NjBR-AuE70=UYM*7>t|I-oix=bzDwp2*RoIwBp@r&vZukG; zyi-2zdyWJ3+E?{%?>e2Ivk`fAn&Ho(KhGSVE4C-zxM-!j01b~mTr>J|5={PrZHOgO zw@ND3=z(J7D>&C7aw{zT>GHhL2BmUX0GLt^=31RRPSnjoUO9LYzh_yegyPoAKhAQE z>#~O27dR4&LdQiak6={9_{LN}Z>;kyVYKH^d^*!`JVSXJlx#&r4>VnP$zb{XoTb=> zZsLvh>keP3fkLTIDdpf-@(ADfq4=@X=&n>dyU0%dwD{zsjCWc;r`-e~X$Q3NTz_TJ zOXG|LMQQIjGXY3o5tBm9>k6y<6XNO<=9H@IXF;63rzsC=-VuS*$E{|L_i;lZmHOD< zY92;>4spdeRn4L6pY4oUKZG<~+8U-q7ZvNOtW0i*6Q?H`9#U3M*k#4J;ek(MwF02x zUo1wgq9o6XG#W^mxl>pAD)Ll-V5BNsdVQ&+QS0+K+?H-gIBJ-ccB1=M_hxB6qcf`C zJ?!q!J4`kLhAMry4&a_0}up{CFevcjBl|N(uDM^N5#@&-nQt2>z*U}eJGi}m5f}l|IRVj-Q;a>wcLpK5RRWJ> zysdd$)Nv0tS?b~bw1=gvz3L_ZAIdDDPj)y|bp1;LE`!av!rODs-tlc}J#?erTgXRX z$@ph%*~_wr^bQYHM7<7=Q=45v|Hk7T=mDpW@OwRy3A_v`ou@JX5h!VI*e((v*5Aq3 zVYfB4<&^Dq5%^?~)NcojqK`(VXP$`#w+&VhQOn%;4pCkz;NEH6-FPHTQ+7I&JE1+Ozq-g43AEZV>ceQ^9PCx zZG@OlEF~!Lq@5dttlr%+gNjRyMwJdJU(6W_KpuVnd{3Yle(-p#6erIRc${l&qx$HA z89&sp=rT7MJ=DuTL1<5{)wtUfpPA|Gr6Q2T*=%2RFm@jyo@`@^*{5{lFPgv>84|pv z%y{|cVNz&`9C*cUely>-PRL)lHVErAKPO!NQ3<&l5(>Vp(MuJnrOf^4qpIa!o3D7( z1bjn#Vv$#or|s7Hct5D@%;@48mM%ISY7>7@ft8f?q~{s)@BqGiupoK1BAg?PyaDQ1 z`YT8{0Vz{zBwJ={I4)#ny{RP{K1dqzAaQN_aaFC%Z>OZ|^VhhautjDavGtsQwx@WH zr|1UKk^+X~S*RjCY_HN!=Jx>b6J8`Q(l4y|mc<6jnkHVng^Wk(A13-;AhawATsmmE#H%|8h}f1frs2x@Fwa_|ea+$tdG2Pz{7 z!ox^w^>^Cv4e{Xo7EQ7bxCe8U+LZG<_e$RnR?p3t?s^1Mb!ieB z#@45r*PTc_yjh#P=O8Zogo+>1#|a2nJvhOjIqKK1U&6P)O%5s~M;99O<|Y9zomWTL z666lK^QW`)cXV_^Y05yQZH3IRCW%25BHAM$c0>w`x!jh^15Zp6xYb!LoQ zr+RukTw0X2mxN%K0%=8|JHiaA3pg5+GMfze%9o5^#upx0M?G9$+P^DTx7~qq9$Qoi zV$o)yy zuUq>3c{_q+HA5OhdN*@*RkxRuD>Bi{Ttv_hyaaB;XhB%mJ2Cb{yL;{Zu@l{N?!GKE7es6_9J{9 zO(tmc0ra2;@oC%SS-8|D=omQ$-Dj>S)Utkthh{ovD3I%k}HoranSepC_yco2Q8 zY{tAuPIhD{X`KbhQIr%!t+GeH%L%q&p z3P%<-S0YY2Emjc~Gb?!su85}h_qdu5XN2XJUM}X1k^!GbwuUPT(b$Ez#LkG6KEWQB z7R&IF4srHe$g2R-SB;inW9T{@+W+~wi7VQd?}7||zi!&V^~o0kM^aby7YE_-B63^d zf_uo8#&C77HBautt_YH%v6!Q>H?}(0@4pv>cM6_7dHJ)5JdyV0Phi!)vz}dv{*n;t zf(+#Hdr=f8DbJqbMez)(n>@QT+amJ7g&w6vZ-vG^H1v~aZqG~u!1D(O+jVAG0EQ*aIsr*bsBdbD`)i^FNJ z&B@yxqPFCRGT#}@dmu-{0vp47xk(`xNM6E=7QZ5{tg6}#zFrd8Pb_bFg7XP{FsYP8 zbvWqG6#jfg*4gvY9!gJxJ3l2UjP}+#QMB(*(?Y&Q4PO`EknE&Cb~Yb@lCbk;-KY)n zzbjS~W5KZ3FV%y>S#$9Sqi$FIBCw`GfPDP|G=|y32VV-g@a1D&@%_oAbB@cAUx#aZ zlAPTJ{iz#Qda8(aNZE&0q+8r3&z_Ln)b=5a%U|OEcc3h1f&8?{b8ErEbilrun}mh3 z$1o^$-XzIiH|iGoJA`w`o|?w3m*NX|sd$`Mt+f*!hyJvQ2fS*&!SYn^On-M|pHGlu z4SC5bM7f6BAkUhGuN*w`97LLkbCx=p@K5RL2p>YpDtf{WTD|d3ucb6iVZ-*DRtoEA zCC5(x)&e=giR_id>5bE^l%Mxx>0@FskpCD4oq@%-Fg$8IcdRwkfn;DsjoX(v;mt3d z_4Mnf#Ft4x!bY!7Hz?RRMq9;5FzugD(sbt4up~6j?-or+ch~y_PqrM2hhTToJjR_~ z)E1idgt7EW>G*9%Q^K;o_#uFjX!V2pwfpgi>}J&p_^QlZki!@#dkvR`p?bckC`J*g z=%3PkFT3HAX2Q+dShHUbb1?ZcK8U7oaufLTCB#1W{=~k0Jabgv>q|H+GU=f-y|{p4 zwN|AE+YbCgx=7vlXE?@gkXW9PaqbO#GB=4$o0FkNT#EI?aLVd2(qnPK$Yh%YD%v(mdwn}bgsxyIBI^)tY?&G zi^2JfClZ@4b{xFjyTY?D61w@*ez2@5rWLpG#34id?>>oPg{`4F-l`7Lg@D@Hc}On} zx%BO4MsLYosLGACJ-d?ifZ35r^t*}wde>AAWO*J-X%jvD+gL9`u`r=kP zyeJ%FqqKfz8e_3K(M1RmB?gIYi{W7Z<THP2ihue0mbpu5n(x_l|e1tw(q!#m5lmef6ktqIb${ zV+ee#XRU}_dDDUiV@opHZ@EbQ<9qIZJMDsZDkW0^t3#j`S)G#>N^ZBs8k+FJhAfu< z%u!$%dyP3*_+jUvCf-%{x#MyDAK?#iPfE<(@Q0H7;a125eD%I(+!x1f;Sy`e<9>nm zQH4czZDQmW7^n>jL)@P@aAuAF$;I7JZE5a8~AJI5CNDqyf$gjloKR7C?OPt9yeH}n5 zNF8Vhmd%1O>T4EZD&0%Dt7YWNImmEV{7QF(dy!>q5k>Kh&Xy8hcBMUvVV~Xn8O&%{ z&q=JCYw#KlwM8%cu-rNadu(P~i3bM<_a{3!J*;vZhR6dln6#eW0^0kN)Vv3!bqM`w z{@j*eyzz=743dgFPY`Cx3|>ata;;_hQ3RJd+kU}~p~aphRx`03B>g4*~f%hUV+#D9rYRbsGD?jkB^$3XcgB|3N1L& zrmk9&Dg450mAd=Q_p?gIy5Zx7vRL?*rpNq76_rysFo)z)tp0B;7lSb9G5wX1vC9Lc z5Q8tb-alolVNWFsxO_=12o}X(>@Mwz1mkYh1##(qQwN=7VKz?61kay8A9(94Ky(4V zq6qd2+4a20Z0QRrmp6C?4;%U?@MatfXnkj&U6bP_&2Ny}BF%4{QhNx*Tabik9Y-~Z z@0WV6XD}aI(%pN}oW$X~Qo_R#+1$@J8(31?zM`#e`#(0f<-AZ^={^NgH#lc?oi(Mu zMk|#KR^Q;V@?&(sh5)D;-fu)rx%gXZ1&5)MR+Mhssy+W>V%S|PRNyTAd}74<(#J>H zR(1BfM%eIv0+ngHH6(i`?-%_4!6PpK*0X)79SX0X$`lv_q>9(E2kkkP;?c@rW2E^Q zs<;`9dg|lDMNECFrD3jTM^Mn-C$44}9d9Kc z#>*k&e#25;D^%82^1d@Yt{Y91MbEu0C}-;HR4+IaCeZ`l?)Q8M2~&E^FvJ?EBJJ(% zz1>tCW-E~FB}DI}z#+fUo+=kQME^=eH>^%V8w)dh*ugPFdhMUi3R2Cg}Zak4!k_8YW(JcR-)hY8C zXja}R7@%Q0&IzQTk@M|)2ViZDNCDRLNI)*lH%SDa^2TG4;%jE4n`8`aQAA$0SPH2@ z)2eWZuP26+uGq+m8F0fZn)X^|bNe z#f{qYZS!(CdBdM$N2(JH_a^b#R2=>yVf%JI_ieRFB{w&|o9txwMrVxv+n78*aXFGb z>Rkj2yq-ED<)A46T9CL^$iPynv`FoEhUM10@J+UZ@+*@_gyboQ>HY9CiwTUo7OM=w zd~$N)1@6U8H#Zu(wGLa_(Esx%h@*pmm5Y9OX@CY`3kPYPQx@z8yAgtm(+agDU%4?c zy8pR4SYbu8vY?JX6HgVq7|f=?w(%`m-C+a@E{euXo>XrGmkmFGzktI*rj*8D z)O|CHKXEzH{~iS+6)%ybRD|JRQ6j<+u_+=SgnJP%K+4$st+~XCVcAjI9e5`RYq$n{ zzy!X9Nv7>T4}}BZpSj9G9|(4ei-}Du<_IZw+CB`?fd$w^;=j8?vlp(#JOWiHaXJjB0Q00RHJ@sG6N#y^H7t^&V} z;VrDI4?75G$q5W9mV=J2iP24NHJy&d|HWHva>FaS#3AO?+ohh1__FMx;?`f{HG3v0 ztiO^Wanb>U4m9eLhoc_2B(ca@YdnHMB*~aYO+AE(&qh@?WukLbf_y z>*3?Xt-lxr?#}y%kTv+l8;!q?Hq8XSU+1E8x~o@9$)zO2z9K#(t`vPDri`mKhv|sh z{KREcy`#pnV>cTT7dm7M9B@9qJRt3lfo(C`CNkIq@>|2<(yn!AmVN?ST zbX_`JjtWa3&N*U{K7FYX8})*D#2@KBae` zhKS~s!r%SrXdhCsv~sF}7?ocyS?afya6%rDBu6g^b2j#TOGp^1zrMR}|70Z>CeYq- z1o|-=FBKlu{@;pm@QQJ_^!&hzi;0Z_Ho){x3O1KQ#TYk=rAt9`YKC0Y^}8GWIN{QW znYJyVTrmNvl!L=YS1G8BAxGmMUPi+Q7yb0XfG`l+L1NQVSbe^BICYrD;^(rke{jWCEZOtVv3xFze!=Z&(7}!)EcN;v0Dbit?RJ6bOr;N$ z=nk8}H<kCEE+IK3z<+3mkn4q!O7TMWpKShWWWM)X*)m6k%3luF6c>zOsFccvfLWf zH+mNkh!H@vR#~oe=ek}W3!71z$Dlj0c(%S|sJr>rvw!x;oCek+8f8s!U{DmfHcNpO z9>(IKOMfJwv?ey`V2ysSx2Npeh_x#bMh)Ngdj$al;5~R7Ac5R2?*f{hI|?{*$0qU- zY$6}ME%OGh^zA^z9zJUs-?a4ni8cw_{cYED*8x{bWg!Fn9)n;E9@B+t;#k}-2_j@# zg#b%R(5_SJAOtfgFCBZc`n<&z6)%nOIu@*yo!a% zpLg#36KBN$01W{b;qWN`Tp(T#jh%;Zp_zpS64lvBVY2B#UK)p`B4Oo)IO3Z&D6<3S zfF?ZdeNEnzE{}#gyuv)>;z6V{!#bx)` zY;hL*f(WVD*D9A4$WbRKF2vf;MoZVdhfWbWhr{+Db5@M^A4wrFReuWWimA4qp`GgoL2`W4WPUL5A=y3Y3P z%G?8lLUhqo@wJW8VDT`j&%YY7xh51NpVYlsrk_i4J|pLO(}(b8_>%U2M`$iVRDc-n zQiOdJbroQ%*vhN{!{pL~N|cfGooK_jTJCA3g_qs4c#6a&_{&$OoSQr_+-O^mKP=Fu zGObEx`7Qyu{nHTGNj(XSX*NPtAILL(0%8Jh)dQh+rtra({;{W2=f4W?Qr3qHi*G6B zOEj7%nw^sPy^@05$lOCjAI)?%B%&#cZ~nC|=g1r!9W@C8T0iUc%T*ne z)&u$n>Ue3FN|hv+VtA+WW)odO-sdtDcHfJ7s&|YCPfWaVHpTGN46V7Lx@feE#Od%0XwiZy40plD%{xl+K04*se zw@X4&*si2Z_0+FU&1AstR)7!Th(fdaOlsWh`d!y=+3m!QC$Zlkg8gnz!}_B7`+wSz z&kD?6{zPnE3uo~Tv8mLP%RaNt2hcCJBq=0T>%MW~Q@Tpt2pPP1?KcywH>in5@ zx+5;xu-ltFfo5vLU;2>r$-KCHjwGR&1XZ0YNyrXXAUK!FLM_7mV&^;;X^*YH(FLRr z`0Jjg7wiq2bisa`CG%o9i)o1`uG?oFjU_Zrv1S^ipz$G-lc^X@~6*)#%nn+RbgksJfl{w=k31(q>7a!PCMp5YY{+Neh~mo zG-3dd!0cy`F!nWR?=9f_KP$X?Lz&cLGm_ohy-|u!VhS1HG~e7~xKpYOh=GmiiU;nu zrZ5tWfan3kp-q_vO)}vY6a$19Q6UL0r znJ+iSHN-&w@vDEZ0V%~?(XBr|jz&vrBNLOngULxtH(Rp&U*rMY42n;05F11xh?k;n_DX2$4|vWIkXnbwfC z=ReH=(O~a;VEgVO?>qsP*#eOC9Y<_9Yt<6X}X{PyF7UXIA$f)>NR5P&4G_Ygq(9TwwQH*P>Rq>3T4I+t2X(b5ogXBAfNf!xiF#Gilm zp2h{&D4k!SkKz-SBa%F-ZoVN$7GX2o=(>vkE^j)BDSGXw?^%RS9F)d_4}PN+6MlI8*Uk7a28CZ)Gp*EK)`n5i z){aq=0SFSO-;sw$nAvJU-$S-cW?RSc7kjEBvWDr1zxb1J7i;!i+3PQwb=)www?7TZ zE~~u)vO>#55eLZW;)F(f0KFf8@$p)~llV{nO7K_Nq-+S^h%QV_CnXLi)p*Pq&`s!d zK2msiR;Hk_rO8`kqe_jfTmmv|$MMo0ll}mI)PO4!ikVd(ZThhi&4ZwK?tD-}noj}v zBJ?jH-%VS|=t)HuTk?J1XaDUjd_5p1kPZi6y#F6$lLeRQbj4hsr=hX z4tXkX2d5DeLMcAYTeYm|u(XvG5JpW}hcOs4#s8g#ihK%@hVz|kL=nfiBqJ{*E*WhC zht3mi$P3a(O5JiDq$Syu9p^HY&9~<#H89D8 zJm84@%TaL_BZ+qy8+T3_pG7Q%z80hnjN;j>S=&WZWF48PDD%55lVuC0%#r5(+S;WH zS7!HEzmn~)Ih`gE`faPRjPe^t%g=F ztpGVW=Cj5ZkpghCf~`ar0+j@A=?3(j@7*pq?|9)n*B4EQTA1xj<+|(Y72?m7F%&&& zdO44owDBPT(8~RO=dT-K4#Ja@^4_0v$O3kn73p6$s?mCmVDUZ+Xl@QcpR6R3B$=am z%>`r9r2Z79Q#RNK?>~lwk^nQlR=Hr-ji$Ss3ltbmB)x@0{VzHL-rxVO(++@Yr@Iu2 zTEX)_9sVM>cX$|xuqz~Y8F-(n;KLAfi*63M7mh&gsPR>N0pd9h!0bm%nA?Lr zS#iEmG|wQd^BSDMk0k?G>S-uE$vtKEF8Dq}%vLD07zK4RLoS?%F1^oZZI$0W->7Z# z?v&|a`u#UD=_>i~`kzBGaPj!mYX5g?3RC4$5EV*j0sV)>H#+$G6!ci=6`)85LWR=FCp-NUff`;2zG9nU6F~ z;3ZyE*>*LvUgae+uMf}aV}V*?DCM>{o31+Sx~6+sz;TI(VmIpDrN3z+BUj`oGGgLP z>h9~MP}Pw#YwzfGP8wSkz`V#}--6}7S9yZvb{;SX?6PM_KuYpbi~*=teZr-ga2QqIz{QrEyZ@>eN*qmy;N@FCBbRNEeeoTmQyrX;+ zCkaJ&vOIbc^2BD6_H+Mrcl?Nt7O{xz9R_L0ZPV_u!sz+TKbXmhK)0QWoe-_HwtKJ@@7=L+ z+K8hhf=4vbdg3GqGN<;v-SMIzvX=Z`WUa_91Yf89^#`G(f-Eq>odB^p-Eqx}ENk#&MxJ+%~Ad2-*`1LNT>2INPw?*V3&kE;tt?rQyBw? zI+xJD04GTz1$7~KMnfpkPRW>f%n|0YCML@ODe`10;^DXX-|Hb*IE%_Vi#Pn9@#ufA z_8NY*1U%VseqYrSm?%>F@`laz+f?+2cIE4Jg6 z_VTcx|DSEA`g!R%RS$2dSRM|9VQClsW-G<~=j5T`pTbu-x6O`R z98b;}`rPM(2={YiytrqX+uh65f?%XiPp`;4CcMT*E*dQJ+if9^D>c_Dk8A(cE<#r=&!& z_`Z01=&MEE+2@yr!|#El=yM}v>i=?w^2E_FLPy(*4A9XmCNy>cBWdx3U>1RylsItO z4V8T$z3W-qqq*H`@}lYpfh=>C!tieKhoMGUi)EpWDr;yIL&fy};Y&l|)f^QE*k~4C zH>y`Iu%#S)z)YUqWO%el*Z)ME#p{1_8-^~6UF;kBTW zMQ!eXQuzkR#}j{qb(y9^Y!X7&T}}-4$%4w@w=;w+>Z%uifR9OoQ>P?0d9xpcwa>7kTv2U zT-F?3`Q`7xOR!gS@j>7In>_h){j#@@(ynYh;nB~}+N6qO(JO1xA z@59Pxc#&I~I64slNR?#hB-4XE>EFU@lUB*D)tu%uEa))B#eJ@ZOX0hIulfnDQz-y8 z`CX@(O%_VC{Ogh&ot``jlDL%R!f>-8yq~oLGxBO?+tQb5%k@a9zTs!+=NOwSVH-cR zqFo^jHeXDA_!rx$NzdP;>{-j5w3QUrR<;}=u2|FBJ;D#v{SK@Z6mjeV7_kFmWt95$ zeGaF{IU?U>?W`jzrG_9=9}yN*LKyzz))PLE+)_jc#4Rd$yFGol;NIk(qO1$5VXR)+ zxF7%f4=Q!NzR>DVXUB&nUT&>Nyf+5QRF+Z`X-bB*7=`|Go5D1&h~ zflKLw??kpiRm0h3|1GvySC2^#kcFz^5{79KKlq@`(leBa=_4CgV9sSHr{RIJ^KwR_ zY??M}-x^=MD+9`v@I3jue=OCn0kxno#6i>b(XKk_XTp_LpI}X*UA<#* zsgvq@yKTe_dTh>q1aeae@8yur08S(Q^8kXkP_ty48V$pX#y9)FQa~E7P7}GP_CbCm zc2dQxTeW(-~Y6}im24*XOC8ySfH*HMEnW3 z4CXp8iK(Nk<^D$g0kUW`8PXn2kdcDk-H@P0?G8?|YVlIFb?a>QunCx%B9TzsqQQ~HD!UO7zq^V!v9jho_FUob&Hxi ztU1nNOK)a!gkb-K4V^QVX05*>-^i|{b`hhvQLyj`E1vAnj0fbqqO%r z6Q;X1x0dL~GqMv%8QindZ4CZ%7pYQW~ z9)I*#Gjref-q(4Z*E#1c&rE0-_(4;_M(V7rgH_7H;ps1s%GBmU z{4a|X##j#XUF2n({v?ZUUAP5k>+)^F)7n-npbV3jAlY8V3*W=fwroDS$c&r$>8aH` zH+irV{RG3^F3oW2&E%5hXgMH9>$WlqX76Cm+iFmFC-DToTa`AcuN9S!SB+BT-IA#3P)JW1m~Cuwjs`Ep(wDXE4oYmt*aU z!Naz^lM}B)JFp7ejro7MU9#cI>wUoi{lylR2~s)3M!6a=_W~ITXCPd@U9W)qA5(mdOf zd3PntGPJyRX<9cgX?(9~TZB5FdEHW~gkJXY51}?s4ZT_VEdwOwD{T2E-B>oC8|_ZwsPNj=-q(-kwy%xX2K0~H z{*+W`-)V`7@c#Iuaef=?RR2O&x>W0A^xSwh5MsjTz(DVG-EoD@asu<>72A_h<39_# zawWVU<9t{r*e^u-5Q#SUI6dV#p$NYEGyiowT>>d*or=Ps!H$-3={bB|An$GPkP5F1 zTnu=ktmF|6E*>ZQvk^~DX(k!N`tiLut*?3FZhs$NUEa4ccDw66-~P;x+0b|<!ZN7Z%A`>2tN#CdoG>((QR~IV_Gj^Yh%!HdA~4C3jOXaqb6Ou z21T~Wmi9F6(_K0@KR@JDTh3-4mv2=T7&ML<+$4;b9SAtv*Uu`0>;VVZHB{4?aIl3J zL(rMfk?1V@l)fy{J5DhVlj&cWKJCcrpOAad(7mC6#%|Sn$VwMjtx6RDx1zbQ|Ngg8N&B56DGhu;dYg$Z{=YmCNn+?ceDclp65c_RnKs4*vefnhudSlrCy6-96vSB4_sFAj# zftzECwmNEOtED^NUt{ZDjT7^g>k1w<=af>+0)%NA;IPq6qx&ya7+QAu=pk8t>KTm` zEBj9J*2t|-(h)xc>Us*jHs)w9qmA>8@u21UqzKk*Ei#0kCeW6o z-2Q+Tvt25IUkb}-_LgD1_FUJ!U8@8OC^9(~Kd*0#zr*8IQkD)6Keb(XFai5*DYf~` z@U?-{)9X&BTf!^&@^rjmvea#9OE~m(D>qfM?CFT9Q4RxqhO0sA7S)=--^*Q=kNh7Y zq%2mu_d_#23d`+v`Ol263CZ<;D%D8Njj6L4T`S*^{!lPL@pXSm>2;~Da- zBX97TS{}exvSva@J5FJVCM$j4WDQuME`vTw>PWS0!;J7R+Kq zVUy6%#n5f7EV(}J#FhDpts;>=d6ow!yhJj8j>MJ@Wr_?x30buuutIG97L1A*QFT$c ziC5rBS;#qj=~yP-yWm-p(?llTwDuhS^f&<(9vA9@UhMH2-Fe_YAG$NvK6X{!mvPK~ zuEA&PA}meylmaIbbJXDOzuIn8cJNCV{tUA<$Vb?57JyAM`*GpEfMmFq>)6$E(9e1@W`l|R%-&}38#bl~levA#fx2wiBk^)mPj?<=S&|gv zQO)4*91$n08@W%2b|QxEiO0KxABAZC{^4BX^6r>Jm?{!`ZId9jjz<%pl(G5l));*`UU3KfnuXSDj2aP>{ zRIB$9pm7lj3*Xg)c1eG!cb+XGt&#?7yJ@C)(Ik)^OZ5><4u$VLCqZ#q2NMCt5 z6$|VN(RWM;5!JV?-h<JkEZ(SZF zC(6J+>A6Am9H7OlOFq6S62-2&z^Np=#xXsOq0WUKr zY_+Ob|CQd1*!Hirj5rn*=_bM5_zKmq6lG zn*&_=x%?ATxZ8ZTzd%biKY_qyNC#ZQ1vX+vc48N>aJXEjs{Y*3Op`Q7-oz8jyAh>d zNt_qvn`>q9aO~7xm{z`ree%lJ3YHCyC`q`-jUVCn*&NIml!uuMNm|~u3#AV?6kC+B z?qrT?xu2^mobSlzb&m(8jttB^je0mx;TT8}`_w(F11IKz83NLj@OmYDpCU^u?fD{) z&=$ptwVw#uohPb2_PrFX;X^I=MVXPDpqTuYhRa>f-=wy$y3)40-;#EUDYB1~V9t%$ z^^<7Zbs0{eB93Pcy)96%XsAi2^k`Gmnypd-&x4v9rAq<>a(pG|J#+Q>E$FvMLmy7T z5_06W=*ASUyPRfgCeiPIe{b47Hjqpb`9Xyl@$6*ntH@SV^bgH&Fk3L9L=6VQb)Uqa z33u#>ecDo&bK(h1WqSH)b_Th#Tvk&%$NXC@_pg5f-Ma#7q;&0QgtsFO~`V&{1b zbSP*X)jgLtd@9XdZ#2_BX4{X~pS8okF7c1xUhEV9>PZco>W-qz7YMD`+kCGULdK|^ zE7VwQ-at{%&fv`a+b&h`TjzxsyQX05UB~a0cuU-}{*%jR48J+yGWyl3Kdz5}U>;lE zgkba*yI5>xqIPz*Y!-P$#_mhHB!0Fpnv{$k-$xxjLAc`XdmHd1k$V@2QlblfJPrly z*~-4HVCq+?9vha>&I6aRGyq2VUon^L1a)g`-Xm*@bl2|hi2b|UmVYW|b+Gy?!aS-p z86a}Jep6Mf>>}n^*Oca@Xz}kxh)Y&pX$^CFAmi#$YVf57X^}uQD!IQSN&int=D> zJ>_|au3Be?hmPKK)1^JQ(O29eTf`>-x^jF2xYK6j_9d_qFkWHIan5=7EmDvZoQWz5 zZGb<{szHc9Nf@om)K_<=FuLR<&?5RKo3LONFQZ@?dyjemAe4$yDrnD zglU#XYo6|~L+YpF#?deK6S{8A*Ou;9G`cdC4S0U74EW18bc5~4>)<*}?Z!1Y)j;Ot zosEP!pc$O^wud(={WG%hY07IE^SwS-fGbvpP?;l8>H$;}urY2JF$u#$q}E*ZG%fR# z`p{xslcvG)kBS~B*^z6zVT@e}imYcz_8PRzM4GS52#ms5Jg9z~ME+uke`(Tq1w3_6 zxUa{HerS7!Wq&y(<9yyN@P^PrQT+6ij_qW3^Q)I53iIFCJE?MVyGLID!f?QHUi1tq z0)RNIMGO$2>S%3MlBc09l!6_(ECxXTU>$KjWdZX^3R~@3!SB zah5Za2$63;#y!Y}(wg1#shMePQTzfQfXyJ-Tf`R05KYcyvo8UW9-IWGWnzxR6Vj8_la;*-z5vWuwUe7@sKr#Tr51d z2PWn5h@|?QU3>k=s{pZ9+(}oye zc*95N_iLmtmu}H-t$smi49Y&ovX}@mKYt2*?C-i3Lh4*#q5YDg1Mh`j9ovRDf9&& zp_UMQh`|pC!|=}1uWoMK5RAjdTg3pXPCsYmRkWW}^m&)u-*c_st~gcss(`haA)xVw zAf=;s>$`Gq_`A}^MjY_BnCjktBNHY1*gzh(i0BFZ{Vg^F?Pbf`8_clvdZ)5(J4EWzAP}Ba5zX=S(2{gDugTQ3`%!q`h7kYSnwC`zEWeuFlODKiityMaM9u{Z%E@@y1jmZA#ⅅ8MglG&ER{i5lN315cO?EdHNLrg? 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 z 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 Pe7HEdAEg|=c=LY&YVNkY diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index 13b35eba55c6dabc3aac36f33d859266c18fa0d0..9987503582cb9ca958259ed581224af17b9ced78 100644 GIT binary patch literal 4698 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 iHw5(R?f*GE476 literal 5680 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 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png index 0a3f5fa40fb3d1e0710331a48de5d256da3f275d..7d6531e398abfef5338bbc839b4226dc41667885 100644 GIT binary patch delta 553 zcmV+^0@nSA1i=K5BYy%2NklkGorKMFQDk{34paEaLd=cEbb!*MRg9mdI6ckv28W}%-{%im= zY_FJ@*hV0~n1_ew9)93=(_#^ndAp6&02LY;0_dKrZ8} zSFZwIzkcnZq@>gb6mMr`W&Hv+;M}=$`o+b?3pqJC^<-sb8DWP0`0<1B(4j;Bfwuma zl$2xuh65uo);NF$d5VjRZxj*|It4bMudlBNXuCd;`Cm>>?w^H)1*3p~03$RI8PA?Q z%OET){9jK`?|(f|u3TPTel9Ff!3G!@7@S|abZH#OnU5YlVtn%C$$uRko&QEgMhqb5 z1HJcu|Ni|9{r&yCv9YlRt*xzszyN&@83VhOP4M&+`fGq z?EE`-?l64(_z~nHmf5psXRTVbDq`izm7(tL?)$(7uz$0&|6aCiS$t}0>g@dd{7IKD zUp7Q`J~EJzk$KqF)m7r==C%(b8XX-Sj{sd_0<u8N9^ zE?_i%$C(aTSXlmLW@gR~4-a46*w|P*efsq5z`($@ot>Q(z;yALU_yccU=)3rIB{Yz r(2xdTj3Ru-rH)`;z^9og0|)^C8*SEWc{23800000NkvXXu0mjfRigHb>FZqno^zN^3(+@_@XjP1uC>hJC?a{y* zD{|!jx7m$}htAgXd~cj3+ZrK}6l!2{cx$4>2i}b0%U|nx*4NknNi1N>>I*rxRx*XF zjWIp$e|p7N*%gv6a^xe`+J2V*GqU;lt>1BWf2ShLW$77g5go>ce}0@lm7sd+gu(Y? z@okUe{~JYoFgC6@om9@LBk=#Q%~7_H=W1tX8-^I diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index bdb57226d5f2bd20f11934f4903f16459cf52379..e81fc06dcae8252b50dc2c07cddcda4a6cd02199 100644 GIT binary patch literal 8830 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 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png index 2f1632cfddf3d9dade342351e627a0a75609fb46..1f195abc4a416bc8a9cd1ea3ed40c68922ef3ee5 100644 GIT binary patch delta 2272 zcmV<62p{*V5$h3Mlci&eQX5Vc0oplHBAJy1OG;PT?|0FXL>r%#{Sl$DjaK7anapRuuVg_V_6N|!EOiree{k^%7W;X})d7cZ`< ztE*drc|_U#{ne{i!vMnmp+kqR@6@T&?Y54i-2uQ!D~}vGvhvE6D}f_Mj4)$a_T44& z%F0TQs;a6l`hWH77d~*{zz8EFqvvfEPrCuo)YQc0I_Vm&YX}B*a!!R5-u7sX{?IckV3H<=XoC zdb`5H!UMN%-SQqbY?yEN?%ngnjIB)pKpNX7CMJd!6n_+W;?Fl5mdRu+-_xwEt^FuB zH#g75#^w+3gUZCjq*9C++XMilxGCz~|HO$C0Z4t*cmI!5C2F<$6%agK%gf8ly}%J) z_V3?+qrJU-46>Am6Vih20ttY zKlt0)+JB}9fM$E~;)VT%3m1~X568d{e%-ot`-iU& zy#cs=`}UwihYoEiE-wBIf9iY;xQ;=KBLd2xg;iHqPd$D5bOAa=9QYxqLx&D^x?U?7 z0Nm6(DJd!F?Afza$aLU)Jx-6kdGjV2Fkpbt5P#k^#hp8M{LpE>8Z>B-%FfR24}h!n zi7#&e8X6jmva+(g@mUWtGZz-?Yl9eKEG#Stq_1cV9`V^gVeUd%ETwJJ($ey@ruDo4 zK)}xX_wWA=^*c(xFkc(UjLpl-Bjd-9Cy>3OsvMB86MX0N=+PqqK&*!UJ6!8@0^srE z$A8@qA3nVC+_`g$nYa467)DFs)TvWs#W&(9}g#*9(JDJ%AIVM1iV<^;hK2L}g6 zsZ^8{n%L>-+TS6Ndu|L8jJdTg(YSe0=-@Y`(9i3m-gqAWut6BaozxV}Hkv zWiZ@`swx{B8!5<4X=y0|i4iL+E3F_vSREZce7HBd%2i$O!x=PG-B=y3XECxW5TqI; z)_{*3v%9Dy2{xylfY;h+z|khJIJ>xIRQX>;&qyI1^_q6paz@34-FVn z6k_uON`f*vEeTp041lJ$c#6L_>wojmgma_N)D=RU;k4wK0Od&C#&P4u$&j|9W&;!_ z%{T^%k08byt5&W01Zl6=V>3ntTPM@L6B$cdH9<$r>KsH>|Z zXU?1;N*SAMQtyXH7^=FF4RrcFB-9UUErL8z3kUrqqfhpXqznUjDi?;D{3HydSh zkQfVoP*cf^7R9S9Ad(11UQ$?C$WpH1Si)j1af8yE?c?JU78De;1szG}ha|0%U2t&l zhSb#5FEQ}6c%mc3YHDg^nSYs?449e%!J>9GW&`S-l$4YZOq=YpXV0{P2B4LZk&z)# ztzU22w8?+r!i6cwIIVHD3II(fI9d*(`JLf0=W8<%nC#xYd$gsgQ5r0ltcDOHbUr9A zFXv67@NMtu>6yHJ`}X7D2S0#aq-njzcDHin%H1Fx8z39XhzJ6m0)LB&idfVzadL7} zqldFp?P1;^m-_m=kn#tqmCax zK9>=(EW|crW8+$s@WwT3*2HM)3cLpxN{+{l9s43FDQODIA{xDZgnprlZt8jS=EZ}z z*7fb%SF55GJi*PKJNNJD)2BPe#>Rdd8X6k>eau1BNEoGUAuu24jA4@AD==DQu{sx(Dy4=tk{Xku+@hjTqep459Rnc zK0e;Z+uQqB1Q7+vI!z3}+6=9;0i5&`xami0YwKzuK16+p;q2^u34_Y?y?gi0Mn*(J zlnfNp|Jyck;(x@cBcM;1sq;xTDYwqsu zoDVtqTATemZfa^;9}*I>)yvCkkFT$91jb``Mvu0MwpJ4u7#M<2EPOYJ6=$2jAc0m? znVg*Lk)EEu6MZ=b@>i!HPv5d8H#fIkTeogq54Bh&c7J^B_KM7`S+lZTTwI*cro50D zp|!QOmfEfvHEL8g>fCqIq)B=`pwVRQ`jQkTKefNV|4s}j2SJiSd-m*E#?>~>%*-kw zy91UiS+ZA`kyam*mo8lzy>8vQNDB)Koqyui z$0U7G5?NE`HE_cMNb9J?#6(vRTomPu_KZRDH$|yUojUa#{YY`|{{;Y2ngIZ*1CZJb u07xBx)Mfxc>HwrR0{~J7Aho^s0Q?IA`oSh?#AKEL0000Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031 z000^Q000001E2u_0{{R30RRC20H6W@1ONa40RR91K%fHv1ONa40RR91KmY&$07g+l zumAuE6iGxuRCodHTWf3-RTMruyW6FuQYeUM04eX6D5c0FCV&1TCZ-py|c5InY-=I zY-!`3OG*I1PedcfpaTWG zz}$w!e2{QT6j)uA1OU8-N{6BItSS$HvMSg(7bJx2Y=32dDp`!10~I{udIVa+2|G#V z0cEH-*RHY~<>3g?j?-cK^;&$8cpYTHEnP(3ixu>PseUTRQ<~jf%ed6Q17;aHDPh|Z z+@II^^V0LKW}5)w|dwIw_gRf zFMqt(ako~@r$m5lC959fGLHG5;r3$WrNJgK`drR2zZ`Bq_rA1%mrYB^t3n{*!QNze z^;M{I8oD7Lp^7cb+fR6L@YvzuR5#}? z#=HP7u8s)cnE$Rj=B?ab0O!v1*&ZX$r#f@YbLjj8?`i3ZwP3VkB!sEhD8YS}7Jq1z z7cjRFzn@CV5dp`pMDQjjHsOiR&7egYgXit7?Dn_dG+#7?=|p>M-Y_s5iTElq)ThyF z=cei9Q{?i9h3Uw-PD>dez5ZKhet=tPFB-(!?{0iIuf_XT*iMSn7ti=0Uo<^*%h2LXNy!0+zfA`9?*&!@XBwdb_G06#>FlRej|>cKdhBgR~P{WYHL3&1oj#B1njWD1HN+;vYVgcBpQu z2vF7Q(LHwT=3uM~8Mrym+v!t>D=Dj$KltcdNh<*XtPa~3X!OJ|%zuy&0a{%3GGwkD zKTeG`b+lyj0jjS1OMkYnepCdoosNY`*zmBIo*981BU%%U@~$z0V`OVtIbEx5pa|Tc zt|Lg#ZQf5OYMUMRD>Wdxm5SAqV2}3!ceE-Mvs!lAvqf?6tS zD1t*y5KBjx{~&;KB9p@;yjZ%A&Yr*OuvepcN(6Kn)m=*PK4I%T9~HOM)8+a`>dXyL z$mdN63+{@ot!nS0XE*Jkx~7Y6^lpnqH3zi2(X-qJAD}ioJ%5efer&7`l)>_->tVrZ zJHf7}ex3-E;6h6{S$!4H2gWGN~F(zYfI&I!<4C6Cj}86!!HVKso`!wlU}od~3= zLBi5c_EG(5M{~kuOY|sI5x`$yrcH9Pv#9jVMYMQQK1QD>Kqz`+<=I!K0Y6;MBrGf4 zOJ~kqN!6ZuyMKzdrww#G29;c2k7Pss?YK=Je|dmP%VM#v1II%QoLSKG-Ph@epI<&I zrZEo;mzznJpNvmr8m%6(C4e7>5#_iPSydcBWwii5)6QO12ymUPb`=Luxe`M%4`70h zLeu)GTpG!&M%#1X0kLzqMMp{xKt-O9mO@)C>h|{{UVp}ysK7G-B?0^Z8sOF7N$5Z# zfx$lo+fU-El%xc3Z8UTkm-)~N&i8X+w_gaG54vtARs}C~IkXDe-{d3=S_Q>kv*)6m z1XazTqw%=E5Xv7^@^^T7Q2wxr+Z2kVYrerj@E`hDauQ;_COrTE002ovPDHLkV1j&W4&nd+ diff --git a/pubspec.lock b/pubspec.lock index 1ad96c7a7..e260cb994 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -226,10 +226,10 @@ packages: dependency: transitive description: name: cli_util - sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c" + sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 url: "https://pub.dev" source: hosted - version: "0.3.5" + version: "0.4.0" clock: dependency: transitive description: @@ -584,10 +584,10 @@ packages: dependency: "direct dev" description: name: flutter_launcher_icons - sha256: ce0e501cfc258907842238e4ca605e74b7fd1cdf04b3b43e86c43f3e40a1592c + sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea" url: "https://pub.dev" source: hosted - version: "0.11.0" + version: "0.13.1" flutter_libepiccash: dependency: "direct main" description: @@ -646,10 +646,10 @@ packages: dependency: "direct main" description: name: flutter_native_splash - sha256: "6777a3abb974021a39b5fdd2d46a03ca390e03903b6351f21d10e7ecc969f12d" + sha256: ba45d8cfbd778478a74696b012f33ffb6b1760c9bc531b21e2964444a4870dae url: "https://pub.dev" source: hosted - version: "2.2.16" + version: "2.3.1" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -853,10 +853,10 @@ packages: dependency: transitive description: name: image - sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6" + sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "4.0.17" import_sorter: dependency: "direct dev" description: @@ -1575,10 +1575,10 @@ packages: dependency: transitive description: name: universal_io - sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d" + sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.2" url_launcher: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index fd5eac1dc..4177d9787 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -145,7 +145,7 @@ dev_dependencies: integration_test: sdk: flutter build_runner: ^2.1.7 - flutter_launcher_icons: ^0.11.0 + flutter_launcher_icons: ^0.13.1 hive_generator: ^2.0.0 dependency_validator: ^3.1.2 hive_test: ^1.0.1 @@ -157,7 +157,7 @@ dev_dependencies: flutter_lints: ^2.0.1 isar_generator: 3.0.5 -flutter_icons: +flutter_launcher_icons: android: true ios: true image_path: assets/icon/icon.png @@ -170,7 +170,7 @@ flutter_icons: icon_size: 48 # min:48, max:256, default: 48 macos: generate: true - image_path: assets/icon/icon.png + image_path: assets/icon/macos-icon.png flutter_native_splash: image: assets/images/splash.png From 02ec7c3424bec5271d30735d5b5dd67f50994561 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Wed, 19 Jul 2023 14:45:20 -0600 Subject: [PATCH 26/80] temp ignore x86_64 on macos --- crypto_plugins/flutter_libepiccash | 2 +- crypto_plugins/flutter_liblelantus | 2 +- crypto_plugins/flutter_libmonero | 2 +- macos/Runner.xcodeproj/project.pbxproj | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index 686559344..f677dec0b 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit 686559344a58f77732c3d0134fbf44d271a55229 +Subproject commit f677dec0b34d3f9fe8fce2bc8ff5c508c3f3bb9a diff --git a/crypto_plugins/flutter_liblelantus b/crypto_plugins/flutter_liblelantus index cdccef0e8..9cd241b5e 160000 --- a/crypto_plugins/flutter_liblelantus +++ b/crypto_plugins/flutter_liblelantus @@ -1 +1 @@ -Subproject commit cdccef0e8dc10b7fe703b5bb9b41b59b25177e83 +Subproject commit 9cd241b5ea142e21c01dd7639b42603281c43287 diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index c920c09df..407425c9f 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit c920c09df5e415bba4bbe95dd50e1f0085f040e6 +Subproject commit 407425c9fcf7a30c81f1345246c7225bc18b5cd5 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 9b99a3480..c2c2e62ad 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -564,6 +564,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; + ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; STRIP_INSTALLED_PRODUCT = NO; SWIFT_COMPILATION_MODE = wholemodule; @@ -716,6 +717,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; + ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; STRIP_INSTALLED_PRODUCT = NO; SWIFT_COMPILATION_MODE = wholemodule; From 308f98259371d3a7c5689065c181a5dfb25bd283 Mon Sep 17 00:00:00 2001 From: ryleedavis Date: Thu, 20 Jul 2023 14:25:58 -0600 Subject: [PATCH 27/80] added chan card favorites to stack_theme --- lib/models/isar/stack_theme.g.dart | 32 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/models/isar/stack_theme.g.dart b/lib/models/isar/stack_theme.g.dart index e1bb0a549..5810282d0 100644 --- a/lib/models/isar/stack_theme.g.dart +++ b/lib/models/isar/stack_theme.g.dart @@ -29626,7 +29626,7 @@ int _themeAssetsV3EstimateSize( } } { - final value = object.dummy1; + final value = object.coinCardFavoritesImagesString; if (value != null) { bytesCount += 3 + value.length * 3; } @@ -29677,7 +29677,7 @@ void _themeAssetsV3Serialize( writer.writeString(offsets[7], object.coinSecondaryImagesString); writer.writeString(offsets[8], object.exchange); writer.writeString(offsets[9], object.loadingGif); - writer.writeString(offsets[10], object.dummy1); + writer.writeString(offsets[10], object.coinCardFavoritesImagesString); writer.writeString(offsets[11], object.dummy2); writer.writeString(offsets[12], object.dummy3); writer.writeString(offsets[13], object.personaEasy); @@ -29714,7 +29714,7 @@ ThemeAssetsV3 _themeAssetsV3Deserialize( object.coinSecondaryImagesString = reader.readString(offsets[7]); object.exchange = reader.readString(offsets[8]); object.loadingGif = reader.readStringOrNull(offsets[9]); - object.dummy1 = reader.readStringOrNull(offsets[10]); + object.coinCardFavoritesImagesString = reader.readStringOrNull(offsets[10]); object.dummy2 = reader.readStringOrNull(offsets[11]); object.dummy3 = reader.readStringOrNull(offsets[12]); object.personaEasy = reader.readString(offsets[13]); @@ -31220,7 +31220,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1IsNull() { + coinCardFavoritesImagesStringIsNull() { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(const FilterCondition.isNull( property: r'otherStringParam1', @@ -31229,7 +31229,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1IsNotNull() { + coinCardFavoritesImagesStringIsNotNull() { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(const FilterCondition.isNotNull( property: r'otherStringParam1', @@ -31238,7 +31238,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1EqualTo( + coinCardFavoritesImagesStringEqualTo( String? value, { bool caseSensitive = true, }) { @@ -31252,7 +31252,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1GreaterThan( + coinCardFavoritesImagesStringGreaterThan( String? value, { bool include = false, bool caseSensitive = true, @@ -31268,7 +31268,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1LessThan( + coinCardFavoritesImagesStringLessThan( String? value, { bool include = false, bool caseSensitive = true, @@ -31284,7 +31284,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1Between( + coinCardFavoritesImagesStringBetween( String? lower, String? upper, { bool includeLower = true, @@ -31304,7 +31304,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1StartsWith( + coinCardFavoritesImagesStringStartsWith( String value, { bool caseSensitive = true, }) { @@ -31318,7 +31318,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1EndsWith( + coinCardFavoritesImagesStringEndsWith( String value, { bool caseSensitive = true, }) { @@ -31332,7 +31332,8 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1Contains(String value, {bool caseSensitive = true}) { + coinCardFavoritesImagesStringContains(String value, + {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.contains( property: r'otherStringParam1', @@ -31343,7 +31344,8 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1Matches(String pattern, {bool caseSensitive = true}) { + coinCardFavoritesImagesStringMatches(String pattern, + {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.matches( property: r'otherStringParam1', @@ -31354,7 +31356,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1IsEmpty() { + coinCardFavoritesImagesStringIsEmpty() { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.equalTo( property: r'otherStringParam1', @@ -31364,7 +31366,7 @@ extension ThemeAssetsV3QueryFilter } QueryBuilder - dummy1IsNotEmpty() { + coinCardFavoritesImagesStringIsNotEmpty() { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.greaterThan( property: r'otherStringParam1', From 96bfafcd19d127d7fb11ef1b2330252b8abf80ce Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 20 Jul 2023 09:11:36 -0600 Subject: [PATCH 28/80] fix: contract decimal places bug for eth token amounts parsing --- lib/utilities/amount/amount_formatter.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/utilities/amount/amount_formatter.dart b/lib/utilities/amount/amount_formatter.dart index 6743bcd53..1ae577507 100644 --- a/lib/utilities/amount/amount_formatter.dart +++ b/lib/utilities/amount/amount_formatter.dart @@ -70,6 +70,11 @@ class AmountFormatter { String string, { EthContract? ethContract, }) { - return unit.tryParse(string, locale: locale, coin: coin); + return unit.tryParse( + string, + locale: locale, + coin: coin, + tokenContract: ethContract, + ); } } From 461267ec95fc2abcd4b682cc5c93e46791a65698 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 20 Jul 2023 11:34:31 -0600 Subject: [PATCH 29/80] eth api error handling clean up and token flag --- .../coins/ethereum/ethereum_wallet.dart | 5 ++- lib/services/ethereum/ethereum_api.dart | 33 +++++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/lib/services/coins/ethereum/ethereum_wallet.dart b/lib/services/coins/ethereum/ethereum_wallet.dart index 9990406d9..62f3020e0 100644 --- a/lib/services/coins/ethereum/ethereum_wallet.dart +++ b/lib/services/coins/ethereum/ethereum_wallet.dart @@ -1023,6 +1023,7 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { final response = await EthereumAPI.getEthTransactions( address: thisAddress, firstBlock: isRescan ? 0 : firstBlock, + includeTokens: true, ); if (response.value == null) { @@ -1057,8 +1058,10 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { txFailed = true; } isIncoming = false; - } else { + } else if (checksumEthereumAddress(element.to) == thisAddress) { isIncoming = true; + } else { + continue; } //Calculate fees (GasLimit * gasPrice) diff --git a/lib/services/ethereum/ethereum_api.dart b/lib/services/ethereum/ethereum_api.dart index d30b9ea27..663513bea 100644 --- a/lib/services/ethereum/ethereum_api.dart +++ b/lib/services/ethereum/ethereum_api.dart @@ -50,6 +50,7 @@ abstract class EthereumAPI { static Future>> getEthTransactions({ required String address, int firstBlock = 0, + bool includeTokens = false, }) async { try { final response = await get( @@ -67,7 +68,7 @@ abstract class EthereumAPI { for (final map in list!) { final txn = EthTxDTO.fromMap(Map.from(map as Map)); - if (txn.hasToken == 0) { + if (txn.hasToken == 0 || includeTokens) { txns.add(txn); } } @@ -76,9 +77,11 @@ abstract class EthereumAPI { null, ); } else { - throw EthApiException( - "getEthTransactions($address) response is empty but status code is " - "${response.statusCode}", + // nice that the api returns an empty body instead of being + // consistent and returning a json object with no transactions + return EthereumResponse( + [], + null, ); } } else { @@ -196,9 +199,11 @@ abstract class EthereumAPI { null, ); } else { - throw EthApiException( - "getEthTransactionNonces($txns) response is empty but status code is " - "${response.statusCode}", + // nice that the api returns an empty body instead of being + // consistent and returning a json object with no transactions + return EthereumResponse( + [], + null, ); } } else { @@ -252,13 +257,13 @@ abstract class EthereumAPI { ); } else { throw EthApiException( - "getEthTransaction($txids) response is empty but status code is " + "getEthTokenTransactionsByTxids($txids) response is empty but status code is " "${response.statusCode}", ); } } else { throw EthApiException( - "getEthTransaction($txids) failed with status code: " + "getEthTokenTransactionsByTxids($txids) failed with status code: " "${response.statusCode}", ); } @@ -269,7 +274,7 @@ abstract class EthereumAPI { ); } catch (e, s) { Logging.instance.log( - "getEthTransaction($txids): $e\n$s", + "getEthTokenTransactionsByTxids($txids): $e\n$s", level: LogLevel.Error, ); return EthereumResponse( @@ -307,9 +312,11 @@ abstract class EthereumAPI { null, ); } else { - throw EthApiException( - "getTokenTransactions($address, $tokenContractAddress) response is empty but status code is " - "${response.statusCode}", + // nice that the api returns an empty body instead of being + // consistent and returning a json object with no transactions + return EthereumResponse( + [], + null, ); } } else { From 87a146b5a4107dee4d742291ebf20ed3d7775a67 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 20 Jul 2023 11:35:52 -0600 Subject: [PATCH 30/80] show failed instead of cancelled for failed eth tx --- lib/widgets/transaction_card.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart index 7791ff3a0..41b81e2da 100644 --- a/lib/widgets/transaction_card.dart +++ b/lib/widgets/transaction_card.dart @@ -230,7 +230,9 @@ class _TransactionCardState extends ConsumerState { fit: BoxFit.scaleDown, child: Text( _transaction.isCancelled - ? "Cancelled" + ? coin == Coin.ethereum + ? "Failed" + : "Cancelled" : whatIsIt( _transaction.type, coin, From 49e5641c3e8fb17ae0d50318a142d6e3cb5e52c2 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 20 Jul 2023 11:36:16 -0600 Subject: [PATCH 31/80] optional nonce --- lib/dto/ethereum/eth_token_tx_extra_dto.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/dto/ethereum/eth_token_tx_extra_dto.dart b/lib/dto/ethereum/eth_token_tx_extra_dto.dart index 144194914..aab41bb76 100644 --- a/lib/dto/ethereum/eth_token_tx_extra_dto.dart +++ b/lib/dto/ethereum/eth_token_tx_extra_dto.dart @@ -46,7 +46,7 @@ class EthTokenTxExtraDTO { ), gas: _amountFromJsonNum(map['gas']), gasPrice: _amountFromJsonNum(map['gasPrice']), - nonce: map['nonce'] as int, + nonce: map['nonce'] as int?, input: map['input'] as String, gasCost: _amountFromJsonNum(map['gasCost']), gasUsed: _amountFromJsonNum(map['gasUsed']), @@ -63,7 +63,7 @@ class EthTokenTxExtraDTO { final Amount gas; final Amount gasPrice; final String input; - final int nonce; + final int? nonce; final Amount gasCost; final Amount gasUsed; From 69aa1fb8859475e76665de78affa944da92fdd5b Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 20 Jul 2023 11:36:30 -0600 Subject: [PATCH 32/80] toString fix --- lib/dto/ethereum/eth_tx_dto.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/dto/ethereum/eth_tx_dto.dart b/lib/dto/ethereum/eth_tx_dto.dart index 7289cda15..260675cf9 100644 --- a/lib/dto/ethereum/eth_tx_dto.dart +++ b/lib/dto/ethereum/eth_tx_dto.dart @@ -127,16 +127,16 @@ class EthTxDTO { map['timestamp'] = timestamp; map['from'] = from; map['to'] = to; - map['value'] = value; - map['gas'] = gas; - map['gasPrice'] = gasPrice; - map['maxFeePerGas'] = maxFeePerGas; - map['maxPriorityFeePerGas'] = maxPriorityFeePerGas; + map['value'] = value.toString(); + map['gas'] = gas.toString(); + map['gasPrice'] = gasPrice.toString(); + map['maxFeePerGas'] = maxFeePerGas.toString(); + map['maxPriorityFeePerGas'] = maxPriorityFeePerGas.toString(); map['isError'] = isError; map['hasToken'] = hasToken; map['compressedTx'] = compressedTx; - map['gasCost'] = gasCost; - map['gasUsed'] = gasUsed; + map['gasCost'] = gasCost.toString(); + map['gasUsed'] = gasUsed.toString(); return map; } From 8a84c898241c26ee43bbc11c4a0f4c1877dee56e Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 20 Jul 2023 15:08:43 -0600 Subject: [PATCH 33/80] show failed instead of cancelled for eth failed txns --- .../transaction_details_view.dart | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart index e8ccf98de..2b1ba62c4 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart @@ -358,7 +358,6 @@ class _TransactionDetailsViewState final currentHeight = ref.watch(walletsChangeNotifierProvider .select((value) => value.getManager(walletId).currentHeight)); - print("THIS TRANSACTION IS $_transaction"); return ConditionalParent( @@ -474,7 +473,9 @@ class _TransactionDetailsViewState ), SelectableText( _transaction.isCancelled - ? "Cancelled" + ? coin == Coin.ethereum + ? "Failed" + : "Cancelled" : whatIsIt( _transaction, currentHeight, @@ -585,7 +586,9 @@ class _TransactionDetailsViewState // child: SelectableText( _transaction.isCancelled - ? "Cancelled" + ? coin == Coin.ethereum + ? "Failed" + : "Cancelled" : whatIsIt( _transaction, currentHeight, @@ -781,8 +784,8 @@ class _TransactionDetailsViewState isDesktop ? const _Divider() : const SizedBox( - height: 12, - ), + height: 12, + ), if (coin == Coin.epicCash) RoundedWhiteContainer( padding: isDesktop @@ -790,22 +793,22 @@ class _TransactionDetailsViewState : const EdgeInsets.all(12), child: Row( mainAxisAlignment: - MainAxisAlignment.spaceBetween, + MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Column( crossAxisAlignment: - CrossAxisAlignment.start, + CrossAxisAlignment.start, children: [ Text( "On chain note", style: isDesktop ? STextStyles - .desktopTextExtraExtraSmall( - context) + .desktopTextExtraExtraSmall( + context) : STextStyles.itemSubtitle( - context), + context), ), const SizedBox( height: 8, @@ -814,18 +817,16 @@ class _TransactionDetailsViewState _transaction.otherData ?? "", style: isDesktop ? STextStyles - .desktopTextExtraExtraSmall( - context) - .copyWith( - color: Theme.of( - context) - .extension< - StackColors>()! - .textDark, - ) - : STextStyles - .itemSubtitle12( - context), + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension< + StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), ), ], ), @@ -854,7 +855,9 @@ class _TransactionDetailsViewState MainAxisAlignment.spaceBetween, children: [ Text( - (coin == Coin.epicCash) ? "Local Note" : "Note ", + (coin == Coin.epicCash) + ? "Local Note" + : "Note ", style: isDesktop ? STextStyles .desktopTextExtraExtraSmall( @@ -923,7 +926,9 @@ class _TransactionDetailsViewState notesServiceChangeNotifierProvider( walletId) .select((value) => value.getNoteFor( - txid: (coin == Coin.epicCash)? _transaction.slateId! : _transaction.txid ))), + txid: (coin == Coin.epicCash) + ? _transaction.slateId! + : _transaction.txid))), builder: (builderContext, AsyncSnapshot snapshot) { if (snapshot.connectionState == From 480f6376703a87098f95e4649876c98dd3235588 Mon Sep 17 00:00:00 2001 From: ryleedavis Date: Thu, 20 Jul 2023 15:15:03 -0600 Subject: [PATCH 34/80] WIP: added cardFavoriteImages + check if card should be favorites or wallet --- lib/models/isar/stack_theme.dart | 26 ++++++++++++++++--- .../sub_widgets/wallet_summary.dart | 1 + .../sub_widgets/favorite_card.dart | 1 + lib/themes/coin_card_provider.dart | 10 +++++++ lib/widgets/coin_card.dart | 7 ++++- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/models/isar/stack_theme.dart b/lib/models/isar/stack_theme.dart index b005c40ea..66a93ead4 100644 --- a/lib/models/isar/stack_theme.dart +++ b/lib/models/isar/stack_theme.dart @@ -2310,8 +2310,6 @@ class ThemeAssetsV3 implements IThemeAssets { // Added some future proof params in case we want to add anything else // This should provide some buffer in stead of creating assetsV4 etc - @Name("otherStringParam1") - late final String? dummy1; @Name("otherStringParam2") late final String? dummy2; @Name("otherStringParam3") @@ -2357,6 +2355,20 @@ class ThemeAssetsV3 implements IThemeAssets { Map? _coinCardImages; late final String? coinCardImagesString; + + @ignore + Map? get coinCardFavoritesImages => + _coinCardFavoritesImages ??= coinCardFavoritesImagesString == null + ? null + : parseCoinAssetsString( + coinCardFavoritesImagesString!, + placeHolder: coinPlaceholder, + ); + @ignore + Map? _coinCardFavoritesImages; + @Name("otherStringParam1") + late final String? coinCardFavoritesImagesString; + ThemeAssetsV3(); factory ThemeAssetsV3.fromJson({ @@ -2421,13 +2433,18 @@ class ThemeAssetsV3 implements IThemeAssets { Map.from(json["coins"]["cards"] as Map), ) : null + ..coinCardFavoritesImagesString = json["coins"]["favoriteCards"] is Map + ? createCoinAssetsString( + "$applicationThemesDirectoryPath/$themeId/assets", + Map.from(json["coins"]["favoriteCards"] as Map), + ) + : null ..loadingGif = json["loading_gif"] is String ? "$applicationThemesDirectoryPath/$themeId/assets/${json["loading_gif"] as String}" : null ..background = json["background"] is String ? "$applicationThemesDirectoryPath/$themeId/assets/${json["background"] as String}" : null - ..dummy1 = null ..dummy2 = null ..dummy3 = null; } @@ -2483,7 +2500,8 @@ class ThemeAssetsV3 implements IThemeAssets { 'coinIcons: $coinIcons, ' 'coinImages: $coinImages, ' 'coinSecondaryImages: $coinSecondaryImages, ' - 'coinCardImages: $coinCardImages' + 'coinCardWalletImages: $coinCardImages' + 'coinCardFavoritesImages: $coinCardFavoritesImages' ')'; } } diff --git a/lib/pages/wallet_view/sub_widgets/wallet_summary.dart b/lib/pages/wallet_view/sub_widgets/wallet_summary.dart index a82145817..08f5f22c8 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_summary.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_summary.dart @@ -52,6 +52,7 @@ class WalletSummary extends StatelessWidget { walletId: walletId, width: constraints.maxWidth, height: constraints.maxHeight, + isFavorite: false, ), Positioned.fill( child: Padding( diff --git a/lib/pages/wallets_view/sub_widgets/favorite_card.dart b/lib/pages/wallets_view/sub_widgets/favorite_card.dart index b3f5e97e5..fe8a6691d 100644 --- a/lib/pages/wallets_view/sub_widgets/favorite_card.dart +++ b/lib/pages/wallets_view/sub_widgets/favorite_card.dart @@ -149,6 +149,7 @@ class _FavoriteCardState extends ConsumerState { walletId: widget.walletId, width: widget.width, height: widget.height, + isFavorite: false, ), child: Padding( padding: const EdgeInsets.all(12.0), diff --git a/lib/themes/coin_card_provider.dart b/lib/themes/coin_card_provider.dart index fc84faebd..ea0dbc7fb 100644 --- a/lib/themes/coin_card_provider.dart +++ b/lib/themes/coin_card_provider.dart @@ -22,3 +22,13 @@ final coinCardProvider = Provider.family((ref, coin) { return null; } }); + +final coinCardFavoritesProvider = Provider.family((ref, coin) { + final assets = ref.watch(themeAssetsProvider); + + if (assets is ThemeAssetsV3) { + return assets.coinCardFavoritesImages?[coin.mainNetVersion]; + } else { + return null; + } +}); diff --git a/lib/widgets/coin_card.dart b/lib/widgets/coin_card.dart index 0bebc5fd8..4ce95b530 100644 --- a/lib/widgets/coin_card.dart +++ b/lib/widgets/coin_card.dart @@ -25,11 +25,13 @@ class CoinCard extends ConsumerWidget { required this.walletId, required this.width, required this.height, + required this.isFavorite, }); final String walletId; final double width; final double height; + final bool isFavorite; @override Widget build(BuildContext context, WidgetRef ref) { @@ -39,6 +41,7 @@ class CoinCard extends ConsumerWidget { ); final bool hasCardImageBg = ref.watch(coinCardProvider(coin)) != null; + final isFavorite = false; return Stack( children: [ @@ -54,7 +57,9 @@ class CoinCard extends ConsumerWidget { fit: BoxFit.cover, image: FileImage( File( - ref.watch(coinCardProvider(coin))!, + (isFavorite) + ? ref.watch(coinCardFavoritesProvider(coin))! + : ref.watch(coinCardProvider(coin))!, ), ), ), From 24d443886eab3b2a252875b3c1ad38c81ce8ca22 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 20 Jul 2023 16:04:01 -0600 Subject: [PATCH 35/80] hide empty tx note field on mobile confirm send screen --- .../send_view/confirm_transaction_view.dart | 81 ++++++++++--------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index 3193e7bb7..a1fc66f21 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -493,51 +493,54 @@ class _ConfirmTransactionViewState ], ), ), - if (coin == Coin.epicCash) + if (coin == Coin.epicCash && + (transactionInfo["onChainNote"] as String).isNotEmpty) const SizedBox( height: 12, ), - if (coin == Coin.epicCash) + if (coin == Coin.epicCash && + (transactionInfo["onChainNote"] as String).isNotEmpty) RoundedWhiteContainer( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text( - "On chain note", - style: STextStyles.smallMed12(context), - ), - const SizedBox( - height: 4, - ), - Text( - transactionInfo["onChainNote"] as String, - style: STextStyles.itemSubtitle12(context), - ), - ], + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + "On chain note", + style: STextStyles.smallMed12(context), + ), + const SizedBox( + height: 4, + ), + Text( + transactionInfo["onChainNote"] as String, + style: STextStyles.itemSubtitle12(context), + ), + ], + ), ), - ), - const SizedBox( - height: 12, - ), - RoundedWhiteContainer( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text( - (coin == Coin.epicCash) ? "Local Note" : - "Note", - style: STextStyles.smallMed12(context), - ), - const SizedBox( - height: 4, - ), - Text( - transactionInfo["note"] as String, - style: STextStyles.itemSubtitle12(context), - ), - ], + if ((transactionInfo["note"] as String).isNotEmpty) + const SizedBox( + height: 12, + ), + if ((transactionInfo["note"] as String).isNotEmpty) + RoundedWhiteContainer( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + (coin == Coin.epicCash) ? "Local Note" : "Note", + style: STextStyles.smallMed12(context), + ), + const SizedBox( + height: 4, + ), + Text( + transactionInfo["note"] as String, + style: STextStyles.itemSubtitle12(context), + ), + ], + ), ), - ), ], ), if (isDesktop) From 0ce86ce7fe166b23bdff16b28073206443297539 Mon Sep 17 00:00:00 2001 From: ryleedavis Date: Thu, 20 Jul 2023 16:51:37 -0600 Subject: [PATCH 36/80] Chan card images for favorites and wallet --- lib/pages/wallets_view/sub_widgets/favorite_card.dart | 2 +- lib/themes/coin_card_provider.dart | 3 ++- lib/widgets/coin_card.dart | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/pages/wallets_view/sub_widgets/favorite_card.dart b/lib/pages/wallets_view/sub_widgets/favorite_card.dart index fe8a6691d..107b323e0 100644 --- a/lib/pages/wallets_view/sub_widgets/favorite_card.dart +++ b/lib/pages/wallets_view/sub_widgets/favorite_card.dart @@ -149,7 +149,7 @@ class _FavoriteCardState extends ConsumerState { walletId: widget.walletId, width: widget.width, height: widget.height, - isFavorite: false, + isFavorite: true, ), child: Padding( padding: const EdgeInsets.all(12.0), diff --git a/lib/themes/coin_card_provider.dart b/lib/themes/coin_card_provider.dart index ea0dbc7fb..b34e9e6f1 100644 --- a/lib/themes/coin_card_provider.dart +++ b/lib/themes/coin_card_provider.dart @@ -27,7 +27,8 @@ final coinCardFavoritesProvider = Provider.family((ref, coin) { final assets = ref.watch(themeAssetsProvider); if (assets is ThemeAssetsV3) { - return assets.coinCardFavoritesImages?[coin.mainNetVersion]; + return assets.coinCardFavoritesImages?[coin.mainNetVersion] ?? + assets.coinCardImages?[coin.mainNetVersion]; } else { return null; } diff --git a/lib/widgets/coin_card.dart b/lib/widgets/coin_card.dart index 4ce95b530..ebc67bb4e 100644 --- a/lib/widgets/coin_card.dart +++ b/lib/widgets/coin_card.dart @@ -40,8 +40,7 @@ class CoinCard extends ConsumerWidget { .select((value) => value.getManager(walletId).coin), ); - final bool hasCardImageBg = ref.watch(coinCardProvider(coin)) != null; - final isFavorite = false; + final bool hasCardImageBg = (isFavorite) ? ref.watch(coinCardFavoritesProvider(coin)) != null : ref.watch(coinCardProvider(coin)) != null; return Stack( children: [ From 28f8fdc2331f2cf1f92876eb386d9c8136826d2b Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 20 Jul 2023 16:15:23 -0600 Subject: [PATCH 37/80] clean up --- lib/pages_desktop_specific/password/create_password_view.dart | 2 +- lib/pages_desktop_specific/password/desktop_login_view.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pages_desktop_specific/password/create_password_view.dart b/lib/pages_desktop_specific/password/create_password_view.dart index 68205d077..2986cd0da 100644 --- a/lib/pages_desktop_specific/password/create_password_view.dart +++ b/lib/pages_desktop_specific/password/create_password_view.dart @@ -125,7 +125,7 @@ class _CreatePasswordViewState extends ConsumerState { } } - if (!widget.restoreFromSWB) { + if (!widget.restoreFromSWB && mounted) { unawaited(showFloatingFlushBar( type: FlushBarType.success, message: "Your password is set up", diff --git a/lib/pages_desktop_specific/password/desktop_login_view.dart b/lib/pages_desktop_specific/password/desktop_login_view.dart index 10e1477b4..471da2763 100644 --- a/lib/pages_desktop_specific/password/desktop_login_view.dart +++ b/lib/pages_desktop_specific/password/desktop_login_view.dart @@ -84,10 +84,10 @@ class _DesktopLoginViewState extends ConsumerState { unawaited( showDialog( context: context, - builder: (context) => Column( + builder: (context) => const Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, - children: const [ + children: [ LoadingIndicator( width: 200, height: 200, From 269f47d6f4245ce95c09c500130245c10474b3ca Mon Sep 17 00:00:00 2001 From: ryleedavis Date: Fri, 21 Jul 2023 11:34:14 -0600 Subject: [PATCH 38/80] resolved merge conflict --- lib/models/isar/stack_theme.dart | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/models/isar/stack_theme.dart b/lib/models/isar/stack_theme.dart index c6d526d85..32878366a 100644 --- a/lib/models/isar/stack_theme.dart +++ b/lib/models/isar/stack_theme.dart @@ -2386,15 +2386,14 @@ class ThemeAssetsV3 implements IThemeAssets { Map? _coinCardImages; late final String? coinCardImagesString; - @ignore Map? get coinCardFavoritesImages => _coinCardFavoritesImages ??= coinCardFavoritesImagesString == null ? null : parseCoinAssetsString( - coinCardFavoritesImagesString!, - placeHolder: coinPlaceholder, - ); + coinCardFavoritesImagesString!, + placeHolder: coinPlaceholder, + ); @ignore Map? _coinCardFavoritesImages; @Name("otherStringParam1") @@ -2467,7 +2466,6 @@ class ThemeAssetsV3 implements IThemeAssets { ..backgroundRelative = json["background"] is String ? "$themeId/assets/${json["background"] as String}" : null - ..dummy1 = null ..dummy2 = null ..dummy3 = null; } From b8fcc98ac6ca64dda77f69a2e4765b9806275996 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 21 Jul 2023 13:23:36 -0600 Subject: [PATCH 39/80] eth token balance fix --- lib/services/ethereum/ethereum_api.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/services/ethereum/ethereum_api.dart b/lib/services/ethereum/ethereum_api.dart index 663513bea..5e95e3aa1 100644 --- a/lib/services/ethereum/ethereum_api.dart +++ b/lib/services/ethereum/ethereum_api.dart @@ -10,7 +10,6 @@ import 'dart:convert'; -import 'package:decimal/decimal.dart'; import 'package:http/http.dart'; import 'package:stackwallet/dto/ethereum/eth_token_tx_dto.dart'; import 'package:stackwallet/dto/ethereum/eth_token_tx_extra_dto.dart'; @@ -431,10 +430,10 @@ abstract class EthereumAPI { final map = json["data"].first as Map; final balance = - Decimal.tryParse(map["balance"].toString()) ?? Decimal.zero; + BigInt.tryParse(map["units"].toString()) ?? BigInt.zero; return EthereumResponse( - Amount.fromDecimal(balance, fractionDigits: map["decimals"] as int), + Amount(rawValue: balance, fractionDigits: map["decimals"] as int), null, ); } else { From e7b480e5852e72f8355ffe1a91ee56763b528ac2 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 21 Jul 2023 14:11:30 -0600 Subject: [PATCH 40/80] add ba/nano wallet representative change option to wallet settings, remove coin control from ba/nano, and some other clean up --- .../add_token_view/add_custom_token_view.dart | 4 +- .../install_theme_from_file_dialog.dart | 2 +- .../sub_widgets/stack_theme_card.dart | 4 +- .../wallet_settings_view.dart | 42 +- .../change_representative_view.dart | 367 ++++++++++++++++++ .../xpub_view.dart | 0 .../sub_widgets/my_token_select_item.dart | 2 +- .../sub_widgets/wallet_options_button.dart | 2 +- lib/route_generator.dart | 17 +- lib/services/coins/banano/banano_wallet.dart | 52 ++- lib/services/coins/nano/nano_wallet.dart | 52 ++- lib/services/nano_api.dart | 130 +++++++ lib/utilities/show_loading.dart | 20 +- lib/widgets/wallet_card.dart | 2 +- 14 files changed, 669 insertions(+), 27 deletions(-) create mode 100644 lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart rename lib/pages/settings_views/{global_settings_view => wallet_settings_view/wallet_settings_wallet_settings}/xpub_view.dart (100%) create mode 100644 lib/services/nano_api.dart diff --git a/lib/pages/add_wallet_views/add_token_view/add_custom_token_view.dart b/lib/pages/add_wallet_views/add_token_view/add_custom_token_view.dart index a3d297b8c..dd807976b 100644 --- a/lib/pages/add_wallet_views/add_token_view/add_custom_token_view.dart +++ b/lib/pages/add_wallet_views/add_token_view/add_custom_token_view.dart @@ -142,7 +142,7 @@ class _AddCustomTokenViewState extends ConsumerState { context: context, message: "Looking up contract", ); - currentToken = response.value; + currentToken = response!.value; if (currentToken != null) { nameController.text = currentToken!.name; symbolController.text = currentToken!.symbol; @@ -157,7 +157,7 @@ class _AddCustomTokenViewState extends ConsumerState { context: context, builder: (context) => StackOkDialog( title: "Failed to look up token", - message: response.exception?.message, + message: response!.exception?.message, ), ), ); diff --git a/lib/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/install_theme_from_file_dialog.dart b/lib/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/install_theme_from_file_dialog.dart index 235bb5e95..812fcc94b 100644 --- a/lib/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/install_theme_from_file_dialog.dart +++ b/lib/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/install_theme_from_file_dialog.dart @@ -164,7 +164,7 @@ class _InstallThemeFromFileDialogState ); if (mounted) { Navigator.of(context).pop(); - if (!result) { + if (!result!) { unawaited( showDialog( context: context, diff --git a/lib/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/stack_theme_card.dart b/lib/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/stack_theme_card.dart index 0c45a68f7..003063bde 100644 --- a/lib/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/stack_theme_card.dart +++ b/lib/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/stack_theme_card.dart @@ -72,11 +72,11 @@ class _StackThemeCardState extends ConsumerState { } Future _downloadPressed() async { - final result = await showLoading( + final result = (await showLoading( whileFuture: _downloadAndInstall(), context: context, message: "Downloading and installing theme...", - ); + ))!; if (mounted) { final message = result diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart index 59f443db9..fcacc60d4 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart @@ -20,11 +20,12 @@ import 'package:stackwallet/pages/home_view/home_view.dart'; import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_views/debug_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_preferences_view.dart'; -import 'package:stackwallet/pages/settings_views/global_settings_view/xpub_view.dart'; import 'package:stackwallet/pages/settings_views/sub_widgets/settings_list_button.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart'; +import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart'; +import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/transaction_filter_provider.dart'; import 'package:stackwallet/route_generator.dart'; @@ -231,7 +232,7 @@ class _WalletSettingsViewState extends ConsumerState { .mnemonic; if (mounted) { - Navigator.push( + await Navigator.push( context, RouteGenerator.getRoute( shouldUseMaterialRoute: @@ -305,6 +306,25 @@ class _WalletSettingsViewState extends ConsumerState { ); }, ), + if (coin == Coin.nano || coin == Coin.banano) + const SizedBox( + height: 8, + ), + if (coin == Coin.nano || coin == Coin.banano) + Consumer( + builder: (_, ref, __) { + return SettingsListButton( + iconAssetName: Assets.svg.eye, + title: "Change representative", + onPressed: () { + Navigator.of(context).pushNamed( + ChangeRepresentativeView.routeName, + arguments: widget.walletId, + ); + }, + ); + }, + ), const SizedBox( height: 8, ), @@ -434,18 +454,20 @@ class _EpiBoxInfoFormState extends ConsumerState { TextButton( onPressed: () async { try { - wallet.updateEpicboxConfig( + await wallet.updateEpicboxConfig( hostController.text, int.parse(portController.text), ); - showFloatingFlushBar( - context: context, - message: "Epicbox info saved!", - type: FlushBarType.success, - ); - wallet.refresh(); + if (mounted) { + await showFloatingFlushBar( + context: context, + message: "Epicbox info saved!", + type: FlushBarType.success, + ); + } + unawaited(wallet.refresh()); } catch (e) { - showFloatingFlushBar( + await showFloatingFlushBar( context: context, message: "Failed to save epicbox info: $e", type: FlushBarType.warning, diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart new file mode 100644 index 000000000..76bb833b1 --- /dev/null +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart @@ -0,0 +1,367 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-05-26 + * + */ + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/services/coins/banano/banano_wallet.dart'; +import 'package:stackwallet/services/coins/nano/nano_wallet.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/show_loading.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; +import 'package:stackwallet/widgets/loading_indicator.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:stackwallet/widgets/stack_text_field.dart'; +import 'package:stackwallet/widgets/textfield_icon_button.dart'; + +class ChangeRepresentativeView extends ConsumerStatefulWidget { + const ChangeRepresentativeView({ + Key? key, + required this.walletId, + this.clipboardInterface = const ClipboardWrapper(), + }) : super(key: key); + + final String walletId; + final ClipboardInterface clipboardInterface; + + static const String routeName = "/changeRepresentative"; + + @override + ConsumerState createState() => _XPubViewState(); +} + +class _XPubViewState extends ConsumerState { + final _textController = TextEditingController(); + final _textFocusNode = FocusNode(); + final bool isDesktop = Util.isDesktop; + + late ClipboardInterface _clipboardInterface; + + String? representative; + + Future loadRepresentative() async { + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + + if (manager.coin == Coin.nano) { + return (manager.wallet as NanoWallet).getCurrentRepresentative(); + } else if (manager.coin == Coin.banano) { + return (manager.wallet as BananoWallet).getCurrentRepresentative(); + } + throw Exception("Unsupported wallet attempted to show representative!"); + } + + Future _save() async { + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + + final changeFuture = manager.coin == Coin.nano + ? (manager.wallet as NanoWallet).changeRepresentative + : (manager.wallet as BananoWallet).changeRepresentative; + + final result = await showLoading( + whileFuture: changeFuture(_textController.text), + context: context, + message: "Updating representative...", + onException: (ex) { + String msg = ex.toString(); + while (msg.isNotEmpty && msg.startsWith("Exception:")) { + msg = msg.substring(10).trim(); + } + showFloatingFlushBar( + type: FlushBarType.warning, + message: msg, + context: context, + ); + }); + + if (mounted) { + if (result != null && result) { + setState(() { + representative = _textController.text; + _textController.text = ""; + }); + await showFloatingFlushBar( + type: FlushBarType.success, + message: "Representative changed", + context: context, + ); + } + } + } + + @override + void initState() { + _clipboardInterface = widget.clipboardInterface; + + super.initState(); + } + + @override + void dispose() { + _textController.dispose(); + _textFocusNode.dispose(); + super.dispose(); + } + + Future _copy() async { + await _clipboardInterface + .setData(ClipboardData(text: representative ?? "")); + if (mounted) { + unawaited(showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + iconAsset: Assets.svg.copy, + context: context, + )); + } + } + + @override + Widget build(BuildContext context) { + return ConditionalParent( + condition: !isDesktop, + builder: (child) => Background( + child: SafeArea( + child: Scaffold( + backgroundColor: + Theme.of(context).extension()!.background, + appBar: AppBar( + leading: AppBarBackButton( + onPressed: () async { + Navigator.of(context).pop(); + }, + ), + title: Text( + "Wallet representative", + style: STextStyles.navBarTitle(context), + ), + actions: [ + Padding( + padding: const EdgeInsets.all(10), + child: AspectRatio( + aspectRatio: 1, + child: AppBarIconButton( + color: Theme.of(context) + .extension()! + .background, + shadows: const [], + icon: SvgPicture.asset( + Assets.svg.copy, + width: 24, + height: 24, + color: Theme.of(context) + .extension()! + .topNavIconPrimary, + ), + onPressed: () { + if (representative != null) { + _copy(); + } + }, + ), + ), + ), + ], + ), + body: Padding( + padding: const EdgeInsets.only( + top: 12, + left: 16, + right: 16, + ), + child: child, + ), + ), + ), + ), + child: ConditionalParent( + condition: isDesktop, + builder: (child) => DesktopDialog( + maxWidth: 600, + maxHeight: double.infinity, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 32, + ), + child: Text( + "${ref.watch(walletsChangeNotifierProvider.select((value) => value.getManager(widget.walletId).walletName))} xPub", + style: STextStyles.desktopH2(context), + ), + ), + DesktopDialogCloseButton( + onPressedOverride: Navigator.of( + context, + rootNavigator: true, + ).pop, + ), + ], + ), + AnimatedSize( + duration: const Duration( + milliseconds: 150, + ), + child: Padding( + padding: const EdgeInsets.fromLTRB(32, 0, 32, 32), + child: child, + ), + ), + ], + ), + ), + child: Column( + children: [ + if (isDesktop) const SizedBox(height: 44), + ConditionalParent( + condition: !isDesktop, + builder: (child) => Expanded( + child: child, + ), + child: FutureBuilder( + future: loadRepresentative(), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + representative = snapshot.data!; + } + + const height = 600.0; + Widget child; + if (representative == null) { + child = const SizedBox( + key: Key("loadingRepresentative"), + height: height, + child: Center( + child: LoadingIndicator( + width: 100, + ), + ), + ); + } else { + child = Column( + children: [ + RoundedWhiteContainer( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + representative!, + style: STextStyles.itemSubtitle(context), + ), + ], + ), + ), + const SizedBox( + height: 24, + ), + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: Util.isDesktop ? false : true, + enableSuggestions: Util.isDesktop ? false : true, + controller: _textController, + style: isDesktop + ? STextStyles.desktopTextExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textFieldActiveText, + height: 1.8, + ) + : STextStyles.field(context), + focusNode: _textFocusNode, + decoration: standardInputDecoration( + "Enter new representative", + _textFocusNode, + context, + desktopMed: isDesktop, + ).copyWith( + contentPadding: isDesktop + ? const EdgeInsets.only( + left: 16, + top: 11, + bottom: 12, + right: 5, + ) + : null, + suffixIcon: _textController.text.isNotEmpty + ? Padding( + padding: const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + children: [ + TextFieldIconButton( + child: const XIcon(), + onTap: () async { + setState(() { + _textController.text = ""; + }); + }, + ), + ], + ), + ), + ) + : null, + ), + ), + ), + if (!isDesktop) const Spacer(), + PrimaryButton( + label: "Save", + onPressed: _save, + ), + if (!isDesktop) + const SizedBox( + height: 16, + ), + ], + ); + } + + return AnimatedSwitcher( + duration: const Duration( + milliseconds: 200, + ), + child: child, + ); + }, + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/settings_views/global_settings_view/xpub_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart similarity index 100% rename from lib/pages/settings_views/global_settings_view/xpub_view.dart rename to lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart diff --git a/lib/pages/token_view/sub_widgets/my_token_select_item.dart b/lib/pages/token_view/sub_widgets/my_token_select_item.dart index 31dc2b085..323ddcf8b 100644 --- a/lib/pages/token_view/sub_widgets/my_token_select_item.dart +++ b/lib/pages/token_view/sub_widgets/my_token_select_item.dart @@ -100,7 +100,7 @@ class _MyTokenSelectItemState extends ConsumerState { message: "Loading ${widget.token.name}", ); - if (!success) { + if (!success!) { return; } diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart index 68fe09aa8..0eda83ce4 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart @@ -13,7 +13,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:stackwallet/pages/settings_views/global_settings_view/xpub_view.dart'; +import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart'; import 'package:stackwallet/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart'; import 'package:stackwallet/providers/providers.dart'; diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 7ccc378c9..66239aaf7 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -103,14 +103,15 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/support_vi import 'package:stackwallet/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_preferences_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart'; -import 'package:stackwallet/pages/settings_views/global_settings_view/xpub_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_view.dart'; +import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart'; +import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart'; import 'package:stackwallet/pages/stack_privacy_calls.dart'; import 'package:stackwallet/pages/token_view/my_tokens_view.dart'; import 'package:stackwallet/pages/token_view/token_contract_details_view.dart'; @@ -564,6 +565,20 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case ChangeRepresentativeView.routeName: + if (args is String) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => ChangeRepresentativeView( + walletId: args, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case AppearanceSettingsView.routeName: return getRoute( shouldUseMaterialRoute: useMaterialPageRoute, diff --git a/lib/services/coins/banano/banano_wallet.dart b/lib/services/coins/banano/banano_wallet.dart index 8511f5599..a050b4027 100644 --- a/lib/services/coins/banano/banano_wallet.dart +++ b/lib/services/coins/banano/banano_wallet.dart @@ -14,9 +14,9 @@ import 'package:stackwallet/services/event_bus/events/global/node_connection_sta import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; -import 'package:stackwallet/services/mixins/coin_control_interface.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; +import 'package:stackwallet/services/nano_api.dart'; import 'package:stackwallet/services/node_service.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; @@ -32,8 +32,7 @@ const int MINIMUM_CONFIRMATIONS = 1; const String DEFAULT_REPRESENTATIVE = "ban_1ka1ium4pfue3uxtntqsrib8mumxgazsjf58gidh1xeo5te3whsq8z476goo"; -class BananoWallet extends CoinServiceAPI - with WalletCache, WalletDB, CoinControlInterface { +class BananoWallet extends CoinServiceAPI with WalletCache, WalletDB { BananoWallet({ required String walletId, required String walletName, @@ -925,4 +924,51 @@ class BananoWallet extends CoinServiceAPI ); await updateCachedChainHeight(height ?? 0); } + + Future getCurrentRepresentative() async { + final serverURI = Uri.parse(getCurrentNode().host); + final address = await currentReceivingAddress; + + final response = await NanoAPI.getAccountInfo( + server: serverURI, + representative: true, + account: address, + ); + + return response.accountInfo?.representative ?? DEFAULT_REPRESENTATIVE; + } + + Future changeRepresentative(String newRepresentative) async { + try { + final serverURI = Uri.parse(getCurrentNode().host); + final balance = this.balance.spendable.raw.toString(); + final String privateKey = await getPrivateKeyFromMnemonic(); + final address = await currentReceivingAddress; + + final response = await NanoAPI.getAccountInfo( + server: serverURI, + representative: true, + account: address, + ); + + if (response.accountInfo == null) { + throw response.exception ?? Exception("Failed to get account info"); + } + + final work = await requestWork(response.accountInfo!.frontier); + + return await NanoAPI.changeRepresentative( + server: serverURI, + accountType: NanoAccountType.BANANO, + account: address, + newRepresentative: newRepresentative, + previousBlock: response.accountInfo!.frontier, + balance: balance, + privateKey: privateKey, + work: work!, + ); + } catch (_) { + rethrow; + } + } } diff --git a/lib/services/coins/nano/nano_wallet.dart b/lib/services/coins/nano/nano_wallet.dart index 1e783bf5f..391303675 100644 --- a/lib/services/coins/nano/nano_wallet.dart +++ b/lib/services/coins/nano/nano_wallet.dart @@ -24,9 +24,9 @@ import 'package:stackwallet/services/event_bus/events/global/node_connection_sta import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; -import 'package:stackwallet/services/mixins/coin_control_interface.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; +import 'package:stackwallet/services/nano_api.dart'; import 'package:stackwallet/services/node_service.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; @@ -42,8 +42,7 @@ const int MINIMUM_CONFIRMATIONS = 1; const String DEFAULT_REPRESENTATIVE = "nano_38713x95zyjsqzx6nm1dsom1jmm668owkeb9913ax6nfgj15az3nu8xkx579"; -class NanoWallet extends CoinServiceAPI - with WalletCache, WalletDB, CoinControlInterface { +class NanoWallet extends CoinServiceAPI with WalletCache, WalletDB { NanoWallet({ required String walletId, required String walletName, @@ -937,4 +936,51 @@ class NanoWallet extends CoinServiceAPI ); await updateCachedChainHeight(height ?? 0); } + + Future getCurrentRepresentative() async { + final serverURI = Uri.parse(getCurrentNode().host); + final address = await currentReceivingAddress; + + final response = await NanoAPI.getAccountInfo( + server: serverURI, + representative: true, + account: address, + ); + + return response.accountInfo?.representative ?? DEFAULT_REPRESENTATIVE; + } + + Future changeRepresentative(String newRepresentative) async { + try { + final serverURI = Uri.parse(getCurrentNode().host); + final balance = this.balance.spendable.raw.toString(); + final String privateKey = await getPrivateKeyFromMnemonic(); + final address = await currentReceivingAddress; + + final response = await NanoAPI.getAccountInfo( + server: serverURI, + representative: true, + account: address, + ); + + if (response.accountInfo == null) { + throw response.exception ?? Exception("Failed to get account info"); + } + + final work = await requestWork(response.accountInfo!.frontier); + + return await NanoAPI.changeRepresentative( + server: serverURI, + accountType: NanoAccountType.NANO, + account: address, + newRepresentative: newRepresentative, + previousBlock: response.accountInfo!.frontier, + balance: balance, + privateKey: privateKey, + work: work!, + ); + } catch (_) { + rethrow; + } + } } diff --git a/lib/services/nano_api.dart b/lib/services/nano_api.dart new file mode 100644 index 000000000..3173bfbe6 --- /dev/null +++ b/lib/services/nano_api.dart @@ -0,0 +1,130 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'package:nanodart/nanodart.dart'; + +class NanoAPI { + static Future< + ({ + NAccountInfo? accountInfo, + Exception? exception, + })> getAccountInfo({ + required Uri server, + required bool representative, + required String account, + }) async { + NAccountInfo? accountInfo; + Exception? exception; + + try { + final response = await http.post( + server, + headers: { + "Content-Type": "application/json", + }, + body: jsonEncode({ + "action": "account_info", + "representative": "true", + "account": account, + }), + ); + + final map = jsonDecode(response.body); + + if (map is Map && map["error"] != null) { + throw Exception(map["error"].toString()); + } + + accountInfo = NAccountInfo( + frontier: map["frontier"] as String, + representative: map["representative"] as String, + ); + } on Exception catch (e) { + exception = e; + } catch (e) { + exception = Exception(e.toString()); + } + + return (accountInfo: accountInfo, exception: exception); + } + + static Future changeRepresentative({ + required Uri server, + required int accountType, + required String account, + required String newRepresentative, + required String previousBlock, + required String balance, + required String privateKey, + required String work, + }) async { + Map block = { + "type": "state", + "account": account, + "previous": previousBlock, + "representative": newRepresentative, + "balance": balance, + "link": + "0000000000000000000000000000000000000000000000000000000000000000", + "work": work, + }; + + final String hash; + + try { + hash = NanoBlocks.computeStateHash( + accountType, + account, + previousBlock, + newRepresentative, + BigInt.parse(balance), + block["link"] as String, + ); + } catch (e) { + if (e is RangeError) { + throw Exception("Invalid representative format"); + } + rethrow; + } + + final signature = NanoSignatures.signBlock(hash, privateKey); + + block["signature"] = signature; + + final map = await postBlock(server: server, block: block); + + if (map is Map && map["error"] != null) { + throw Exception(map["error"].toString()); + } + + return map["error"] == null; + } + + // TODO: GET RID OF DYNAMIC AND USED TYPED DATA + static Future postBlock({ + required Uri server, + required Map block, + }) async { + final response = await http.post( + server, + headers: { + "Content-Type": "application/json", + }, + body: jsonEncode({ + "action": "process", + "json_block": "true", + "subtype": "change", + "block": block, + }), + ); + + return jsonDecode(response.body); + } +} + +class NAccountInfo { + final String frontier; + final String representative; + + NAccountInfo({required this.frontier, required this.representative}); +} diff --git a/lib/utilities/show_loading.dart b/lib/utilities/show_loading.dart index db4437d6f..759eaa05c 100644 --- a/lib/utilities/show_loading.dart +++ b/lib/utilities/show_loading.dart @@ -12,15 +12,17 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/widgets/custom_loading_overlay.dart'; -Future showLoading({ +Future showLoading({ required Future whileFuture, required BuildContext context, required String message, String? subMessage, bool isDesktop = false, bool opaqueBG = false, + void Function(Exception)? onException, }) async { unawaited( showDialog( @@ -43,10 +45,24 @@ Future showLoading({ ), ); - final result = await whileFuture; + Exception? ex; + T? result; + + try { + result = await whileFuture; + } catch (e, s) { + Logging.instance.log( + "showLoading caught: $e\n$s", + level: LogLevel.Warning, + ); + ex = e is Exception ? e : Exception(e.toString()); + } if (context.mounted) { Navigator.of(context, rootNavigator: isDesktop).pop(); + if (ex != null) { + onException?.call(ex); + } } return result; diff --git a/lib/widgets/wallet_card.dart b/lib/widgets/wallet_card.dart index 63b3a4a0e..09dcb0e2e 100644 --- a/lib/widgets/wallet_card.dart +++ b/lib/widgets/wallet_card.dart @@ -140,7 +140,7 @@ class SimpleWalletCard extends ConsumerWidget { isDesktop: Util.isDesktop, ); - if (!success) { + if (!success!) { // TODO: show error dialog here? Logging.instance.log( "Failed to load token wallet for $contract", From 0d8b710f295b2e2cd4313ed0dbd39d72962cb51c Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 21 Jul 2023 14:52:22 -0600 Subject: [PATCH 41/80] salty sodium ref --- crypto_plugins/flutter_libmonero | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index 407425c9f..d410d983f 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit 407425c9fcf7a30c81f1345246c7225bc18b5cd5 +Subproject commit d410d983f071eaf01372c358d9f0b16af85611f7 From 3125a25a690198dff6b4c7012f84b6937f3c074c Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 21 Jul 2023 15:58:28 -0600 Subject: [PATCH 42/80] add change rep to desktop --- .../change_representative_view.dart | 57 ++++++++++--- .../sub_widgets/wallet_options_button.dart | 81 ++++++++++++++++++- 2 files changed, 125 insertions(+), 13 deletions(-) diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart index 76bb833b1..5c94c0bc5 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart @@ -87,6 +87,7 @@ class _XPubViewState extends ConsumerState { whileFuture: changeFuture(_textController.text), context: context, message: "Updating representative...", + isDesktop: Util.isDesktop, onException: (ex) { String msg = ex.toString(); while (msg.isNotEmpty && msg.startsWith("Exception:")) { @@ -214,7 +215,7 @@ class _XPubViewState extends ConsumerState { left: 32, ), child: Text( - "${ref.watch(walletsChangeNotifierProvider.select((value) => value.getManager(widget.walletId).walletName))} xPub", + "Change representative", style: STextStyles.desktopH2(context), ), ), @@ -240,7 +241,7 @@ class _XPubViewState extends ConsumerState { ), child: Column( children: [ - if (isDesktop) const SizedBox(height: 44), + if (isDesktop) const SizedBox(height: 24), ConditionalParent( condition: !isDesktop, builder: (child) => Expanded( @@ -269,15 +270,48 @@ class _XPubViewState extends ConsumerState { } else { child = Column( children: [ - RoundedWhiteContainer( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - representative!, - style: STextStyles.itemSubtitle(context), - ), - ], + ConditionalParent( + condition: !isDesktop, + builder: (child) => RoundedWhiteContainer( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + child, + ], + ), + ), + child: ConditionalParent( + condition: isDesktop, + builder: (child) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Current representative", + style: STextStyles.desktopTextExtraExtraSmall( + context), + ), + const SizedBox( + height: 4, + ), + child, + ], + ), + child: Row( + children: [ + SelectableText( + representative!, + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + ], + ), ), ), const SizedBox( @@ -337,6 +371,7 @@ class _XPubViewState extends ConsumerState { ), ), ), + if (isDesktop) const SizedBox(height: 60), if (!isDesktop) const Spacer(), PrimaryButton( label: "Save", diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart index 0eda83ce4..61c61a807 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart @@ -13,6 +13,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart'; import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart'; import 'package:stackwallet/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart'; @@ -21,11 +22,13 @@ import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; enum _WalletOptions { addressList, deleteWallet, + changeRepresentative, showXpub; String get prettyName { @@ -34,6 +37,8 @@ enum _WalletOptions { return "Address list"; case _WalletOptions.deleteWallet: return "Delete wallet"; + case _WalletOptions.changeRepresentative: + return "Change representative"; case _WalletOptions.showXpub: return "Show xPub"; } @@ -70,6 +75,9 @@ class WalletOptionsButton extends StatelessWidget { onAddressListPressed: () async { Navigator.of(context).pop(_WalletOptions.addressList); }, + onChangeRepPressed: () async { + Navigator.of(context).pop(_WalletOptions.changeRepresentative); + }, onShowXpubPressed: () async { Navigator.of(context).pop(_WalletOptions.showXpub); }, @@ -134,6 +142,32 @@ class WalletOptionsButton extends StatelessWidget { ), ); + if (result == true) { + if (context.mounted) { + Navigator.of(context).pop(); + } + } + break; + case _WalletOptions.changeRepresentative: + final result = await showDialog( + context: context, + barrierDismissible: false, + builder: (context) => Navigator( + initialRoute: ChangeRepresentativeView.routeName, + onGenerateRoute: RouteGenerator.generateRoute, + onGenerateInitialRoutes: (_, __) { + return [ + RouteGenerator.generateRoute( + RouteSettings( + name: ChangeRepresentativeView.routeName, + arguments: walletId, + ), + ), + ]; + }, + ), + ); + if (result == true) { if (context.mounted) { Navigator.of(context).pop(); @@ -171,18 +205,24 @@ class WalletOptionsPopupMenu extends ConsumerWidget { required this.onDeletePressed, required this.onAddressListPressed, required this.onShowXpubPressed, + required this.onChangeRepPressed, required this.walletId, }) : super(key: key); final VoidCallback onDeletePressed; final VoidCallback onAddressListPressed; final VoidCallback onShowXpubPressed; + final VoidCallback onChangeRepPressed; final String walletId; @override Widget build(BuildContext context, WidgetRef ref) { - final bool xpubEnabled = ref.watch(walletsChangeNotifierProvider - .select((value) => value.getManager(walletId).hasXPub)); + final manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId))); + final bool xpubEnabled = manager.hasXPub; + + final bool canChangeRep = + manager.coin == Coin.nano || manager.coin == Coin.banano; return Stack( children: [ @@ -237,6 +277,43 @@ class WalletOptionsPopupMenu extends ConsumerWidget { ), ), ), + if (canChangeRep) + const SizedBox( + height: 8, + ), + if (canChangeRep) + TransparentButton( + onPressed: onChangeRepPressed, + child: Padding( + padding: const EdgeInsets.all(8), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SvgPicture.asset( + Assets.svg.eye, + width: 20, + height: 20, + color: Theme.of(context) + .extension()! + .textFieldActiveSearchIconLeft, + ), + const SizedBox(width: 14), + Expanded( + child: Text( + _WalletOptions.changeRepresentative.prettyName, + style: STextStyles.desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ), + ), + ), + ], + ), + ), + ), if (xpubEnabled) const SizedBox( height: 8, From 8a0a45f131419380fd21e6e753cfb599d3250fa6 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 21 Jul 2023 16:09:47 -0600 Subject: [PATCH 43/80] mobile rep fix --- .../change_representative_view.dart | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart index 5c94c0bc5..a91b0cb4e 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart @@ -293,25 +293,25 @@ class _XPubViewState extends ConsumerState { const SizedBox( height: 4, ), - child, - ], - ), - child: Row( - children: [ - SelectableText( - representative!, - style: isDesktop - ? STextStyles.desktopTextExtraExtraSmall( - context) - .copyWith( - color: Theme.of(context) - .extension()! - .textDark, - ) - : STextStyles.itemSubtitle12(context), + Row( + children: [ + child, + ], ), ], ), + child: SelectableText( + representative!, + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), ), ), const SizedBox( From 89e803d77d38c8fea74de6f6be0be6888bfb9be6 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 21 Jul 2023 16:58:20 -0600 Subject: [PATCH 44/80] update xmr ref --- crypto_plugins/flutter_libmonero | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index d410d983f..e48952185 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit d410d983f071eaf01372c358d9f0b16af85611f7 +Subproject commit e48952185556a10f182184fd572bcb04365f5831 From 6ff4c5d49aa50359f41998b24269ec40e9c70dcb Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 24 Jul 2023 09:06:10 -0600 Subject: [PATCH 45/80] clean up --- lib/services/coins/firo/firo_wallet.dart | 64 ------------------------ 1 file changed, 64 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index e62b7d069..3527c9802 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -3133,17 +3133,6 @@ class FiroWallet extends CoinServiceAPI txnsData.add(Tuple2(transaction, transactionAddress)); await db.addNewTransactionData(txnsData, walletId); - - // final models.TransactionData newTxData = - // models.TransactionData.fromMap(transactions); - // await DB.instance.put( - // boxName: walletId, - // key: 'latest_lelantus_tx_model', - // value: newTxData); - // final ldata = DB.instance.get( - // boxName: walletId, - // key: 'latest_lelantus_tx_model') as models.TransactionData; - // _lelantusTransactionData = Future(() => ldata); } else { // This is a mint Logging.instance.log("this is a mint", level: LogLevel.Info); @@ -3204,20 +3193,6 @@ class FiroWallet extends CoinServiceAPI Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info); return feeObject; - - // final result = await electrumXClient.getFeeRate(); - // - // final locale = await Devicelocale.currentLocale; - // final String fee = - // Format.satoshiAmountToPrettyString(result["rate"] as int, locale!); - // - // final fees = { - // "fast": fee, - // "average": fee, - // "slow": fee, - // }; - // final FeeObject feeObject = FeeObject.fromJson(fees); - // return feeObject; } catch (e) { Logging.instance .log("Exception rethrown from _getFees(): $e", level: LogLevel.Error); @@ -4072,45 +4047,6 @@ class FiroWallet extends CoinServiceAPI ); } - // /// Takes in a list of isar_models.UTXOs and adds a name (dependent on object index within list) - // /// and checks for the txid associated with the utxo being blocked and marks it accordingly. - // /// Now also checks for output labeling. - // Future _sortOutputs(List utxos) async { - // final blockedHashArray = - // DB.instance.get(boxName: walletId, key: 'blocked_tx_hashes') - // as List?; - // final List lst = []; - // if (blockedHashArray != null) { - // for (var hash in blockedHashArray) { - // lst.add(hash as String); - // } - // } - // final labels = - // DB.instance.get(boxName: walletId, key: 'labels') as Map? ?? - // {}; - // - // _outputsList = []; - // - // for (var i = 0; i < utxos.length; i++) { - // if (labels[utxos[i].txid] != null) { - // utxos[i].txName = labels[utxos[i].txid] as String? ?? ""; - // } else { - // utxos[i].txName = 'Output #$i'; - // } - // - // if (utxos[i].status.confirmed == false) { - // _outputsList.add(utxos[i]); - // } else { - // if (lst.contains(utxos[i].txid)) { - // utxos[i].blocked = true; - // _outputsList.add(utxos[i]); - // } else if (!lst.contains(utxos[i].txid)) { - // _outputsList.add(utxos[i]); - // } - // } - // } - // } - @override Future fullRescan( int maxUnusedAddressGap, From baa34ca9f2cc4c9165073680930be8551a0fd905 Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 24 Jul 2023 09:06:48 -0600 Subject: [PATCH 46/80] isar lelantus coin schema --- lib/db/isar/main_db.dart | 2 + .../models/firo_specific/lelantus_coin.dart | 75 + .../models/firo_specific/lelantus_coin.g.dart | 1570 +++++++++++++++++ 3 files changed, 1647 insertions(+) create mode 100644 lib/models/isar/models/firo_specific/lelantus_coin.dart create mode 100644 lib/models/isar/models/firo_specific/lelantus_coin.g.dart diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index bb6ea5e8d..209f13c5d 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -14,6 +14,7 @@ import 'package:isar/isar.dart'; import 'package:stackwallet/exceptions/main_db/main_db_exception.dart'; import 'package:stackwallet/models/isar/models/block_explorer.dart'; import 'package:stackwallet/models/isar/models/contact_entry.dart'; +import 'package:stackwallet/models/isar/models/firo_specific/lelantus_coin.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/models/isar/stack_theme.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; @@ -54,6 +55,7 @@ class MainDB { TransactionBlockExplorerSchema, StackThemeSchema, ContactEntrySchema, + LelantusCoinSchema, ], directory: (await StackFileSystem.applicationIsarDirectory()).path, // inspector: kDebugMode, diff --git a/lib/models/isar/models/firo_specific/lelantus_coin.dart b/lib/models/isar/models/firo_specific/lelantus_coin.dart new file mode 100644 index 000000000..3dd48b2dc --- /dev/null +++ b/lib/models/isar/models/firo_specific/lelantus_coin.dart @@ -0,0 +1,75 @@ +import 'package:isar/isar.dart'; + +part 'lelantus_coin.g.dart'; + +@collection +class LelantusCoin { + Id id = Isar.autoIncrement; + + @Index() + final String walletId; + + @Index( + unique: true, + composite: [ + CompositeIndex("walletId"), + CompositeIndex("txid"), + ], + replace: false, + ) + final String publicCoin; + + final String txid; + + final String value; // can't use BigInt in isar :shrug: + + final int index; + + final int anonymitySetId; + + final bool isUsed; + + LelantusCoin({ + required this.walletId, + required this.publicCoin, + required this.txid, + required this.value, + required this.index, + required this.anonymitySetId, + required this.isUsed, + }); + + LelantusCoin copyWith({ + String? walletId, + String? publicCoin, + String? txid, + String? value, + int? index, + int? anonymitySetId, + bool? isUsed, + }) { + return LelantusCoin( + walletId: walletId ?? this.walletId, + publicCoin: publicCoin ?? this.publicCoin, + txid: txid ?? this.txid, + value: value ?? this.value, + index: index ?? this.index, + anonymitySetId: anonymitySetId ?? this.anonymitySetId, + isUsed: isUsed ?? this.isUsed, + ); + } + + @override + String toString() { + return 'LelantusCoin{' + 'id: $id, ' + 'walletId: $walletId, ' + 'publicCoin: $publicCoin, ' + 'txid: $txid, ' + 'value: $value, ' + 'index: $index, ' + 'anonymitySetId: $anonymitySetId, ' + 'isUsed: $isUsed' + '}'; + } +} diff --git a/lib/models/isar/models/firo_specific/lelantus_coin.g.dart b/lib/models/isar/models/firo_specific/lelantus_coin.g.dart new file mode 100644 index 000000000..8fafde571 --- /dev/null +++ b/lib/models/isar/models/firo_specific/lelantus_coin.g.dart @@ -0,0 +1,1570 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'lelantus_coin.dart'; + +// ************************************************************************** +// IsarCollectionGenerator +// ************************************************************************** + +// coverage:ignore-file +// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters + +extension GetLelantusCoinCollection on Isar { + IsarCollection get lelantusCoins => this.collection(); +} + +const LelantusCoinSchema = CollectionSchema( + name: r'LelantusCoin', + id: -6795633185033299066, + properties: { + r'anonymitySetId': PropertySchema( + id: 0, + name: r'anonymitySetId', + type: IsarType.long, + ), + r'index': PropertySchema( + id: 1, + name: r'index', + type: IsarType.long, + ), + r'isUsed': PropertySchema( + id: 2, + name: r'isUsed', + type: IsarType.bool, + ), + r'publicCoin': PropertySchema( + id: 3, + name: r'publicCoin', + type: IsarType.string, + ), + r'txid': PropertySchema( + id: 4, + name: r'txid', + type: IsarType.string, + ), + r'value': PropertySchema( + id: 5, + name: r'value', + type: IsarType.string, + ), + r'walletId': PropertySchema( + id: 6, + name: r'walletId', + type: IsarType.string, + ) + }, + estimateSize: _lelantusCoinEstimateSize, + serialize: _lelantusCoinSerialize, + deserialize: _lelantusCoinDeserialize, + deserializeProp: _lelantusCoinDeserializeProp, + idName: r'id', + indexes: { + r'walletId': IndexSchema( + id: -1783113319798776304, + name: r'walletId', + unique: false, + replace: false, + properties: [ + IndexPropertySchema( + name: r'walletId', + type: IndexType.hash, + caseSensitive: true, + ) + ], + ), + r'publicCoin_walletId_txid': IndexSchema( + id: 5610740154835640070, + name: r'publicCoin_walletId_txid', + unique: true, + replace: false, + properties: [ + IndexPropertySchema( + name: r'publicCoin', + type: IndexType.hash, + caseSensitive: true, + ), + IndexPropertySchema( + name: r'walletId', + type: IndexType.hash, + caseSensitive: true, + ), + IndexPropertySchema( + name: r'txid', + type: IndexType.hash, + caseSensitive: true, + ) + ], + ) + }, + links: {}, + embeddedSchemas: {}, + getId: _lelantusCoinGetId, + getLinks: _lelantusCoinGetLinks, + attach: _lelantusCoinAttach, + version: '3.0.5', +); + +int _lelantusCoinEstimateSize( + LelantusCoin object, + List offsets, + Map> allOffsets, +) { + var bytesCount = offsets.last; + bytesCount += 3 + object.publicCoin.length * 3; + bytesCount += 3 + object.txid.length * 3; + bytesCount += 3 + object.value.length * 3; + bytesCount += 3 + object.walletId.length * 3; + return bytesCount; +} + +void _lelantusCoinSerialize( + LelantusCoin object, + IsarWriter writer, + List offsets, + Map> allOffsets, +) { + writer.writeLong(offsets[0], object.anonymitySetId); + writer.writeLong(offsets[1], object.index); + writer.writeBool(offsets[2], object.isUsed); + writer.writeString(offsets[3], object.publicCoin); + writer.writeString(offsets[4], object.txid); + writer.writeString(offsets[5], object.value); + writer.writeString(offsets[6], object.walletId); +} + +LelantusCoin _lelantusCoinDeserialize( + Id id, + IsarReader reader, + List offsets, + Map> allOffsets, +) { + final object = LelantusCoin( + anonymitySetId: reader.readLong(offsets[0]), + index: reader.readLong(offsets[1]), + isUsed: reader.readBool(offsets[2]), + publicCoin: reader.readString(offsets[3]), + txid: reader.readString(offsets[4]), + value: reader.readString(offsets[5]), + walletId: reader.readString(offsets[6]), + ); + object.id = id; + return object; +} + +P _lelantusCoinDeserializeProp

( + IsarReader reader, + int propertyId, + int offset, + Map> allOffsets, +) { + switch (propertyId) { + case 0: + return (reader.readLong(offset)) as P; + case 1: + return (reader.readLong(offset)) as P; + case 2: + return (reader.readBool(offset)) as P; + case 3: + return (reader.readString(offset)) as P; + case 4: + return (reader.readString(offset)) as P; + case 5: + return (reader.readString(offset)) as P; + case 6: + return (reader.readString(offset)) as P; + default: + throw IsarError('Unknown property with id $propertyId'); + } +} + +Id _lelantusCoinGetId(LelantusCoin object) { + return object.id; +} + +List> _lelantusCoinGetLinks(LelantusCoin object) { + return []; +} + +void _lelantusCoinAttach( + IsarCollection col, Id id, LelantusCoin object) { + object.id = id; +} + +extension LelantusCoinByIndex on IsarCollection { + Future getByPublicCoinWalletIdTxid( + String publicCoin, String walletId, String txid) { + return getByIndex( + r'publicCoin_walletId_txid', [publicCoin, walletId, txid]); + } + + LelantusCoin? getByPublicCoinWalletIdTxidSync( + String publicCoin, String walletId, String txid) { + return getByIndexSync( + r'publicCoin_walletId_txid', [publicCoin, walletId, txid]); + } + + Future deleteByPublicCoinWalletIdTxid( + String publicCoin, String walletId, String txid) { + return deleteByIndex( + r'publicCoin_walletId_txid', [publicCoin, walletId, txid]); + } + + bool deleteByPublicCoinWalletIdTxidSync( + String publicCoin, String walletId, String txid) { + return deleteByIndexSync( + r'publicCoin_walletId_txid', [publicCoin, walletId, txid]); + } + + Future> getAllByPublicCoinWalletIdTxid( + List publicCoinValues, + List walletIdValues, + List txidValues) { + final len = publicCoinValues.length; + assert(walletIdValues.length == len && txidValues.length == len, + 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([publicCoinValues[i], walletIdValues[i], txidValues[i]]); + } + + return getAllByIndex(r'publicCoin_walletId_txid', values); + } + + List getAllByPublicCoinWalletIdTxidSync( + List publicCoinValues, + List walletIdValues, + List txidValues) { + final len = publicCoinValues.length; + assert(walletIdValues.length == len && txidValues.length == len, + 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([publicCoinValues[i], walletIdValues[i], txidValues[i]]); + } + + return getAllByIndexSync(r'publicCoin_walletId_txid', values); + } + + Future deleteAllByPublicCoinWalletIdTxid(List publicCoinValues, + List walletIdValues, List txidValues) { + final len = publicCoinValues.length; + assert(walletIdValues.length == len && txidValues.length == len, + 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([publicCoinValues[i], walletIdValues[i], txidValues[i]]); + } + + return deleteAllByIndex(r'publicCoin_walletId_txid', values); + } + + int deleteAllByPublicCoinWalletIdTxidSync(List publicCoinValues, + List walletIdValues, List txidValues) { + final len = publicCoinValues.length; + assert(walletIdValues.length == len && txidValues.length == len, + 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([publicCoinValues[i], walletIdValues[i], txidValues[i]]); + } + + return deleteAllByIndexSync(r'publicCoin_walletId_txid', values); + } + + Future putByPublicCoinWalletIdTxid(LelantusCoin object) { + return putByIndex(r'publicCoin_walletId_txid', object); + } + + Id putByPublicCoinWalletIdTxidSync(LelantusCoin object, + {bool saveLinks = true}) { + return putByIndexSync(r'publicCoin_walletId_txid', object, + saveLinks: saveLinks); + } + + Future> putAllByPublicCoinWalletIdTxid(List objects) { + return putAllByIndex(r'publicCoin_walletId_txid', objects); + } + + List putAllByPublicCoinWalletIdTxidSync(List objects, + {bool saveLinks = true}) { + return putAllByIndexSync(r'publicCoin_walletId_txid', objects, + saveLinks: saveLinks); + } +} + +extension LelantusCoinQueryWhereSort + on QueryBuilder { + QueryBuilder anyId() { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(const IdWhereClause.any()); + }); + } +} + +extension LelantusCoinQueryWhere + on QueryBuilder { + QueryBuilder idEqualTo(Id id) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IdWhereClause.between( + lower: id, + upper: id, + )); + }); + } + + QueryBuilder idNotEqualTo( + Id id) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: false), + ) + .addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: false), + ); + } else { + return query + .addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: false), + ) + .addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: false), + ); + } + }); + } + + QueryBuilder idGreaterThan( + Id id, + {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: include), + ); + }); + } + + QueryBuilder idLessThan(Id id, + {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: include), + ); + }); + } + + QueryBuilder idBetween( + Id lowerId, + Id upperId, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IdWhereClause.between( + lower: lowerId, + includeLower: includeLower, + upper: upperId, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder walletIdEqualTo( + String walletId) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'walletId', + value: [walletId], + )); + }); + } + + QueryBuilder + walletIdNotEqualTo(String walletId) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'walletId', + lower: [], + upper: [walletId], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'walletId', + lower: [walletId], + includeLower: false, + upper: [], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'walletId', + lower: [walletId], + includeLower: false, + upper: [], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'walletId', + lower: [], + upper: [walletId], + includeUpper: false, + )); + } + }); + } + + QueryBuilder + publicCoinEqualToAnyWalletIdTxid(String publicCoin) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'publicCoin_walletId_txid', + value: [publicCoin], + )); + }); + } + + QueryBuilder + publicCoinNotEqualToAnyWalletIdTxid(String publicCoin) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [], + upper: [publicCoin], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin], + includeLower: false, + upper: [], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin], + includeLower: false, + upper: [], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [], + upper: [publicCoin], + includeUpper: false, + )); + } + }); + } + + QueryBuilder + publicCoinWalletIdEqualToAnyTxid(String publicCoin, String walletId) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'publicCoin_walletId_txid', + value: [publicCoin, walletId], + )); + }); + } + + QueryBuilder + publicCoinEqualToWalletIdNotEqualToAnyTxid( + String publicCoin, String walletId) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin], + upper: [publicCoin, walletId], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin, walletId], + includeLower: false, + upper: [publicCoin], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin, walletId], + includeLower: false, + upper: [publicCoin], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin], + upper: [publicCoin, walletId], + includeUpper: false, + )); + } + }); + } + + QueryBuilder + publicCoinWalletIdTxidEqualTo( + String publicCoin, String walletId, String txid) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'publicCoin_walletId_txid', + value: [publicCoin, walletId, txid], + )); + }); + } + + QueryBuilder + publicCoinWalletIdEqualToTxidNotEqualTo( + String publicCoin, String walletId, String txid) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin, walletId], + upper: [publicCoin, walletId, txid], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin, walletId, txid], + includeLower: false, + upper: [publicCoin, walletId], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin, walletId, txid], + includeLower: false, + upper: [publicCoin, walletId], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'publicCoin_walletId_txid', + lower: [publicCoin, walletId], + upper: [publicCoin, walletId, txid], + includeUpper: false, + )); + } + }); + } +} + +extension LelantusCoinQueryFilter + on QueryBuilder { + QueryBuilder + anonymitySetIdEqualTo(int value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'anonymitySetId', + value: value, + )); + }); + } + + QueryBuilder + anonymitySetIdGreaterThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'anonymitySetId', + value: value, + )); + }); + } + + QueryBuilder + anonymitySetIdLessThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'anonymitySetId', + value: value, + )); + }); + } + + QueryBuilder + anonymitySetIdBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'anonymitySetId', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder idEqualTo( + Id value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'id', + value: value, + )); + }); + } + + QueryBuilder idGreaterThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder idLessThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder idBetween( + Id lower, + Id upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'id', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder indexEqualTo( + int value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'index', + value: value, + )); + }); + } + + QueryBuilder + indexGreaterThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'index', + value: value, + )); + }); + } + + QueryBuilder indexLessThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'index', + value: value, + )); + }); + } + + QueryBuilder indexBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'index', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder isUsedEqualTo( + bool value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'isUsed', + value: value, + )); + }); + } + + QueryBuilder + publicCoinEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'publicCoin', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + publicCoinGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'publicCoin', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + publicCoinLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'publicCoin', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + publicCoinBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'publicCoin', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + publicCoinStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'publicCoin', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + publicCoinEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'publicCoin', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + publicCoinContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'publicCoin', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + publicCoinMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'publicCoin', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + publicCoinIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'publicCoin', + value: '', + )); + }); + } + + QueryBuilder + publicCoinIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'publicCoin', + value: '', + )); + }); + } + + QueryBuilder txidEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + txidGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder txidLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder txidBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'txid', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + txidStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder txidEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder txidContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder txidMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'txid', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + txidIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'txid', + value: '', + )); + }); + } + + QueryBuilder + txidIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'txid', + value: '', + )); + }); + } + + QueryBuilder valueEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder valueLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder valueBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'value', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder valueEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder valueContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'value', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder valueMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'value', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + valueIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'value', + value: '', + )); + }); + } + + QueryBuilder + valueIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'value', + value: '', + )); + }); + } + + QueryBuilder + walletIdEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + walletIdGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + walletIdLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + walletIdBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'walletId', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + walletIdStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + walletIdEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + walletIdContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + walletIdMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'walletId', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + walletIdIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'walletId', + value: '', + )); + }); + } + + QueryBuilder + walletIdIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'walletId', + value: '', + )); + }); + } +} + +extension LelantusCoinQueryObject + on QueryBuilder {} + +extension LelantusCoinQueryLinks + on QueryBuilder {} + +extension LelantusCoinQuerySortBy + on QueryBuilder { + QueryBuilder + sortByAnonymitySetId() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'anonymitySetId', Sort.asc); + }); + } + + QueryBuilder + sortByAnonymitySetIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'anonymitySetId', Sort.desc); + }); + } + + QueryBuilder sortByIndex() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'index', Sort.asc); + }); + } + + QueryBuilder sortByIndexDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'index', Sort.desc); + }); + } + + QueryBuilder sortByIsUsed() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'isUsed', Sort.asc); + }); + } + + QueryBuilder sortByIsUsedDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'isUsed', Sort.desc); + }); + } + + QueryBuilder sortByPublicCoin() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'publicCoin', Sort.asc); + }); + } + + QueryBuilder + sortByPublicCoinDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'publicCoin', Sort.desc); + }); + } + + QueryBuilder sortByTxid() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'txid', Sort.asc); + }); + } + + QueryBuilder sortByTxidDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'txid', Sort.desc); + }); + } + + QueryBuilder sortByValue() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'value', Sort.asc); + }); + } + + QueryBuilder sortByValueDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'value', Sort.desc); + }); + } + + QueryBuilder sortByWalletId() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'walletId', Sort.asc); + }); + } + + QueryBuilder sortByWalletIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'walletId', Sort.desc); + }); + } +} + +extension LelantusCoinQuerySortThenBy + on QueryBuilder { + QueryBuilder + thenByAnonymitySetId() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'anonymitySetId', Sort.asc); + }); + } + + QueryBuilder + thenByAnonymitySetIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'anonymitySetId', Sort.desc); + }); + } + + QueryBuilder thenById() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.asc); + }); + } + + QueryBuilder thenByIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.desc); + }); + } + + QueryBuilder thenByIndex() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'index', Sort.asc); + }); + } + + QueryBuilder thenByIndexDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'index', Sort.desc); + }); + } + + QueryBuilder thenByIsUsed() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'isUsed', Sort.asc); + }); + } + + QueryBuilder thenByIsUsedDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'isUsed', Sort.desc); + }); + } + + QueryBuilder thenByPublicCoin() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'publicCoin', Sort.asc); + }); + } + + QueryBuilder + thenByPublicCoinDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'publicCoin', Sort.desc); + }); + } + + QueryBuilder thenByTxid() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'txid', Sort.asc); + }); + } + + QueryBuilder thenByTxidDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'txid', Sort.desc); + }); + } + + QueryBuilder thenByValue() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'value', Sort.asc); + }); + } + + QueryBuilder thenByValueDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'value', Sort.desc); + }); + } + + QueryBuilder thenByWalletId() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'walletId', Sort.asc); + }); + } + + QueryBuilder thenByWalletIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'walletId', Sort.desc); + }); + } +} + +extension LelantusCoinQueryWhereDistinct + on QueryBuilder { + QueryBuilder + distinctByAnonymitySetId() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'anonymitySetId'); + }); + } + + QueryBuilder distinctByIndex() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'index'); + }); + } + + QueryBuilder distinctByIsUsed() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'isUsed'); + }); + } + + QueryBuilder distinctByPublicCoin( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'publicCoin', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctByTxid( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'txid', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctByValue( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'value', caseSensitive: caseSensitive); + }); + } + + QueryBuilder distinctByWalletId( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'walletId', caseSensitive: caseSensitive); + }); + } +} + +extension LelantusCoinQueryProperty + on QueryBuilder { + QueryBuilder idProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'id'); + }); + } + + QueryBuilder anonymitySetIdProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'anonymitySetId'); + }); + } + + QueryBuilder indexProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'index'); + }); + } + + QueryBuilder isUsedProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'isUsed'); + }); + } + + QueryBuilder publicCoinProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'publicCoin'); + }); + } + + QueryBuilder txidProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'txid'); + }); + } + + QueryBuilder valueProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'value'); + }); + } + + QueryBuilder walletIdProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'walletId'); + }); + } +} From a5ba67aa1d3a44de01d1ef931931f951a9db4429 Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 24 Jul 2023 09:42:29 -0600 Subject: [PATCH 47/80] WIP migrate lcoins hive => isar --- lib/models/isar/models/isar_models.dart | 1 + lib/models/lelantus_coin.dart | 2 + lib/utilities/constants.dart | 2 +- lib/utilities/db_version_migration.dart | 65 ++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/lib/models/isar/models/isar_models.dart b/lib/models/isar/models/isar_models.dart index ce7652a46..9de91fc84 100644 --- a/lib/models/isar/models/isar_models.dart +++ b/lib/models/isar/models/isar_models.dart @@ -15,5 +15,6 @@ export 'blockchain_data/output.dart'; export 'blockchain_data/transaction.dart'; export 'blockchain_data/utxo.dart'; export 'ethereum/eth_contract.dart'; +export 'firo_specific/lelantus_coin.dart'; export 'log.dart'; export 'transaction_note.dart'; diff --git a/lib/models/lelantus_coin.dart b/lib/models/lelantus_coin.dart index 0e32d33bf..56557c1cd 100644 --- a/lib/models/lelantus_coin.dart +++ b/lib/models/lelantus_coin.dart @@ -12,6 +12,7 @@ import 'package:hive/hive.dart'; part 'type_adaptors/lelantus_coin.g.dart'; +@Deprecated("Use Isar object instead") // @HiveType(typeId: 9) class LelantusCoin { // @HiveField(0) @@ -27,6 +28,7 @@ class LelantusCoin { // @HiveField(5) bool isUsed; + @Deprecated("Use Isar object instead") LelantusCoin( this.index, this.value, diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart index 2dd7be287..ad9d68997 100644 --- a/lib/utilities/constants.dart +++ b/lib/utilities/constants.dart @@ -58,7 +58,7 @@ abstract class Constants { // Enable Logger.print statements static const bool disableLogger = false; - static const int currentDataVersion = 10; + static const int currentDataVersion = 11; static const int rescanV1 = 1; diff --git a/lib/utilities/db_version_migration.dart b/lib/utilities/db_version_migration.dart index 293b5d48c..3f69161f4 100644 --- a/lib/utilities/db_version_migration.dart +++ b/lib/utilities/db_version_migration.dart @@ -180,7 +180,6 @@ class DbVersionMigrator with WalletDB { // clear possible broken firo cache await DB.instance.clearSharedTransactionCache(coin: Coin.firo); - // update version await DB.instance.put( boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 4); @@ -343,12 +342,76 @@ class DbVersionMigrator with WalletDB { // try to continue migrating return await migrate(10, secureStore: secureStore); + case 10: + // migrate + await _v10(secureStore); + + // update version + await DB.instance.put( + boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 11); + + // try to continue migrating + return await migrate(11, secureStore: secureStore); + default: // finally return return; } } + Future _v10(SecureStorageInterface secureStore) async { + await Hive.openBox(DB.boxNameAllWalletsData); + await Hive.openBox(DB.boxNamePrefs); + final walletsService = WalletsService(secureStorageInterface: secureStore); + final prefs = Prefs.instance; + final walletInfoList = await walletsService.walletNames; + await prefs.init(); + await MainDB.instance.initMainDB(); + + for (final walletId in walletInfoList.keys) { + final info = walletInfoList[walletId]!; + assert(info.walletId == walletId); + + if (info.coin == Coin.firo && + MainDB.instance.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .countSync() == + 0) { + final walletBox = await Hive.openBox(walletId); + + final hiveLCoins = DB.instance.get( + boxName: walletId, + key: "_lelantus_coins", + ) as List? ?? + []; + + final List coins = []; + for (final e in hiveLCoins) { + final lcoin = e as LelantusCoin; + + final coin = isar_models.LelantusCoin( + walletId: walletId, + publicCoin: lcoin.publicCoin, + txid: lcoin.txId, + value: lcoin.value.toString(), + index: lcoin.index, + anonymitySetId: lcoin.anonymitySetId, + isUsed: lcoin.isUsed, + ); + + coins.add(coin); + } + + if (coins.isNotEmpty) { + await MainDB.instance.isar.writeTxn(() async { + await MainDB.instance.isar.lelantusCoins.putAll(coins); + }); + } + } + } + } + Future _v4(SecureStorageInterface secureStore) async { await Hive.openBox(DB.boxNameAllWalletsData); await Hive.openBox(DB.boxNamePrefs); From df0b004b82478600ddcc073c222701b820022591 Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 24 Jul 2023 12:30:01 -0600 Subject: [PATCH 48/80] finish up basic migrate lcoins hive => isar --- lib/services/coins/firo/firo_wallet.dart | 565 ++++++++++++----------- lib/services/mixins/firo_hive.dart | 26 +- lib/utilities/db_version_migration.dart | 3 +- 3 files changed, 301 insertions(+), 293 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 3527c9802..004e5399c 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -26,7 +26,6 @@ import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; -import 'package:stackwallet/models/lelantus_coin.dart'; import 'package:stackwallet/models/lelantus_fee_data.dart'; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/models/signing_data.dart'; @@ -161,6 +160,7 @@ Future executeNative(Map arguments) async { final mnemonicPassphrase = arguments['mnemonicPassphrase'] as String; final coin = arguments['coin'] as Coin; final network = arguments['network'] as NetworkType; + final walletId = arguments['walletId'] as String; final restoreData = await isolateRestore( mnemonic, @@ -170,6 +170,7 @@ Future executeNative(Map arguments) async { setDataMap, usedSerialNumbers, network, + walletId, ); sendPort.send(restoreData); return; @@ -206,13 +207,14 @@ Future> isolateRestore( Map _setDataMap, List _usedSerialNumbers, NetworkType network, + String walletId, ) async { List jindexes = []; - List> lelantusCoins = []; + List lelantusCoins = []; final List spendTxIds = []; - var lastFoundIndex = 0; - var currentIndex = 0; + int lastFoundIndex = 0; + int currentIndex = 0; try { Set usedSerialNumbersSet = _usedSerialNumbers.toSet(); @@ -239,7 +241,7 @@ Future> isolateRestore( isTestnet: coin == Coin.firoTestNet, ); - for (var setId = 1; setId <= _latestSetId; setId++) { + for (int setId = 1; setId <= _latestSetId; setId++) { final setData = _setDataMap[setId] as Map; final foundCoin = (setData["coins"] as List).firstWhere( (e) => e[1] == mintTag, @@ -264,32 +266,23 @@ Future> isolateRestore( isTestnet: coin == Coin.firoTestNet, ); final bool isUsed = usedSerialNumbersSet.contains(serialNumber); - final duplicateCoin = lelantusCoins.firstWhere( - (element) { - final coin = element.values.first; - return coin.txId == txId && - coin.index == currentIndex && - coin.anonymitySetId != setId; - }, - orElse: () => {}, + + lelantusCoins.removeWhere((e) => + e.txid == txId && + e.index == currentIndex && + e.anonymitySetId != setId); + + lelantusCoins.add( + isar_models.LelantusCoin( + walletId: walletId, + index: currentIndex, + value: amount.toString(), + publicCoin: publicCoin, + txid: txId, + anonymitySetId: setId, + isUsed: isUsed, + ), ); - if (duplicateCoin.isNotEmpty) { - Logging.instance.log( - "Firo isolateRestore removing duplicate coin: $duplicateCoin", - level: LogLevel.Info, - ); - lelantusCoins.remove(duplicateCoin); - } - lelantusCoins.add({ - txId: LelantusCoin( - currentIndex, - amount, - publicCoin, - txId, - setId, - isUsed, - ) - }); Logging.instance.log( "amount $amount used $isUsed", level: LogLevel.Info, @@ -322,32 +315,22 @@ Future> isolateRestore( isTestnet: coin == Coin.firoTestNet, ); bool isUsed = usedSerialNumbersSet.contains(serialNumber); - final duplicateCoin = lelantusCoins.firstWhere( - (element) { - final coin = element.values.first; - return coin.txId == txId && - coin.index == currentIndex && - coin.anonymitySetId != setId; - }, - orElse: () => {}, + lelantusCoins.removeWhere((e) => + e.txid == txId && + e.index == currentIndex && + e.anonymitySetId != setId); + + lelantusCoins.add( + isar_models.LelantusCoin( + walletId: walletId, + index: currentIndex, + value: amount.toString(), + publicCoin: publicCoin, + txid: txId, + anonymitySetId: setId, + isUsed: isUsed, + ), ); - if (duplicateCoin.isNotEmpty) { - Logging.instance.log( - "Firo isolateRestore removing duplicate coin: $duplicateCoin", - level: LogLevel.Info, - ); - lelantusCoins.remove(duplicateCoin); - } - lelantusCoins.add({ - txId: LelantusCoin( - currentIndex, - amount, - publicCoin, - txId, - setId, - isUsed, - ) - }); jindexes.add(currentIndex); spendTxIds.add(txId); @@ -396,73 +379,74 @@ Future> staticProcessRestore( Map result, int currentHeight, ) async { - List? _l = result['_lelantus_coins'] as List?; - final List> lelantusCoins = []; - for (var el in _l ?? []) { - lelantusCoins.add({el.keys.first: el.values.first as LelantusCoin}); - } + List lelantusCoins = + result['_lelantus_coins'] as List; // Edit the receive transactions with the mint fees. - Map editedTransactions = - {}; - for (var item in lelantusCoins) { - item.forEach((key, value) { - String txid = value.txId; - isar_models.Transaction? tx; + List editedTransactions = []; + + for (final coin in lelantusCoins) { + String txid = coin.txid; + isar_models.Transaction? tx; + try { + tx = txns.firstWhere((e) => e.txid == txid); + } catch (_) { + tx = null; + } + + if (tx == null || tx.subType == isar_models.TransactionSubType.join) { + // This is a jmint. + continue; + } + + List inputTxns = []; + for (final input in tx.inputs) { + isar_models.Transaction? inputTx; try { - tx = txns.firstWhere((e) => e.txid == txid); + inputTx = txns.firstWhere((e) => e.txid == input.txid); } catch (_) { - tx = null; + inputTx = null; } + if (inputTx != null) { + inputTxns.add(inputTx); + } + } + if (inputTxns.isEmpty) { + //some error. + Logging.instance.log( + "cryptic \"//some error\" occurred in staticProcessRestore on lelantus coin: $coin", + level: LogLevel.Error, + ); + continue; + } - if (tx == null || tx.subType == isar_models.TransactionSubType.join) { - // This is a jmint. - return; - } - List inputs = []; - for (var element in tx.inputs) { - isar_models.Transaction? input; - try { - input = txns.firstWhere((e) => e.txid == element.txid); - } catch (_) { - input = null; - } - if (input != null) { - inputs.add(input); - } - } - if (inputs.isEmpty) { - //some error. - return; - } - - int mintFee = tx.fee; - int sharedFee = mintFee ~/ inputs.length; - for (var element in inputs) { - editedTransactions[element.txid] = isar_models.Transaction( - walletId: element.walletId, - txid: element.txid, - timestamp: element.timestamp, - type: element.type, - subType: isar_models.TransactionSubType.mint, - amount: element.amount, - amountString: Amount( - rawValue: BigInt.from(element.amount), - fractionDigits: Coin.firo.decimals, - ).toJsonString(), - fee: sharedFee, - height: element.height, - isCancelled: false, - isLelantus: true, - slateId: null, - otherData: txid, - nonce: null, - inputs: element.inputs, - outputs: element.outputs, - numberOfMessages: null, - )..address.value = element.address.value; - } - }); + int mintFee = tx.fee; + int sharedFee = mintFee ~/ inputTxns.length; + for (final inputTx in inputTxns) { + final edited = isar_models.Transaction( + walletId: inputTx.walletId, + txid: inputTx.txid, + timestamp: inputTx.timestamp, + type: inputTx.type, + subType: isar_models.TransactionSubType.mint, + amount: inputTx.amount, + amountString: Amount( + rawValue: BigInt.from(inputTx.amount), + fractionDigits: Coin.firo.decimals, + ).toJsonString(), + fee: sharedFee, + height: inputTx.height, + isCancelled: false, + isLelantus: true, + slateId: null, + otherData: txid, + nonce: null, + inputs: inputTx.inputs, + outputs: inputTx.outputs, + numberOfMessages: null, + )..address.value = inputTx.address.value; + editedTransactions.add(edited); + } } // Logging.instance.log(editedTransactions, addToDebugMessagesDB: false); @@ -472,12 +456,13 @@ Future> staticProcessRestore( } // Logging.instance.log(transactionMap, addToDebugMessagesDB: false); - editedTransactions.forEach((key, value) { - transactionMap.update(key, (_value) => value); - }); + // update with edited transactions + for (final tx in editedTransactions) { + transactionMap[tx.txid] = tx; + } transactionMap.removeWhere((key, value) => - lelantusCoins.any((element) => element.containsKey(key)) || + lelantusCoins.any((element) => element.txid == key) || ((value.height == -1 || value.height == null) && !value.isConfirmed(currentHeight, MINIMUM_CONFIRMATIONS))); @@ -2248,9 +2233,9 @@ class FiroWallet extends CoinServiceAPI _feeObject = Future(() => feeObj); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.60, walletId)); - final lelantusCoins = getLelantusCoinMap(); - Logging.instance.log("_lelantus_coins at refresh: $lelantusCoins", - level: LogLevel.Warning, printFullLength: true); + // final lelantusCoins = getLelantusCoinMap(); + // Logging.instance.log("_lelantus_coins at refresh: $lelantusCoins", + // level: LogLevel.Warning, printFullLength: true); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.70, walletId)); await _refreshLelantusData(); @@ -2327,7 +2312,8 @@ class FiroWallet extends CoinServiceAPI level: LogLevel.Error); } - final List lelantusCoins = await _getUnspentCoins(); + final List lelantusCoins = + await _getUnspentCoins(); final root = await Bip32Utils.getBip32Root( _mnemonic!, @@ -2349,7 +2335,7 @@ class FiroWallet extends CoinServiceAPI } final String privateKey = Format.uint8listToString(keyPair.privateKey!); return DartLelantusEntry(coin.isUsed ? 1 : 0, 0, coin.anonymitySetId, - coin.value, coin.index, privateKey); + int.parse(coin.value), coin.index, privateKey); }).toList(); final lelantusEntries = await Future.wait(waitLelantusEntries); @@ -2361,61 +2347,55 @@ class FiroWallet extends CoinServiceAPI return lelantusEntries; } - List> getLelantusCoinMap() { - final _l = firoGetLelantusCoins(); - final List> lelantusCoins = []; - for (var el in _l ?? []) { - lelantusCoins.add({el.keys.first: el.values.first as LelantusCoin}); - } - return lelantusCoins; - } + Future> _getUnspentCoins() async { + final jindexes = firoGetJIndex() ?? []; - Future> _getUnspentCoins() async { - final List> lelantusCoins = getLelantusCoinMap(); - if (lelantusCoins.isNotEmpty) { - lelantusCoins.removeWhere((element) => - element.values.any((elementCoin) => elementCoin.value == 0)); - } - final jindexes = firoGetJIndex(); + final lelantusCoinsList = await db.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .filter() + .not() + .valueEqualTo("0") + .findAll(); - List coins = []; - - List lelantusCoinsList = - lelantusCoins.fold([], (previousValue, element) { - previousValue.add(element.values.first); - return previousValue; - }); + List coins = []; final currentChainHeight = await chainHeight; for (int i = 0; i < lelantusCoinsList.length; i++) { // Logging.instance.log("lelantusCoinsList[$i]: ${lelantusCoinsList[i]}"); - final txid = lelantusCoinsList[i].txId; - final txn = await cachedElectrumXClient.getTransaction( - txHash: txid, - verbose: true, - coin: coin, - ); - final confirmations = txn["confirmations"]; - bool isUnconfirmed = confirmations is int && confirmations < 1; + final coin = lelantusCoinsList[i]; - final tx = await db.getTransaction(walletId, txid); + final tx = await db.getTransaction(walletId, coin.txid); - if (!jindexes!.contains(lelantusCoinsList[i].index) && - tx != null && - tx.isLelantus == true && - !(tx.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS))) { - isUnconfirmed = true; + // TODO check if sane default + bool isUnconfirmed = false; + + if (tx != null) { + bool isConfirmed = tx.isConfirmed( + currentChainHeight, + MINIMUM_CONFIRMATIONS, + ); + if (!jindexes.contains(coin.index) && + tx.isLelantus == true && + !isConfirmed) { + isUnconfirmed = true; + } else if (!isConfirmed) { + continue; + } + } else { + final txn = await cachedElectrumXClient.getTransaction( + txHash: coin.txid, + verbose: true, + coin: this.coin, + ); + final confirmations = txn["confirmations"]; + isUnconfirmed = confirmations is int && confirmations < 1; } - - if (tx != null && - !tx.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { - continue; - } - if (!lelantusCoinsList[i].isUsed && - lelantusCoinsList[i].anonymitySetId != ANONYMITY_SET_EMPTY_ID && + if (!coin.isUsed && + coin.anonymitySetId != ANONYMITY_SET_EMPTY_ID && !isUnconfirmed) { - coins.add(lelantusCoinsList[i]); + coins.add(coin); } } return coins; @@ -2427,62 +2407,65 @@ class FiroWallet extends CoinServiceAPI Future _refreshBalance() async { try { final utxosUpdateFuture = _refreshUTXOs(); - final List> lelantusCoins = - getLelantusCoinMap(); - if (lelantusCoins.isNotEmpty) { - lelantusCoins.removeWhere((element) => - element.values.any((elementCoin) => elementCoin.value == 0)); - } + final lelantusCoins = await db.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .filter() + .not() + .valueEqualTo(0.toString()) + .findAll(); final currentChainHeight = await chainHeight; final jindexes = firoGetJIndex(); int intLelantusBalance = 0; int unconfirmedLelantusBalance = 0; - for (final element in lelantusCoins) { - element.forEach((key, lelantusCoin) { - isar_models.Transaction? txn = db.isar.transactions - .where() - .txidWalletIdEqualTo( - lelantusCoin.txId, - walletId, - ) - .findFirstSync(); + for (final lelantusCoin in lelantusCoins) { + isar_models.Transaction? txn = db.isar.transactions + .where() + .txidWalletIdEqualTo( + lelantusCoin.txid, + walletId, + ) + .findFirstSync(); - if (txn == null) { - // TODO: ?????????????????????????????????????? - } else { - bool isLelantus = txn.isLelantus == true; - if (!jindexes!.contains(lelantusCoin.index) && isLelantus) { - if (!lelantusCoin.isUsed && - txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { - // mint tx, add value to balance - intLelantusBalance += lelantusCoin.value; - } /* else { + if (txn == null) { + // TODO: ?????????????????????????????????????? + Logging.instance.log( + "Transaction not found in DB for lelantus coin: $lelantusCoin", + level: LogLevel.Fatal, + ); + } else { + bool isLelantus = txn.isLelantus == true; + if (!jindexes!.contains(lelantusCoin.index) && isLelantus) { + if (!lelantusCoin.isUsed && + txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { + // mint tx, add value to balance + intLelantusBalance += int.parse(lelantusCoin.value); + } /* else { // This coin is not confirmed and may be replaced }*/ - } else if (jindexes.contains(lelantusCoin.index) && - isLelantus && - !lelantusCoin.isUsed && - !txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { - unconfirmedLelantusBalance += lelantusCoin.value; - } else if (jindexes.contains(lelantusCoin.index) && - !lelantusCoin.isUsed) { - intLelantusBalance += lelantusCoin.value; - } else if (!lelantusCoin.isUsed && - (txn.isLelantus == true - ? true - : txn.isConfirmed( - currentChainHeight, MINIMUM_CONFIRMATIONS) != - false)) { - intLelantusBalance += lelantusCoin.value; - } else if (!isLelantus && - txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS) == - false) { - unconfirmedLelantusBalance += lelantusCoin.value; - } + } else if (jindexes.contains(lelantusCoin.index) && + isLelantus && + !lelantusCoin.isUsed && + !txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { + unconfirmedLelantusBalance += int.parse(lelantusCoin.value); + } else if (jindexes.contains(lelantusCoin.index) && + !lelantusCoin.isUsed) { + intLelantusBalance += int.parse(lelantusCoin.value); + } else if (!lelantusCoin.isUsed && + (txn.isLelantus == true + ? true + : txn.isConfirmed( + currentChainHeight, MINIMUM_CONFIRMATIONS) != + false)) { + intLelantusBalance += int.parse(lelantusCoin.value); + } else if (!isLelantus && + txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS) == + false) { + unconfirmedLelantusBalance += int.parse(lelantusCoin.value); } - }); + } } _balancePrivate = Balance( @@ -2551,17 +2534,19 @@ class FiroWallet extends CoinServiceAPI } } - final List> lelantusCoins = getLelantusCoinMap(); - if (lelantusCoins.isNotEmpty) { - lelantusCoins.removeWhere((element) => - element.values.any((elementCoin) => elementCoin.value == 0)); - } + final lelantusCoins = await db.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .filter() + .not() + .valueEqualTo(0.toString()) + .findAll(); + final data = await _txnData; for (final value in data) { if (value.inputs.isNotEmpty) { for (var element in value.inputs) { - if (lelantusCoins - .any((element) => element.keys.contains(value.txid)) && + if (lelantusCoins.any((e) => e.txid == value.txid) && spendableOutputs.firstWhere( (output) => output?.txid == element.txid, orElse: () => null) != @@ -2844,7 +2829,14 @@ class FiroWallet extends CoinServiceAPI } Future _refreshLelantusData() async { - final List> lelantusCoins = getLelantusCoinMap(); + final lelantusCoins = await db.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .filter() + .not() + .valueEqualTo(0.toString()) + .findAll(); + final jindexes = firoGetJIndex(); // Get all joinsplit transaction ids @@ -2855,19 +2847,16 @@ class FiroWallet extends CoinServiceAPI .isLelantusEqualTo(true) .findAll(); List joinsplits = []; + for (final tx in listLelantusTxData) { if (tx.subType == isar_models.TransactionSubType.join) { joinsplits.add(tx.txid); } } - for (final coin - in lelantusCoins.fold([], (previousValue, element) { - (previousValue as List).add(element.values.first); - return previousValue; - })) { + for (final coin in lelantusCoins) { if (jindexes != null) { - if (jindexes.contains(coin.index) && !joinsplits.contains(coin.txId)) { - joinsplits.add(coin.txId); + if (jindexes.contains(coin.index) && !joinsplits.contains(coin.txid)) { + joinsplits.add(coin.txid); } } } @@ -3030,51 +3019,66 @@ class FiroWallet extends CoinServiceAPI Logging.instance.log( "_submitLelantusToNetwork txid: ${transactionInfo['txid']}", level: LogLevel.Info); + if (txid == transactionInfo['txid']) { final index = firoGetMintIndex(); - final List> lelantusCoins = - getLelantusCoinMap(); - List> coins; - if (lelantusCoins.isEmpty) { - coins = []; - } else { - coins = [...lelantusCoins]; - } if (transactionInfo['spendCoinIndexes'] != null) { // This is a joinsplit + final spentCoinIndexes = + transactionInfo['spendCoinIndexes'] as List; + final List updatedCoins = []; + // Update all of the coins that have been spent. - for (final lCoinMap in coins) { - final lCoin = lCoinMap.values.first; - if ((transactionInfo['spendCoinIndexes'] as List) - .contains(lCoin.index)) { - lCoinMap[lCoinMap.keys.first] = LelantusCoin( - lCoin.index, - lCoin.value, - lCoin.publicCoin, - lCoin.txId, - lCoin.anonymitySetId, - true); + + for (final index in spentCoinIndexes) { + final possibleCoins = await db.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .filter() + .indexEqualTo(index) + .findAll(); + + if (possibleCoins.isNotEmpty) { + if (possibleCoins.length > 1) { + print( + "======================= possibleCoins.length > 1 !!! ================================="); + } else { + final spentCoin = possibleCoins.first; + updatedCoins.add(spentCoin.copyWith(isUsed: true)); + } } } // if a jmint was made add it to the unspent coin index - LelantusCoin jmint = LelantusCoin( - index, - transactionInfo['jmintValue'] as int? ?? 0, - transactionInfo['publicCoin'] as String, - transactionInfo['txid'] as String, - latestSetId, - false); - if (jmint.value > 0) { - coins.add({jmint.txId: jmint}); + final jmint = isar_models.LelantusCoin( + walletId: walletId, + index: index, + value: (transactionInfo['jmintValue'] as int? ?? 0).toString(), + publicCoin: transactionInfo['publicCoin'] as String, + txid: transactionInfo['txid'] as String, + anonymitySetId: latestSetId, + isUsed: false, + ); + if (int.parse(jmint.value) > 0) { + updatedCoins.add(jmint); final jindexes = firoGetJIndex()!; jindexes.add(index); await firoUpdateJIndex(jindexes); await firoUpdateMintIndex(index + 1); } - await firoUpdateLelantusCoins(coins); + + await db.isar.writeTxn(() async { + for (final c in updatedCoins) { + await db.isar.lelantusCoins.deleteByPublicCoinWalletIdTxid( + c.publicCoin, + c.walletId, + c.txid, + ); + } + await db.isar.lelantusCoins.putAll(updatedCoins); + }); final amount = Amount.fromDecimal( Decimal.parse(transactionInfo["amount"].toString()), @@ -3087,14 +3091,8 @@ class FiroWallet extends CoinServiceAPI txid: transactionInfo['txid'] as String, timestamp: transactionInfo['timestamp'] as int? ?? (DateTime.now().millisecondsSinceEpoch ~/ 1000), - type: transactionInfo['txType'] == "Received" - ? isar_models.TransactionType.incoming - : isar_models.TransactionType.outgoing, - subType: transactionInfo["subType"] == "mint" - ? isar_models.TransactionSubType.mint - : transactionInfo["subType"] == "join" - ? isar_models.TransactionSubType.join - : isar_models.TransactionSubType.none, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.join, amount: amount.raw.toInt(), amountString: amount.toJsonString(), fee: Amount.fromDecimal( @@ -3137,25 +3135,30 @@ class FiroWallet extends CoinServiceAPI // This is a mint Logging.instance.log("this is a mint", level: LogLevel.Info); + final List updatedCoins = []; + // TODO: transactionInfo['mintsMap'] for (final mintMap in transactionInfo['mintsMap'] as List>) { - final index = mintMap['index'] as int?; - LelantusCoin mint = LelantusCoin( - index!, - mintMap['value'] as int, - mintMap['publicCoin'] as String, - transactionInfo['txid'] as String, - latestSetId, - false, + final index = mintMap['index'] as int; + final mint = isar_models.LelantusCoin( + walletId: walletId, + index: index, + value: (mintMap['value'] as int).toString(), + publicCoin: mintMap['publicCoin'] as String, + txid: transactionInfo['txid'] as String, + anonymitySetId: latestSetId, + isUsed: false, ); - if (mint.value > 0) { - coins.add({mint.txId: mint}); + if (int.parse(mint.value) > 0) { + updatedCoins.add(mint); await firoUpdateMintIndex(index + 1); } } // Logging.instance.log(coins); - await firoUpdateLelantusCoins(coins); + await db.isar.writeTxn(() async { + await db.isar.lelantusCoins.putAll(updatedCoins); + }); } return true; } else { @@ -4556,6 +4559,7 @@ class FiroWallet extends CoinServiceAPI "setDataMap": setDataMap, "usedSerialNumbers": usedSerialNumbers, "network": _network, + "walletId": walletId, }); await Future.wait([dataFuture]); @@ -4576,7 +4580,10 @@ class FiroWallet extends CoinServiceAPI await Future.wait([ firoUpdateMintIndex(message['mintIndex'] as int), - firoUpdateLelantusCoins(message['_lelantus_coins'] as List), + db.isar.writeTxn(() async { + await db.isar.lelantusCoins.putAll( + message['_lelantus_coins'] as List); + }), firoUpdateJIndex(message['jindex'] as List), ]); diff --git a/lib/services/mixins/firo_hive.dart b/lib/services/mixins/firo_hive.dart index be9845453..631aebe6d 100644 --- a/lib/services/mixins/firo_hive.dart +++ b/lib/services/mixins/firo_hive.dart @@ -30,19 +30,19 @@ mixin FiroHive { ); } - // _lelantus_coins - List? firoGetLelantusCoins() { - return DB.instance.get(boxName: _walletId, key: "_lelantus_coins") - as List?; - } - - Future firoUpdateLelantusCoins(List lelantusCoins) async { - await DB.instance.put( - boxName: _walletId, - key: "_lelantus_coins", - value: lelantusCoins, - ); - } + // // _lelantus_coins + // List? firoGetLelantusCoins() { + // return DB.instance.get(boxName: _walletId, key: "_lelantus_coins") + // as List?; + // } + // + // Future firoUpdateLelantusCoins(List lelantusCoins) async { + // await DB.instance.put( + // boxName: _walletId, + // key: "_lelantus_coins", + // value: lelantusCoins, + // ); + // } // mintIndex int firoGetMintIndex() { diff --git a/lib/utilities/db_version_migration.dart b/lib/utilities/db_version_migration.dart index 3f69161f4..dac1dbe82 100644 --- a/lib/utilities/db_version_migration.dart +++ b/lib/utilities/db_version_migration.dart @@ -388,7 +388,8 @@ class DbVersionMigrator with WalletDB { final List coins = []; for (final e in hiveLCoins) { - final lcoin = e as LelantusCoin; + final map = e as Map; + final lcoin = map.values.first as LelantusCoin; final coin = isar_models.LelantusCoin( walletId: walletId, From c97de6017bec6a8dcf5d51ab6467464e3b2b223f Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 24 Jul 2023 15:42:45 -0600 Subject: [PATCH 49/80] update lelantus coin schema --- lib/db/isar/main_db.dart | 1 - .../models/firo_specific/lelantus_coin.dart | 29 +- .../models/firo_specific/lelantus_coin.g.dart | 663 +++++++++++++++--- lib/services/coins/firo/firo_wallet.dart | 24 +- lib/utilities/db_version_migration.dart | 11 +- test/services/coins/manager_test.mocks.dart | 55 -- .../transaction_card_test.mocks.dart | 54 -- 7 files changed, 634 insertions(+), 203 deletions(-) diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index 209f13c5d..fa565c0cd 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -14,7 +14,6 @@ import 'package:isar/isar.dart'; import 'package:stackwallet/exceptions/main_db/main_db_exception.dart'; import 'package:stackwallet/models/isar/models/block_explorer.dart'; import 'package:stackwallet/models/isar/models/contact_entry.dart'; -import 'package:stackwallet/models/isar/models/firo_specific/lelantus_coin.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/models/isar/stack_theme.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; diff --git a/lib/models/isar/models/firo_specific/lelantus_coin.dart b/lib/models/isar/models/firo_specific/lelantus_coin.dart index 3dd48b2dc..9ad5bc5a3 100644 --- a/lib/models/isar/models/firo_specific/lelantus_coin.dart +++ b/lib/models/isar/models/firo_specific/lelantus_coin.dart @@ -23,20 +23,33 @@ class LelantusCoin { final String value; // can't use BigInt in isar :shrug: - final int index; + @Index( + unique: true, + replace: false, + composite: [ + CompositeIndex("walletId"), + ], + ) + final int mintIndex; final int anonymitySetId; final bool isUsed; + final bool isJMint; + + final String? otherData; + LelantusCoin({ required this.walletId, required this.publicCoin, required this.txid, required this.value, - required this.index, + required this.mintIndex, required this.anonymitySetId, required this.isUsed, + required this.isJMint, + required this.otherData, }); LelantusCoin copyWith({ @@ -44,18 +57,22 @@ class LelantusCoin { String? publicCoin, String? txid, String? value, - int? index, + int? mintIndex, int? anonymitySetId, bool? isUsed, + bool? isJMint, + String? otherData, }) { return LelantusCoin( walletId: walletId ?? this.walletId, publicCoin: publicCoin ?? this.publicCoin, txid: txid ?? this.txid, value: value ?? this.value, - index: index ?? this.index, + mintIndex: mintIndex ?? this.mintIndex, anonymitySetId: anonymitySetId ?? this.anonymitySetId, isUsed: isUsed ?? this.isUsed, + isJMint: isJMint ?? this.isJMint, + otherData: otherData ?? this.otherData, ); } @@ -67,8 +84,10 @@ class LelantusCoin { 'publicCoin: $publicCoin, ' 'txid: $txid, ' 'value: $value, ' - 'index: $index, ' + 'mintIndex: $mintIndex, ' 'anonymitySetId: $anonymitySetId, ' + 'otherData: $otherData, ' + 'isJMint: $isJMint, ' 'isUsed: $isUsed' '}'; } diff --git a/lib/models/isar/models/firo_specific/lelantus_coin.g.dart b/lib/models/isar/models/firo_specific/lelantus_coin.g.dart index 8fafde571..d2e27638d 100644 --- a/lib/models/isar/models/firo_specific/lelantus_coin.g.dart +++ b/lib/models/isar/models/firo_specific/lelantus_coin.g.dart @@ -22,33 +22,43 @@ const LelantusCoinSchema = CollectionSchema( name: r'anonymitySetId', type: IsarType.long, ), - r'index': PropertySchema( + r'isJMint': PropertySchema( id: 1, - name: r'index', - type: IsarType.long, + name: r'isJMint', + type: IsarType.bool, ), r'isUsed': PropertySchema( id: 2, name: r'isUsed', type: IsarType.bool, ), - r'publicCoin': PropertySchema( + r'mintIndex': PropertySchema( id: 3, + name: r'mintIndex', + type: IsarType.long, + ), + r'otherData': PropertySchema( + id: 4, + name: r'otherData', + type: IsarType.string, + ), + r'publicCoin': PropertySchema( + id: 5, name: r'publicCoin', type: IsarType.string, ), r'txid': PropertySchema( - id: 4, + id: 6, name: r'txid', type: IsarType.string, ), r'value': PropertySchema( - id: 5, + id: 7, name: r'value', type: IsarType.string, ), r'walletId': PropertySchema( - id: 6, + id: 8, name: r'walletId', type: IsarType.string, ) @@ -94,6 +104,24 @@ const LelantusCoinSchema = CollectionSchema( caseSensitive: true, ) ], + ), + r'mintIndex_walletId': IndexSchema( + id: -9147309777276196770, + name: r'mintIndex_walletId', + unique: true, + replace: false, + properties: [ + IndexPropertySchema( + name: r'mintIndex', + type: IndexType.value, + caseSensitive: false, + ), + IndexPropertySchema( + name: r'walletId', + type: IndexType.hash, + caseSensitive: true, + ) + ], ) }, links: {}, @@ -110,6 +138,12 @@ int _lelantusCoinEstimateSize( Map> allOffsets, ) { var bytesCount = offsets.last; + { + final value = object.otherData; + if (value != null) { + bytesCount += 3 + value.length * 3; + } + } bytesCount += 3 + object.publicCoin.length * 3; bytesCount += 3 + object.txid.length * 3; bytesCount += 3 + object.value.length * 3; @@ -124,12 +158,14 @@ void _lelantusCoinSerialize( Map> allOffsets, ) { writer.writeLong(offsets[0], object.anonymitySetId); - writer.writeLong(offsets[1], object.index); + writer.writeBool(offsets[1], object.isJMint); writer.writeBool(offsets[2], object.isUsed); - writer.writeString(offsets[3], object.publicCoin); - writer.writeString(offsets[4], object.txid); - writer.writeString(offsets[5], object.value); - writer.writeString(offsets[6], object.walletId); + writer.writeLong(offsets[3], object.mintIndex); + writer.writeString(offsets[4], object.otherData); + writer.writeString(offsets[5], object.publicCoin); + writer.writeString(offsets[6], object.txid); + writer.writeString(offsets[7], object.value); + writer.writeString(offsets[8], object.walletId); } LelantusCoin _lelantusCoinDeserialize( @@ -140,12 +176,14 @@ LelantusCoin _lelantusCoinDeserialize( ) { final object = LelantusCoin( anonymitySetId: reader.readLong(offsets[0]), - index: reader.readLong(offsets[1]), + isJMint: reader.readBool(offsets[1]), isUsed: reader.readBool(offsets[2]), - publicCoin: reader.readString(offsets[3]), - txid: reader.readString(offsets[4]), - value: reader.readString(offsets[5]), - walletId: reader.readString(offsets[6]), + mintIndex: reader.readLong(offsets[3]), + otherData: reader.readStringOrNull(offsets[4]), + publicCoin: reader.readString(offsets[5]), + txid: reader.readString(offsets[6]), + value: reader.readString(offsets[7]), + walletId: reader.readString(offsets[8]), ); object.id = id; return object; @@ -161,17 +199,21 @@ P _lelantusCoinDeserializeProp

( case 0: return (reader.readLong(offset)) as P; case 1: - return (reader.readLong(offset)) as P; + return (reader.readBool(offset)) as P; case 2: return (reader.readBool(offset)) as P; case 3: - return (reader.readString(offset)) as P; + return (reader.readLong(offset)) as P; case 4: - return (reader.readString(offset)) as P; + return (reader.readStringOrNull(offset)) as P; case 5: return (reader.readString(offset)) as P; case 6: return (reader.readString(offset)) as P; + case 7: + return (reader.readString(offset)) as P; + case 8: + return (reader.readString(offset)) as P; default: throw IsarError('Unknown property with id $propertyId'); } @@ -290,6 +332,92 @@ extension LelantusCoinByIndex on IsarCollection { return putAllByIndexSync(r'publicCoin_walletId_txid', objects, saveLinks: saveLinks); } + + Future getByMintIndexWalletId(int mintIndex, String walletId) { + return getByIndex(r'mintIndex_walletId', [mintIndex, walletId]); + } + + LelantusCoin? getByMintIndexWalletIdSync(int mintIndex, String walletId) { + return getByIndexSync(r'mintIndex_walletId', [mintIndex, walletId]); + } + + Future deleteByMintIndexWalletId(int mintIndex, String walletId) { + return deleteByIndex(r'mintIndex_walletId', [mintIndex, walletId]); + } + + bool deleteByMintIndexWalletIdSync(int mintIndex, String walletId) { + return deleteByIndexSync(r'mintIndex_walletId', [mintIndex, walletId]); + } + + Future> getAllByMintIndexWalletId( + List mintIndexValues, List walletIdValues) { + final len = mintIndexValues.length; + assert(walletIdValues.length == len, + 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([mintIndexValues[i], walletIdValues[i]]); + } + + return getAllByIndex(r'mintIndex_walletId', values); + } + + List getAllByMintIndexWalletIdSync( + List mintIndexValues, List walletIdValues) { + final len = mintIndexValues.length; + assert(walletIdValues.length == len, + 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([mintIndexValues[i], walletIdValues[i]]); + } + + return getAllByIndexSync(r'mintIndex_walletId', values); + } + + Future deleteAllByMintIndexWalletId( + List mintIndexValues, List walletIdValues) { + final len = mintIndexValues.length; + assert(walletIdValues.length == len, + 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([mintIndexValues[i], walletIdValues[i]]); + } + + return deleteAllByIndex(r'mintIndex_walletId', values); + } + + int deleteAllByMintIndexWalletIdSync( + List mintIndexValues, List walletIdValues) { + final len = mintIndexValues.length; + assert(walletIdValues.length == len, + 'All index values must have the same length'); + final values = >[]; + for (var i = 0; i < len; i++) { + values.add([mintIndexValues[i], walletIdValues[i]]); + } + + return deleteAllByIndexSync(r'mintIndex_walletId', values); + } + + Future putByMintIndexWalletId(LelantusCoin object) { + return putByIndex(r'mintIndex_walletId', object); + } + + Id putByMintIndexWalletIdSync(LelantusCoin object, {bool saveLinks = true}) { + return putByIndexSync(r'mintIndex_walletId', object, saveLinks: saveLinks); + } + + Future> putAllByMintIndexWalletId(List objects) { + return putAllByIndex(r'mintIndex_walletId', objects); + } + + List putAllByMintIndexWalletIdSync(List objects, + {bool saveLinks = true}) { + return putAllByIndexSync(r'mintIndex_walletId', objects, + saveLinks: saveLinks); + } } extension LelantusCoinQueryWhereSort @@ -552,6 +680,144 @@ extension LelantusCoinQueryWhere } }); } + + QueryBuilder + mintIndexEqualToAnyWalletId(int mintIndex) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'mintIndex_walletId', + value: [mintIndex], + )); + }); + } + + QueryBuilder + mintIndexNotEqualToAnyWalletId(int mintIndex) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [], + upper: [mintIndex], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [mintIndex], + includeLower: false, + upper: [], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [mintIndex], + includeLower: false, + upper: [], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [], + upper: [mintIndex], + includeUpper: false, + )); + } + }); + } + + QueryBuilder + mintIndexGreaterThanAnyWalletId( + int mintIndex, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [mintIndex], + includeLower: include, + upper: [], + )); + }); + } + + QueryBuilder + mintIndexLessThanAnyWalletId( + int mintIndex, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [], + upper: [mintIndex], + includeUpper: include, + )); + }); + } + + QueryBuilder + mintIndexBetweenAnyWalletId( + int lowerMintIndex, + int upperMintIndex, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [lowerMintIndex], + includeLower: includeLower, + upper: [upperMintIndex], + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder + mintIndexWalletIdEqualTo(int mintIndex, String walletId) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'mintIndex_walletId', + value: [mintIndex, walletId], + )); + }); + } + + QueryBuilder + mintIndexEqualToWalletIdNotEqualTo(int mintIndex, String walletId) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [mintIndex], + upper: [mintIndex, walletId], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [mintIndex, walletId], + includeLower: false, + upper: [mintIndex], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [mintIndex, walletId], + includeLower: false, + upper: [mintIndex], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'mintIndex_walletId', + lower: [mintIndex], + upper: [mintIndex, walletId], + includeUpper: false, + )); + } + }); + } } extension LelantusCoinQueryFilter @@ -665,60 +931,16 @@ extension LelantusCoinQueryFilter }); } - QueryBuilder indexEqualTo( - int value) { + QueryBuilder + isJMintEqualTo(bool value) { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(FilterCondition.equalTo( - property: r'index', + property: r'isJMint', value: value, )); }); } - QueryBuilder - indexGreaterThan( - int value, { - bool include = false, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.greaterThan( - include: include, - property: r'index', - value: value, - )); - }); - } - - QueryBuilder indexLessThan( - int value, { - bool include = false, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.lessThan( - include: include, - property: r'index', - value: value, - )); - }); - } - - QueryBuilder indexBetween( - int lower, - int upper, { - bool includeLower = true, - bool includeUpper = true, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.between( - property: r'index', - lower: lower, - includeLower: includeLower, - upper: upper, - includeUpper: includeUpper, - )); - }); - } - QueryBuilder isUsedEqualTo( bool value) { return QueryBuilder.apply(this, (query) { @@ -729,6 +951,216 @@ extension LelantusCoinQueryFilter }); } + QueryBuilder + mintIndexEqualTo(int value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'mintIndex', + value: value, + )); + }); + } + + QueryBuilder + mintIndexGreaterThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'mintIndex', + value: value, + )); + }); + } + + QueryBuilder + mintIndexLessThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'mintIndex', + value: value, + )); + }); + } + + QueryBuilder + mintIndexBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'mintIndex', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder + otherDataIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'otherData', + )); + }); + } + + QueryBuilder + otherDataIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'otherData', + )); + }); + } + + QueryBuilder + otherDataEqualTo( + String? value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'otherData', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + otherDataGreaterThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'otherData', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + otherDataLessThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'otherData', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + otherDataBetween( + String? lower, + String? upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'otherData', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + otherDataStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'otherData', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + otherDataEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'otherData', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + otherDataContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'otherData', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + otherDataMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'otherData', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder + otherDataIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'otherData', + value: '', + )); + }); + } + + QueryBuilder + otherDataIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'otherData', + value: '', + )); + }); + } + QueryBuilder publicCoinEqualTo( String value, { @@ -1292,15 +1724,15 @@ extension LelantusCoinQuerySortBy }); } - QueryBuilder sortByIndex() { + QueryBuilder sortByIsJMint() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'index', Sort.asc); + return query.addSortBy(r'isJMint', Sort.asc); }); } - QueryBuilder sortByIndexDesc() { + QueryBuilder sortByIsJMintDesc() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'index', Sort.desc); + return query.addSortBy(r'isJMint', Sort.desc); }); } @@ -1316,6 +1748,30 @@ extension LelantusCoinQuerySortBy }); } + QueryBuilder sortByMintIndex() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'mintIndex', Sort.asc); + }); + } + + QueryBuilder sortByMintIndexDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'mintIndex', Sort.desc); + }); + } + + QueryBuilder sortByOtherData() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'otherData', Sort.asc); + }); + } + + QueryBuilder sortByOtherDataDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'otherData', Sort.desc); + }); + } + QueryBuilder sortByPublicCoin() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'publicCoin', Sort.asc); @@ -1394,15 +1850,15 @@ extension LelantusCoinQuerySortThenBy }); } - QueryBuilder thenByIndex() { + QueryBuilder thenByIsJMint() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'index', Sort.asc); + return query.addSortBy(r'isJMint', Sort.asc); }); } - QueryBuilder thenByIndexDesc() { + QueryBuilder thenByIsJMintDesc() { return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'index', Sort.desc); + return query.addSortBy(r'isJMint', Sort.desc); }); } @@ -1418,6 +1874,30 @@ extension LelantusCoinQuerySortThenBy }); } + QueryBuilder thenByMintIndex() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'mintIndex', Sort.asc); + }); + } + + QueryBuilder thenByMintIndexDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'mintIndex', Sort.desc); + }); + } + + QueryBuilder thenByOtherData() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'otherData', Sort.asc); + }); + } + + QueryBuilder thenByOtherDataDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'otherData', Sort.desc); + }); + } + QueryBuilder thenByPublicCoin() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'publicCoin', Sort.asc); @@ -1477,9 +1957,9 @@ extension LelantusCoinQueryWhereDistinct }); } - QueryBuilder distinctByIndex() { + QueryBuilder distinctByIsJMint() { return QueryBuilder.apply(this, (query) { - return query.addDistinctBy(r'index'); + return query.addDistinctBy(r'isJMint'); }); } @@ -1489,6 +1969,19 @@ extension LelantusCoinQueryWhereDistinct }); } + QueryBuilder distinctByMintIndex() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'mintIndex'); + }); + } + + QueryBuilder distinctByOtherData( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'otherData', caseSensitive: caseSensitive); + }); + } + QueryBuilder distinctByPublicCoin( {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { @@ -1532,9 +2025,9 @@ extension LelantusCoinQueryProperty }); } - QueryBuilder indexProperty() { + QueryBuilder isJMintProperty() { return QueryBuilder.apply(this, (query) { - return query.addPropertyName(r'index'); + return query.addPropertyName(r'isJMint'); }); } @@ -1544,6 +2037,18 @@ extension LelantusCoinQueryProperty }); } + QueryBuilder mintIndexProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'mintIndex'); + }); + } + + QueryBuilder otherDataProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'otherData'); + }); + } + QueryBuilder publicCoinProperty() { return QueryBuilder.apply(this, (query) { return query.addPropertyName(r'publicCoin'); diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 004e5399c..67882a6b6 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -269,18 +269,20 @@ Future> isolateRestore( lelantusCoins.removeWhere((e) => e.txid == txId && - e.index == currentIndex && + e.mintIndex == currentIndex && e.anonymitySetId != setId); lelantusCoins.add( isar_models.LelantusCoin( walletId: walletId, - index: currentIndex, + mintIndex: currentIndex, value: amount.toString(), publicCoin: publicCoin, txid: txId, anonymitySetId: setId, isUsed: isUsed, + isJMint: false, + otherData: null, ), ); Logging.instance.log( @@ -317,18 +319,20 @@ Future> isolateRestore( bool isUsed = usedSerialNumbersSet.contains(serialNumber); lelantusCoins.removeWhere((e) => e.txid == txId && - e.index == currentIndex && + e.mintIndex == currentIndex && e.anonymitySetId != setId); lelantusCoins.add( isar_models.LelantusCoin( walletId: walletId, - index: currentIndex, + mintIndex: currentIndex, value: amount.toString(), publicCoin: publicCoin, txid: txId, anonymitySetId: setId, isUsed: isUsed, + isJMint: true, + otherData: null, ), ); jindexes.add(currentIndex); @@ -2325,7 +2329,7 @@ class FiroWallet extends CoinServiceAPI final derivePath = constructDerivePath( networkWIF: _network.wif, chain: MINT_INDEX, - index: coin.index, + index: coin.mintIndex, ); final keyPair = await Bip32Utils.getBip32NodeFromRoot(root, derivePath); @@ -2335,7 +2339,7 @@ class FiroWallet extends CoinServiceAPI } final String privateKey = Format.uint8listToString(keyPair.privateKey!); return DartLelantusEntry(coin.isUsed ? 1 : 0, 0, coin.anonymitySetId, - int.parse(coin.value), coin.index, privateKey); + int.parse(coin.value), coin.mintIndex, privateKey); }).toList(); final lelantusEntries = await Future.wait(waitLelantusEntries); @@ -3054,12 +3058,14 @@ class FiroWallet extends CoinServiceAPI // if a jmint was made add it to the unspent coin index final jmint = isar_models.LelantusCoin( walletId: walletId, - index: index, + mintIndex: nextFreeMintIndex, value: (transactionInfo['jmintValue'] as int? ?? 0).toString(), publicCoin: transactionInfo['publicCoin'] as String, txid: transactionInfo['txid'] as String, anonymitySetId: latestSetId, isUsed: false, + isJMint: true, + otherData: null, ); if (int.parse(jmint.value) > 0) { updatedCoins.add(jmint); @@ -3143,12 +3149,14 @@ class FiroWallet extends CoinServiceAPI final index = mintMap['index'] as int; final mint = isar_models.LelantusCoin( walletId: walletId, - index: index, + mintIndex: index, value: (mintMap['value'] as int).toString(), publicCoin: mintMap['publicCoin'] as String, txid: transactionInfo['txid'] as String, anonymitySetId: latestSetId, isUsed: false, + isJMint: false, + otherData: null, ); if (int.parse(mint.value) > 0) { updatedCoins.add(mint); diff --git a/lib/utilities/db_version_migration.dart b/lib/utilities/db_version_migration.dart index dac1dbe82..d2c0adbe8 100644 --- a/lib/utilities/db_version_migration.dart +++ b/lib/utilities/db_version_migration.dart @@ -386,19 +386,28 @@ class DbVersionMigrator with WalletDB { ) as List? ?? []; + final jindexes = (DB.instance + .get(boxName: walletId, key: "jindex") as List? ?? + []) + .cast(); + final List coins = []; for (final e in hiveLCoins) { final map = e as Map; final lcoin = map.values.first as LelantusCoin; + final isJMint = jindexes.contains(lcoin.index); + final coin = isar_models.LelantusCoin( walletId: walletId, publicCoin: lcoin.publicCoin, txid: lcoin.txId, value: lcoin.value.toString(), - index: lcoin.index, + mintIndex: lcoin.index, anonymitySetId: lcoin.anonymitySetId, isUsed: lcoin.isUsed, + isJMint: isJMint, + otherData: null, ); coins.add(coin); diff --git a/test/services/coins/manager_test.mocks.dart b/test/services/coins/manager_test.mocks.dart index 8b48a38a9..25fd46d9d 100644 --- a/test/services/coins/manager_test.mocks.dart +++ b/test/services/coins/manager_test.mocks.dart @@ -14,7 +14,6 @@ import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i5; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i4; import 'package:stackwallet/models/balance.dart' as _i6; import 'package:stackwallet/models/isar/models/isar_models.dart' as _i13; -import 'package:stackwallet/models/lelantus_coin.dart' as _i15; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i3; import 'package:stackwallet/models/signing_data.dart' as _i14; import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as _i10; @@ -589,15 +588,6 @@ class MockFiroWallet extends _i1.Mock implements _i10.FiroWallet { returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); @override - List> getLelantusCoinMap() => - (super.noSuchMethod( - Invocation.method( - #getLelantusCoinMap, - [], - ), - returnValue: >[], - ) as List>); - @override _i11.Future anonymizeAllPublicFunds() => (super.noSuchMethod( Invocation.method( #anonymizeAllPublicFunds, @@ -1061,51 +1051,6 @@ class MockFiroWallet extends _i1.Mock implements _i10.FiroWallet { ), returnValueForMissingStub: null, ); - @override - void initFiroHive(String? walletId) => super.noSuchMethod( - Invocation.method( - #initFiroHive, - [walletId], - ), - returnValueForMissingStub: null, - ); - @override - _i11.Future firoUpdateJIndex(List? jIndex) => - (super.noSuchMethod( - Invocation.method( - #firoUpdateJIndex, - [jIndex], - ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); - @override - _i11.Future firoUpdateLelantusCoins(List? lelantusCoins) => - (super.noSuchMethod( - Invocation.method( - #firoUpdateLelantusCoins, - [lelantusCoins], - ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); - @override - int firoGetMintIndex() => (super.noSuchMethod( - Invocation.method( - #firoGetMintIndex, - [], - ), - returnValue: 0, - ) as int); - @override - _i11.Future firoUpdateMintIndex(int? mintIndex) => (super.noSuchMethod( - Invocation.method( - #firoUpdateMintIndex, - [mintIndex], - ), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) as _i11.Future); } /// A class which mocks [ElectrumX]. diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart index 4fc6f8832..29bd7bd29 100644 --- a/test/widget_tests/transaction_card_test.mocks.dart +++ b/test/widget_tests/transaction_card_test.mocks.dart @@ -1602,15 +1602,6 @@ class MockFiroWallet extends _i1.Mock implements _i23.FiroWallet { returnValueForMissingStub: _i19.Future.value(), ) as _i19.Future); @override - List> getLelantusCoinMap() => - (super.noSuchMethod( - Invocation.method( - #getLelantusCoinMap, - [], - ), - returnValue: >[], - ) as List>); - @override _i19.Future anonymizeAllPublicFunds() => (super.noSuchMethod( Invocation.method( #anonymizeAllPublicFunds, @@ -2075,51 +2066,6 @@ class MockFiroWallet extends _i1.Mock implements _i23.FiroWallet { ), returnValueForMissingStub: null, ); - @override - void initFiroHive(String? walletId) => super.noSuchMethod( - Invocation.method( - #initFiroHive, - [walletId], - ), - returnValueForMissingStub: null, - ); - @override - _i19.Future firoUpdateJIndex(List? jIndex) => - (super.noSuchMethod( - Invocation.method( - #firoUpdateJIndex, - [jIndex], - ), - returnValue: _i19.Future.value(), - returnValueForMissingStub: _i19.Future.value(), - ) as _i19.Future); - @override - _i19.Future firoUpdateLelantusCoins(List? lelantusCoins) => - (super.noSuchMethod( - Invocation.method( - #firoUpdateLelantusCoins, - [lelantusCoins], - ), - returnValue: _i19.Future.value(), - returnValueForMissingStub: _i19.Future.value(), - ) as _i19.Future); - @override - int firoGetMintIndex() => (super.noSuchMethod( - Invocation.method( - #firoGetMintIndex, - [], - ), - returnValue: 0, - ) as int); - @override - _i19.Future firoUpdateMintIndex(int? mintIndex) => (super.noSuchMethod( - Invocation.method( - #firoUpdateMintIndex, - [mintIndex], - ), - returnValue: _i19.Future.value(), - returnValueForMissingStub: _i19.Future.value(), - ) as _i19.Future); } /// A class which mocks [LocaleService]. From 2fb94444c46965c34d5adcaaa9257fda649a718a Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 24 Jul 2023 16:49:11 -0600 Subject: [PATCH 50/80] no more firo specific hive --- lib/services/coins/firo/firo_wallet.dart | 322 ++++++++++------------- lib/services/mixins/firo_hive.dart | 61 ----- 2 files changed, 145 insertions(+), 238 deletions(-) delete mode 100644 lib/services/mixins/firo_hive.dart diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 67882a6b6..a5a7b3b47 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -35,7 +35,6 @@ import 'package:stackwallet/services/event_bus/events/global/refresh_percent_cha import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; -import 'package:stackwallet/services/mixins/firo_hive.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/mixins/xpubable.dart'; @@ -752,7 +751,7 @@ Future _setTestnetWrapper(bool isTestnet) async { /// Handles a single instance of a firo wallet class FiroWallet extends CoinServiceAPI - with WalletCache, WalletDB, FiroHive + with WalletCache, WalletDB implements XPubAble { // Constructor FiroWallet({ @@ -773,7 +772,6 @@ class FiroWallet extends CoinServiceAPI _cachedElectrumXClient = cachedClient; _secureStore = secureStore; initCache(walletId, coin); - initFiroHive(walletId); initWalletDB(mockableOverride: mockableOverride); Logging.instance.log("$walletName isolates length: ${isolates.length}", @@ -2181,7 +2179,6 @@ class FiroWallet extends CoinServiceAPI value: "", ); - await firoUpdateJIndex([]); // Generate and add addresses to relevant arrays final initialReceivingAddress = await _generateAddressForChain(0, 0); final initialChangeAddress = await _generateAddressForChain(1, 0); @@ -2352,57 +2349,60 @@ class FiroWallet extends CoinServiceAPI } Future> _getUnspentCoins() async { - final jindexes = firoGetJIndex() ?? []; + // final jindexes = firoGetJIndex() ?? []; final lelantusCoinsList = await db.isar.lelantusCoins .where() .walletIdEqualTo(walletId) .filter() + .isUsedEqualTo(false) // TODO add this? .not() .valueEqualTo("0") .findAll(); - List coins = []; + return lelantusCoinsList; - final currentChainHeight = await chainHeight; - - for (int i = 0; i < lelantusCoinsList.length; i++) { - // Logging.instance.log("lelantusCoinsList[$i]: ${lelantusCoinsList[i]}"); - final coin = lelantusCoinsList[i]; - - final tx = await db.getTransaction(walletId, coin.txid); - - // TODO check if sane default - bool isUnconfirmed = false; - - if (tx != null) { - bool isConfirmed = tx.isConfirmed( - currentChainHeight, - MINIMUM_CONFIRMATIONS, - ); - if (!jindexes.contains(coin.index) && - tx.isLelantus == true && - !isConfirmed) { - isUnconfirmed = true; - } else if (!isConfirmed) { - continue; - } - } else { - final txn = await cachedElectrumXClient.getTransaction( - txHash: coin.txid, - verbose: true, - coin: this.coin, - ); - final confirmations = txn["confirmations"]; - isUnconfirmed = confirmations is int && confirmations < 1; - } - if (!coin.isUsed && - coin.anonymitySetId != ANONYMITY_SET_EMPTY_ID && - !isUnconfirmed) { - coins.add(coin); - } - } - return coins; + // List coins = []; + // + // final currentChainHeight = await chainHeight; + // + // for (int i = 0; i < lelantusCoinsList.length; i++) { + // // Logging.instance.log("lelantusCoinsList[$i]: ${lelantusCoinsList[i]}"); + // final coin = lelantusCoinsList[i]; + // + // final tx = await db.getTransaction(walletId, coin.txid); + // + // // TODO check if sane default + // bool isUnconfirmed = false; + // + // if (tx != null) { + // bool isConfirmed = tx.isConfirmed( + // currentChainHeight, + // MINIMUM_CONFIRMATIONS, + // ); + // if (!jindexes.contains(coin.index) && + // tx.isLelantus == true && + // !isConfirmed) { + // isUnconfirmed = true; + // } else if (!isConfirmed) { + // continue; + // } + // } else { + // final txn = await cachedElectrumXClient.getTransaction( + // txHash: coin.txid, + // verbose: true, + // coin: this.coin, + // ); + // final confirmations = txn["confirmations"]; + // isUnconfirmed = confirmations is int && confirmations < 1; + // } + // if (!coin.isUsed && + // coin.anonymitySetId != ANONYMITY_SET_EMPTY_ID && + // !isUnconfirmed) { + // coins.add(coin); + // } + // } + // return coins; } // index 0 and 1 for the funds available to spend. @@ -2415,12 +2415,12 @@ class FiroWallet extends CoinServiceAPI .where() .walletIdEqualTo(walletId) .filter() + .isUsedEqualTo(false) .not() .valueEqualTo(0.toString()) .findAll(); final currentChainHeight = await chainHeight; - final jindexes = firoGetJIndex(); int intLelantusBalance = 0; int unconfirmedLelantusBalance = 0; @@ -2440,33 +2440,17 @@ class FiroWallet extends CoinServiceAPI level: LogLevel.Fatal, ); } else { - bool isLelantus = txn.isLelantus == true; - if (!jindexes!.contains(lelantusCoin.index) && isLelantus) { - if (!lelantusCoin.isUsed && - txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { - // mint tx, add value to balance - intLelantusBalance += int.parse(lelantusCoin.value); - } /* else { - // This coin is not confirmed and may be replaced - }*/ - } else if (jindexes.contains(lelantusCoin.index) && - isLelantus && - !lelantusCoin.isUsed && - !txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { - unconfirmedLelantusBalance += int.parse(lelantusCoin.value); - } else if (jindexes.contains(lelantusCoin.index) && - !lelantusCoin.isUsed) { + if (txn.isLelantus != true) { + Logging.instance.log( + "Bad database state found in $walletName $walletId for _refreshBalance lelantus", + level: LogLevel.Fatal, + ); + } + + if (txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { + // mint tx, add value to balance intLelantusBalance += int.parse(lelantusCoin.value); - } else if (!lelantusCoin.isUsed && - (txn.isLelantus == true - ? true - : txn.isConfirmed( - currentChainHeight, MINIMUM_CONFIRMATIONS) != - false)) { - intLelantusBalance += int.parse(lelantusCoin.value); - } else if (!isLelantus && - txn.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS) == - false) { + } else { unconfirmedLelantusBalance += int.parse(lelantusCoin.value); } } @@ -2615,10 +2599,16 @@ class FiroWallet extends CoinServiceAPI } Future>> createMintsFromAmount(int total) async { - var tmpTotal = total; - var index = 1; - var mints = >[]; - final nextFreeMintIndex = firoGetMintIndex(); + int tmpTotal = total; + int index = 0; + final mints = >[]; + final lastUsedIndex = await db.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .sortByMintIndexDesc() + .mintIndexProperty() + .findFirst(); + final nextFreeMintIndex = (lastUsedIndex ?? 0) + 1; while (tmpTotal > 0) { final mintValue = min(tmpTotal, MINT_LIMIT); final mint = await _getMintHex( @@ -2783,9 +2773,6 @@ class FiroWallet extends CoinServiceAPI amount += utxosToUse[i].value; } - final index = firoGetMintIndex(); - Logging.instance.log("index of mint $index", level: LogLevel.Info); - for (var mintsElement in mintsMap) { Logging.instance.log("using $mintsElement", level: LogLevel.Info); Uint8List mintu8 = @@ -2837,45 +2824,39 @@ class FiroWallet extends CoinServiceAPI .where() .walletIdEqualTo(walletId) .filter() + .isUsedEqualTo(false) + .and() + .isJMintEqualTo(true) .not() .valueEqualTo(0.toString()) .findAll(); - final jindexes = firoGetJIndex(); - // Get all joinsplit transaction ids - final listLelantusTxData = await db + final lelantusJoinSplitTxns = await db .getTransactions(walletId) .filter() .isLelantusEqualTo(true) + .and() + .subTypeEqualTo(isar_models.TransactionSubType.join) .findAll(); - List joinsplits = []; - for (final tx in listLelantusTxData) { - if (tx.subType == isar_models.TransactionSubType.join) { - joinsplits.add(tx.txid); - } - } + Set joinSplitTXIDs = {}; + + // for (final tx in lelantusJoinSplitTxns) { + // joinSplitTXIDs.add(tx.txid); + // } for (final coin in lelantusCoins) { - if (jindexes != null) { - if (jindexes.contains(coin.index) && !joinsplits.contains(coin.txid)) { - joinsplits.add(coin.txid); - } - } + joinSplitTXIDs.add(coin.txid); } - Map> data = - {}; - for (final entry in listLelantusTxData) { - data[entry.txid] = Tuple2(entry.address.value, entry); - } + Map> + updatedData = {}; // Grab the most recent information on all the joinsplits - final updatedJSplit = await getJMintTransactions( cachedElectrumXClient, - joinsplits, + joinSplitTXIDs.toList(), coin, ); @@ -2887,7 +2868,7 @@ class FiroWallet extends CoinServiceAPI try { currentTx = - listLelantusTxData.firstWhere((e) => e.txid == tx.value.txid); + lelantusJoinSplitTxns.firstWhere((e) => e.txid == tx.value.txid); } catch (_) { currentTx = null; } @@ -2895,54 +2876,23 @@ class FiroWallet extends CoinServiceAPI if (currentTx == null) { // this send was accidentally not included in the list tx.value.isLelantus = true; - data[tx.value.txid] = + updatedData[tx.value.txid] = Tuple2(tx.value.address.value ?? tx.key, tx.value); - - continue; - } - if (currentTx.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS) != + } else if (currentTx.isConfirmed( + currentChainHeight, MINIMUM_CONFIRMATIONS) != tx.value.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { tx.value.isLelantus = true; - data[tx.value.txid] = + updatedData[tx.value.txid] = Tuple2(tx.value.address.value ?? tx.key, tx.value); } } - // Logging.instance.log(txData.txChunks); - final listTxData = await _txnData; - for (final value in listTxData) { - // ignore change addresses - // bool hasAtLeastOneReceive = false; - // int howManyReceiveInputs = 0; - // for (var element in value.inputs) { - // if (listLelantusTxData.containsKey(element.txid) && - // listLelantusTxData[element.txid]!.txType == "Received" - // // && - // // listLelantusTxData[element.txid].subType != "mint" - // ) { - // // hasAtLeastOneReceive = true; - // // howManyReceiveInputs++; - // } - // } - - if (value.type == isar_models.TransactionType.incoming && - value.subType != isar_models.TransactionSubType.mint) { - // Every receive other than a mint should be shown. Mints will be collected and shown from the send side - value.isLelantus = true; - data[value.txid] = Tuple2(value.address.value, value); - } else if (value.type == isar_models.TransactionType.outgoing) { - // all sends should be shown, mints will be displayed correctly in the ui - value.isLelantus = true; - data[value.txid] = Tuple2(value.address.value, value); - } - } - // TODO: optimize this whole lelantus process final List> txnsData = []; - for (final value in data.values) { + for (final value in updatedData.values) { // allow possible null address on mints as we don't display address // this should normally never be null anyways but old (dbVersion up to 4) // migrated transactions may not have had an address (full rescan should @@ -2967,15 +2917,6 @@ class FiroWallet extends CoinServiceAPI } await db.addNewTransactionData(txnsData, walletId); - - // // update the _lelantusTransactionData - // final models.TransactionData newTxData = - // models.TransactionData.fromMap(listLelantusTxData); - // // Logging.instance.log(newTxData.txChunks); - // _lelantusTransactionData = Future(() => newTxData); - // await DB.instance.put( - // boxName: walletId, key: 'latest_lelantus_tx_model', value: newTxData); - // return newTxData; } Future _getMintHex(int amount, int index) async { @@ -3025,7 +2966,13 @@ class FiroWallet extends CoinServiceAPI level: LogLevel.Info); if (txid == transactionInfo['txid']) { - final index = firoGetMintIndex(); + final lastUsedIndex = await db.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .sortByMintIndexDesc() + .mintIndexProperty() + .findFirst(); + final nextFreeMintIndex = (lastUsedIndex ?? 0) + 1; if (transactionInfo['spendCoinIndexes'] != null) { // This is a joinsplit @@ -3041,7 +2988,7 @@ class FiroWallet extends CoinServiceAPI .where() .walletIdEqualTo(walletId) .filter() - .indexEqualTo(index) + .mintIndexEqualTo(index) .findAll(); if (possibleCoins.isNotEmpty) { @@ -3069,22 +3016,26 @@ class FiroWallet extends CoinServiceAPI ); if (int.parse(jmint.value) > 0) { updatedCoins.add(jmint); - final jindexes = firoGetJIndex()!; - jindexes.add(index); - await firoUpdateJIndex(jindexes); - await firoUpdateMintIndex(index + 1); } - await db.isar.writeTxn(() async { - for (final c in updatedCoins) { - await db.isar.lelantusCoins.deleteByPublicCoinWalletIdTxid( - c.publicCoin, - c.walletId, - c.txid, - ); - } - await db.isar.lelantusCoins.putAll(updatedCoins); - }); + try { + await db.isar.writeTxn(() async { + for (final c in updatedCoins) { + await db.isar.lelantusCoins.deleteByPublicCoinWalletIdTxid( + c.publicCoin, + c.walletId, + c.txid, + ); + } + await db.isar.lelantusCoins.putAll(updatedCoins); + }); + } catch (e, s) { + Logging.instance.log( + "$e\n$s", + level: LogLevel.Fatal, + ); + rethrow; + } final amount = Amount.fromDecimal( Decimal.parse(transactionInfo["amount"].toString()), @@ -3160,13 +3111,20 @@ class FiroWallet extends CoinServiceAPI ); if (int.parse(mint.value) > 0) { updatedCoins.add(mint); - await firoUpdateMintIndex(index + 1); } } // Logging.instance.log(coins); - await db.isar.writeTxn(() async { - await db.isar.lelantusCoins.putAll(updatedCoins); - }); + try { + await db.isar.writeTxn(() async { + await db.isar.lelantusCoins.putAll(updatedCoins); + }); + } catch (e, s) { + Logging.instance.log( + "$e\n$s", + level: LogLevel.Fatal, + ); + rethrow; + } } return true; } else { @@ -3933,7 +3891,6 @@ class FiroWallet extends CoinServiceAPI coin: coin, ); - // todo check here if we should mark as blocked final utxo = isar_models.UTXO( walletId: walletId, txid: txn["txid"] as String, @@ -4586,14 +4543,19 @@ class FiroWallet extends CoinServiceAPI await chainHeight, ); - await Future.wait([ - firoUpdateMintIndex(message['mintIndex'] as int), - db.isar.writeTxn(() async { - await db.isar.lelantusCoins.putAll( - message['_lelantus_coins'] as List); - }), - firoUpdateJIndex(message['jindex'] as List), - ]); + final coins = message['_lelantus_coins'] as List; + + try { + await db.isar.writeTxn(() async { + await db.isar.lelantusCoins.putAll(coins); + }); + } catch (e, s) { + Logging.instance.log( + "$e\n$s", + level: LogLevel.Fatal, + ); + rethrow; + } final transactionMap = message["newTxMap"] as Map; @@ -4677,7 +4639,13 @@ class FiroWallet extends CoinServiceAPI int spendAmount, String address, bool subtractFeeFromAmount) async { final _mnemonic = await mnemonicString; final _mnemonicPassphrase = await mnemonicPassphrase; - final index = firoGetMintIndex(); + final lastUsedIndex = await db.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .sortByMintIndexDesc() + .mintIndexProperty() + .findFirst(); + final nextFreeMintIndex = (lastUsedIndex ?? 0) + 1; final lelantusEntry = await _getLelantusEntry(); final anonymitySets = await fetchAnonymitySets(); final locktime = await getBlockHead(electrumXClient); @@ -4691,7 +4659,7 @@ class FiroWallet extends CoinServiceAPI "subtractFeeFromAmount": subtractFeeFromAmount, "mnemonic": _mnemonic, "mnemonicPassphrase": _mnemonicPassphrase, - "index": index, + "index": nextFreeMintIndex, // "price": price, "lelantusEntries": lelantusEntry, "locktime": locktime, diff --git a/lib/services/mixins/firo_hive.dart b/lib/services/mixins/firo_hive.dart deleted file mode 100644 index 631aebe6d..000000000 --- a/lib/services/mixins/firo_hive.dart +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Stack Wallet. - * - * Copyright (c) 2023 Cypher Stack - * All Rights Reserved. - * The code is distributed under GPLv3 license, see LICENSE file for details. - * Generated by Cypher Stack on 2023-05-26 - * - */ - -import 'package:stackwallet/db/hive/db.dart'; - -mixin FiroHive { - late final String _walletId; - - void initFiroHive(String walletId) { - _walletId = walletId; - } - - // jindex - List? firoGetJIndex() { - return DB.instance.get(boxName: _walletId, key: "jindex") as List?; - } - - Future firoUpdateJIndex(List jIndex) async { - await DB.instance.put( - boxName: _walletId, - key: "jindex", - value: jIndex, - ); - } - - // // _lelantus_coins - // List? firoGetLelantusCoins() { - // return DB.instance.get(boxName: _walletId, key: "_lelantus_coins") - // as List?; - // } - // - // Future firoUpdateLelantusCoins(List lelantusCoins) async { - // await DB.instance.put( - // boxName: _walletId, - // key: "_lelantus_coins", - // value: lelantusCoins, - // ); - // } - - // mintIndex - int firoGetMintIndex() { - return DB.instance.get(boxName: _walletId, key: "mintIndex") - as int? ?? - 0; - } - - Future firoUpdateMintIndex(int mintIndex) async { - await DB.instance.put( - boxName: _walletId, - key: "mintIndex", - value: mintIndex, - ); - } -} From 462b845bd40b1f448d86d75e366363e53d459512 Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 24 Jul 2023 16:54:38 -0600 Subject: [PATCH 51/80] clean up unspent coins --- lib/services/coins/firo/firo_wallet.dart | 51 +++--------------------- 1 file changed, 5 insertions(+), 46 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index a5a7b3b47..fe1956ce9 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -2349,60 +2349,19 @@ class FiroWallet extends CoinServiceAPI } Future> _getUnspentCoins() async { - // final jindexes = firoGetJIndex() ?? []; - final lelantusCoinsList = await db.isar.lelantusCoins .where() .walletIdEqualTo(walletId) .filter() - .isUsedEqualTo(false) // TODO add this? + .isUsedEqualTo(false) .not() - .valueEqualTo("0") + .group((q) => q + .valueEqualTo("0") + .or() + .anonymitySetIdEqualTo(ANONYMITY_SET_EMPTY_ID)) .findAll(); return lelantusCoinsList; - - // List coins = []; - // - // final currentChainHeight = await chainHeight; - // - // for (int i = 0; i < lelantusCoinsList.length; i++) { - // // Logging.instance.log("lelantusCoinsList[$i]: ${lelantusCoinsList[i]}"); - // final coin = lelantusCoinsList[i]; - // - // final tx = await db.getTransaction(walletId, coin.txid); - // - // // TODO check if sane default - // bool isUnconfirmed = false; - // - // if (tx != null) { - // bool isConfirmed = tx.isConfirmed( - // currentChainHeight, - // MINIMUM_CONFIRMATIONS, - // ); - // if (!jindexes.contains(coin.index) && - // tx.isLelantus == true && - // !isConfirmed) { - // isUnconfirmed = true; - // } else if (!isConfirmed) { - // continue; - // } - // } else { - // final txn = await cachedElectrumXClient.getTransaction( - // txHash: coin.txid, - // verbose: true, - // coin: this.coin, - // ); - // final confirmations = txn["confirmations"]; - // isUnconfirmed = confirmations is int && confirmations < 1; - // } - // if (!coin.isUsed && - // coin.anonymitySetId != ANONYMITY_SET_EMPTY_ID && - // !isUnconfirmed) { - // coins.add(coin); - // } - // } - // return coins; } // index 0 and 1 for the funds available to spend. From 18f3a2056c382a9a31446d8be81135d367e0c4f1 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 08:55:50 -0600 Subject: [PATCH 52/80] check anon set when creating list of mints --- lib/services/coins/firo/firo_wallet.dart | 89 ++++++++++++++++++++---- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index fe1956ce9..331b5b519 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -2559,8 +2559,7 @@ class FiroWallet extends CoinServiceAPI Future>> createMintsFromAmount(int total) async { int tmpTotal = total; - int index = 0; - final mints = >[]; + int counter = 0; final lastUsedIndex = await db.isar.lelantusCoins .where() .walletIdEqualTo(walletId) @@ -2568,20 +2567,82 @@ class FiroWallet extends CoinServiceAPI .mintIndexProperty() .findFirst(); final nextFreeMintIndex = (lastUsedIndex ?? 0) + 1; + + final root = await Bip32Utils.getBip32Root( + (await mnemonic).join(" "), + (await mnemonicPassphrase)!, + _network, + ); + + final mints = >[]; while (tmpTotal > 0) { - final mintValue = min(tmpTotal, MINT_LIMIT); - final mint = await _getMintHex( - mintValue, - nextFreeMintIndex + index, + final index = nextFreeMintIndex + counter; + + final bip32.BIP32 mintKeyPair = await Bip32Utils.getBip32NodeFromRoot( + root, + constructDerivePath( + networkWIF: _network.wif, + chain: MINT_INDEX, + index: index, + ), ); - mints.add({ - "value": mintValue, - "script": mint, - "index": nextFreeMintIndex + index, - "publicCoin": "", - }); - tmpTotal = tmpTotal - MINT_LIMIT; - index++; + + final String mintTag = CreateTag( + Format.uint8listToString(mintKeyPair.privateKey!), + index, + Format.uint8listToString(mintKeyPair.identifier), + isTestnet: coin == Coin.firoTestNet, + ); + final List> anonymitySets; + try { + anonymitySets = await fetchAnonymitySets(); + } catch (e, s) { + Logging.instance.log( + "Firo needs better internet to create mints: $e\n$s", + level: LogLevel.Fatal, + ); + rethrow; + } + + bool isUsedMintTag = false; + + // stupid dynamic maps + for (final set in anonymitySets) { + final setCoins = set["coins"] as List; + for (final coin in setCoins) { + if (coin[1] == mintTag) { + isUsedMintTag = true; + break; + } + } + if (isUsedMintTag) { + break; + } + } + + if (isUsedMintTag) { + Logging.instance.log( + "Found used index when minting", + level: LogLevel.Warning, + ); + } + + if (!isUsedMintTag) { + final mintValue = min(tmpTotal, MINT_LIMIT); + final mint = await _getMintHex( + mintValue, + index, + ); + mints.add({ + "value": mintValue, + "script": mint, + "index": index, + "publicCoin": "", + }); + tmpTotal = tmpTotal - MINT_LIMIT; + } + + counter++; } return mints; } From 99a36f158731fad192f7c30bc59ba64dfd671479 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 09:03:26 -0600 Subject: [PATCH 53/80] fix mint limit constant --- lib/services/coins/firo/firo_wallet.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 331b5b519..b02816497 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -58,8 +58,8 @@ import 'package:uuid/uuid.dart'; const DUST_LIMIT = 1000; const MINIMUM_CONFIRMATIONS = 1; -const MINT_LIMIT = 100100000000; -const int LELANTUS_VALUE_SPEND_LIMIT_PER_TRANSACTION = 5001 * 100000000; +const MINT_LIMIT = 5001 * 100000000; +const MINT_LIMIT_TESTNET = 1001 * 100000000; const JMINT_INDEX = 5; const MINT_INDEX = 2; @@ -2628,7 +2628,8 @@ class FiroWallet extends CoinServiceAPI } if (!isUsedMintTag) { - final mintValue = min(tmpTotal, MINT_LIMIT); + final mintValue = min(tmpTotal, + (coin == Coin.firoTestNet ? MINT_LIMIT_TESTNET : MINT_LIMIT)); final mint = await _getMintHex( mintValue, index, @@ -2639,7 +2640,8 @@ class FiroWallet extends CoinServiceAPI "index": index, "publicCoin": "", }); - tmpTotal = tmpTotal - MINT_LIMIT; + tmpTotal = tmpTotal - + (coin == Coin.firoTestNet ? MINT_LIMIT_TESTNET : MINT_LIMIT); } counter++; From 140f1468f9d3e243d80a128d65f305b3521b3d07 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 09:04:09 -0600 Subject: [PATCH 54/80] remove unused code --- lib/services/coins/firo/firo_wallet.dart | 69 ------------------------ 1 file changed, 69 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index b02816497..659a6d94b 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -4769,75 +4769,6 @@ class FiroWallet extends CoinServiceAPI this.isActive = isActive; }; - Future getCoinsToJoinSplit( - int required, - ) async { - List coins = await _getLelantusEntry(); - if (required > LELANTUS_VALUE_SPEND_LIMIT_PER_TRANSACTION) { - return false; - } - - int availableBalance = coins.fold( - 0, (previousValue, element) => previousValue + element.amount); - - if (required > availableBalance) { - return false; - } - - // sort by biggest amount. if it is same amount we will prefer the older block - coins.sort((a, b) => - (a.amount != b.amount ? a.amount > b.amount : a.height < b.height) - ? -1 - : 1); - int spendVal = 0; - - List coinsToSpend = []; - - while (spendVal < required) { - if (coins.isEmpty) { - break; - } - - DartLelantusEntry? chosen; - int need = required - spendVal; - - var itr = coins.first; - if (need >= itr.amount) { - chosen = itr; - coins.remove(itr); - } else { - for (int index = coins.length - 1; index != 0; index--) { - var coinIt = coins[index]; - var nextItr = coins[index - 1]; - - if (coinIt.amount >= need && - (index - 1 == 0 || nextItr.amount != coinIt.amount)) { - chosen = coinIt; - coins.remove(chosen); - break; - } - } - } - - // TODO: investigate the bug here where chosen is null, conditions, given one mint - spendVal += chosen!.amount; - coinsToSpend.insert(coinsToSpend.length, chosen); - } - - // sort by group id ay ascending order. it is mandatory for creating proper joinsplit - coinsToSpend.sort((a, b) => a.anonymitySetId < b.anonymitySetId ? 1 : -1); - - int changeToMint = spendVal - required; - List indices = []; - for (var l in coinsToSpend) { - indices.add(l.index); - } - List coinsToBeSpentOut = []; - coinsToBeSpentOut.addAll(coinsToSpend); - - return {"changeToMint": changeToMint, "coinsToSpend": coinsToBeSpentOut}; - } - Future estimateJoinSplitFee( int spendAmount, ) async { From a0b42226f1f9937e4bbbacc3e8f8e473e41e0636 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 10:39:23 -0600 Subject: [PATCH 55/80] fix test --- test/services/coins/firo/firo_wallet_test.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/services/coins/firo/firo_wallet_test.dart b/test/services/coins/firo/firo_wallet_test.dart index 68db15437..fcd7bd50e 100644 --- a/test/services/coins/firo/firo_wallet_test.dart +++ b/test/services/coins/firo/firo_wallet_test.dart @@ -72,6 +72,7 @@ void main() { setData, List.from(usedSerials), firoNetwork, + "walletId", ); const currentHeight = 100000000000; @@ -133,6 +134,7 @@ void main() { setData, List.from(usedSerials), firoNetwork, + "walletId", ), throwsA(isA())); }); From c7f1392734df24cd177324f44cdee12f6af8c789 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 10:49:49 -0600 Subject: [PATCH 56/80] cache boxes hive error fix --- lib/db/hive/db.dart | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/db/hive/db.dart b/lib/db/hive/db.dart index 931a1cee4..25efcdb3e 100644 --- a/lib/db/hive/db.dart +++ b/lib/db/hive/db.dart @@ -177,6 +177,9 @@ class DB { } Future> getTxCacheBox({required Coin coin}) async { + if (_txCacheBoxes[coin]?.isOpen != true) { + _txCacheBoxes.remove(coin); + } return _txCacheBoxes[coin] ??= await Hive.openBox(_boxNameTxCache(coin: coin)); } @@ -186,6 +189,9 @@ class DB { } Future> getAnonymitySetCacheBox({required Coin coin}) async { + if (_setCacheBoxes[coin]?.isOpen != true) { + _setCacheBoxes.remove(coin); + } return _setCacheBoxes[coin] ??= await Hive.openBox(_boxNameSetCache(coin: coin)); } @@ -195,6 +201,9 @@ class DB { } Future> getUsedSerialsCacheBox({required Coin coin}) async { + if (_usedSerialsCacheBoxes[coin]?.isOpen != true) { + _usedSerialsCacheBoxes.remove(coin); + } return _usedSerialsCacheBoxes[coin] ??= await Hive.openBox(_boxNameUsedSerialsCache(coin: coin)); } From a8abd388271f0e6ebfaee51d44490cd374e3e408 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 11:17:30 -0600 Subject: [PATCH 57/80] invalid vsize fix --- lib/services/coins/firo/firo_wallet.dart | 26 +++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 659a6d94b..7b42698dc 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -1429,16 +1429,32 @@ class FiroWallet extends CoinServiceAPI feeRatePerKB: selectedTxFeeRate, ); - if (feeForOneOutput < vSizeForOneOutput + 1) { - feeForOneOutput = vSizeForOneOutput + 1; - } - - final int amount = satoshiAmountToSend - feeForOneOutput; + int amount = satoshiAmountToSend - feeForOneOutput; dynamic txn = await buildTransaction( utxoSigningData: utxoSigningData, recipients: recipientsArray, satoshiAmounts: [amount], ); + + int count = 0; + int fee = feeForOneOutput; + int vsize = txn["vSize"] as int; + + while (fee < vsize && count < 10) { + // 10 being some reasonable max + count++; + fee += count; + amount = satoshiAmountToSend - fee; + + txn = await buildTransaction( + utxoSigningData: utxoSigningData, + recipients: recipientsArray, + satoshiAmounts: [amount], + ); + + vsize = txn["vSize"] as int; + } + Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], From 5f9b1f77f58114eb0f39b2f10911da15b169b791 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 11:17:54 -0600 Subject: [PATCH 58/80] clearer exception --- lib/services/coins/firo/firo_wallet.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 7b42698dc..10cf4473c 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -4592,7 +4592,8 @@ class FiroWallet extends CoinServiceAPI "$e\n$s", level: LogLevel.Fatal, ); - rethrow; + // don't just rethrow since isar likes to strip stack traces for some reason + throw Exception("e=$e & s=$s"); } final transactionMap = From e1140e6fa6dc863ca09b43ea2b3596d899be026d Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 11:18:21 -0600 Subject: [PATCH 59/80] clear lelantus coins on full rescan --- lib/db/isar/main_db.dart | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index fa565c0cd..4b60e2cda 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -371,6 +371,7 @@ class MainDB { final transactionCount = await getTransactions(walletId).count(); final addressCount = await getAddresses(walletId).count(); final utxoCount = await getUTXOs(walletId).count(); + final lelantusCoinCount = await isar.lelantusCoins.where().walletIdEqualTo(walletId).count(); await isar.writeTxn(() async { const paginateLimit = 50; @@ -404,6 +405,16 @@ class MainDB { .findAll(); await isar.utxos.deleteAll(utxoIds); } + + // lelantusCoins + for (int i = 0; i < lelantusCoinCount; i += paginateLimit) { + final lelantusCoinIds = await isar.lelantusCoins.where().walletIdEqualTo(walletId) + .offset(i) + .limit(paginateLimit) + .idProperty() + .findAll(); + await isar.lelantusCoins.deleteAll(lelantusCoinIds); + } }); } From 5439ce895433bbf9c9e5dee3cb6e1596954c38b9 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 12:06:06 -0600 Subject: [PATCH 60/80] show error before data in case dart decides string is too long and cuts it off --- lib/electrumx_rpc/electrumx.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/electrumx_rpc/electrumx.dart b/lib/electrumx_rpc/electrumx.dart index e0a3118eb..804a1364c 100644 --- a/lib/electrumx_rpc/electrumx.dart +++ b/lib/electrumx_rpc/electrumx.dart @@ -159,8 +159,8 @@ class ElectrumX { throw Exception( "JSONRPC response\n" " command: $command\n" - " args: $args\n" - " error: ${response.data}", + " error: ${response.data}" + " args: $args\n", ); } From 3c1a3f23e379fb187e40e1738ce34154f17a8b43 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 12:07:09 -0600 Subject: [PATCH 61/80] clean up --- lib/services/coins/firo/firo_wallet.dart | 47 ------------------------ 1 file changed, 47 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 10cf4473c..a31e0f62c 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -1224,18 +1224,6 @@ class FiroWallet extends CoinServiceAPI try { final txid = txData["txid"] as String; - // temporarily update apdate available balance until a full refresh is done - - // TODO: something here causes an exception to be thrown giving user false info that the tx failed - // Decimal sendTotal = - // Format.satoshisToAmount(txData["value"] as int, coin: coin); - // sendTotal += Decimal.parse(txData["fees"].toString()); - - // TODO: is this needed? - // final bals = await balances; - // bals[0] -= sendTotal; - // _balances = Future(() => bals); - return txid; } catch (e, s) { //todo: come back to this @@ -2409,7 +2397,6 @@ class FiroWallet extends CoinServiceAPI .findFirstSync(); if (txn == null) { - // TODO: ?????????????????????????????????????? Logging.instance.log( "Transaction not found in DB for lelantus coin: $lelantusCoin", level: LogLevel.Fatal, @@ -2686,8 +2673,6 @@ class FiroWallet extends CoinServiceAPI int satoshisPerRecipient, List> mintsMap, ) async { - //todo: check if print needed - // debugPrint(utxosToUse.toString()); List addressStringsToGet = []; // Populating the addresses to derive @@ -3966,7 +3951,6 @@ class FiroWallet extends CoinServiceAPI Logging.instance .log('Outputs fetched: $outputArray', level: LogLevel.Info); - // TODO move this out of here and into IDB await db.isar.writeTxn(() async { await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); @@ -4816,36 +4800,6 @@ class FiroWallet extends CoinServiceAPI Logging.instance.log('Closing estimateJoinSplit!', level: LogLevel.Info); return (message as LelantusFeeData).fee; } - // int fee; - // int size; - // - // for (fee = 0;;) { - // int currentRequired = spendAmount; - // - // TODO: investigate the bug here - // var map = await getCoinsToJoinSplit(currentRequired); - // if (map is bool && !map) { - // return 0; - // } - // - // List coinsToBeSpent = - // map['coinsToSpend'] as List; - // - // // 1054 is constant part, mainly Schnorr and Range proofs, 2560 is for each sigma/aux data - // // 179 other parts of tx, assuming 1 utxo and 1 jmint - // size = 1054 + 2560 * coinsToBeSpent.length + 180; - // // uint64_t feeNeeded = GetMinimumFee(size, DEFAULT_TX_CONFIRM_TARGET); - // int feeNeeded = - // size; //TODO(Levon) temporary, use real estimation methods here - // - // if (fee >= feeNeeded) { - // break; - // } - // - // fee = feeNeeded; - // } - // - // return fee; @override Future estimateFeeFor(Amount amount, int feeRate) async { @@ -4908,7 +4862,6 @@ class FiroWallet extends CoinServiceAPI } } - // TODO: correct formula for firo? Amount roughFeeEstimate(int inputCount, int outputCount, int feeRatePerKB) { return Amount( rawValue: BigInt.from(((181 * inputCount) + (34 * outputCount) + 10) * From 7d1d7cb8049c08195b146e77e0c77131e2f1c08b Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 12:07:44 -0600 Subject: [PATCH 62/80] auto format on save --- lib/db/isar/main_db.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index 4b60e2cda..93c9052da 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -371,7 +371,8 @@ class MainDB { final transactionCount = await getTransactions(walletId).count(); final addressCount = await getAddresses(walletId).count(); final utxoCount = await getUTXOs(walletId).count(); - final lelantusCoinCount = await isar.lelantusCoins.where().walletIdEqualTo(walletId).count(); + final lelantusCoinCount = + await isar.lelantusCoins.where().walletIdEqualTo(walletId).count(); await isar.writeTxn(() async { const paginateLimit = 50; @@ -408,7 +409,9 @@ class MainDB { // lelantusCoins for (int i = 0; i < lelantusCoinCount; i += paginateLimit) { - final lelantusCoinIds = await isar.lelantusCoins.where().walletIdEqualTo(walletId) + final lelantusCoinIds = await isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) .offset(i) .limit(paginateLimit) .idProperty() From 590717560e3469ab1b65ea80b355c601285e1023 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 12:12:10 -0600 Subject: [PATCH 63/80] notif error fix? --- lib/widgets/crypto_notifications.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/widgets/crypto_notifications.dart b/lib/widgets/crypto_notifications.dart index f94c74ed9..88a96d422 100644 --- a/lib/widgets/crypto_notifications.dart +++ b/lib/widgets/crypto_notifications.dart @@ -13,6 +13,7 @@ import 'dart:async'; import 'package:event_bus/event_bus.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/services/notifications_api.dart'; import 'package:stackwallet/themes/coin_icon_provider.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -84,6 +85,7 @@ class _CryptoNotificationsState extends ConsumerState { @override void initState() { + NotificationApi.prefs = ref.read(prefsChangeNotifierProvider); _streamSubscription = CryptoNotificationsEventBus.instance .on() .listen( From 20c706c7e5558ca6a170b739234f79021b8d4e0d Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 12:16:08 -0600 Subject: [PATCH 64/80] add todo check --- lib/services/coins/firo/firo_wallet.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index a31e0f62c..ea0a255d4 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -2637,6 +2637,8 @@ class FiroWallet extends CoinServiceAPI mintValue, index, ); + + // TODO publicCoin prob shouldn't be empty? mints.add({ "value": mintValue, "script": mint, From c9470a5078168f1359f9b771bbb3d7d9e4d86f09 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 13:48:19 -0600 Subject: [PATCH 65/80] desktop notifications fix --- lib/widgets/crypto_notifications.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/widgets/crypto_notifications.dart b/lib/widgets/crypto_notifications.dart index 88a96d422..b570ae4f9 100644 --- a/lib/widgets/crypto_notifications.dart +++ b/lib/widgets/crypto_notifications.dart @@ -13,7 +13,7 @@ import 'dart:async'; import 'package:event_bus/event_bus.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:stackwallet/providers/global/prefs_provider.dart'; +import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/services/notifications_api.dart'; import 'package:stackwallet/themes/coin_icon_provider.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -86,6 +86,7 @@ class _CryptoNotificationsState extends ConsumerState { @override void initState() { NotificationApi.prefs = ref.read(prefsChangeNotifierProvider); + NotificationApi.notificationsService = ref.read(notificationsProvider); _streamSubscription = CryptoNotificationsEventBus.instance .on() .listen( From 128fa9db6cb79dc6c5dc8ecfadb2afcc8c6121dc Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 13:48:39 -0600 Subject: [PATCH 66/80] rpc timeout mod --- lib/electrumx_rpc/rpc.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/electrumx_rpc/rpc.dart b/lib/electrumx_rpc/rpc.dart index 0c3834ae8..e865356d6 100644 --- a/lib/electrumx_rpc/rpc.dart +++ b/lib/electrumx_rpc/rpc.dart @@ -79,7 +79,7 @@ class JsonRPC { // TODO different timeout length? req.initiateTimeout( - const Duration(seconds: 10), + Duration(seconds: connectionTimeout.inSeconds ~/ 2), onTimedOut: () { _requestQueue.remove(req); }, From 04658f8eef091b31ba78da10d1a9ab194544fb83 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 13:55:19 -0600 Subject: [PATCH 67/80] null error bandaid --- lib/services/notifications_api.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/services/notifications_api.dart b/lib/services/notifications_api.dart index 41e95387b..3ef97462a 100644 --- a/lib/services/notifications_api.dart +++ b/lib/services/notifications_api.dart @@ -77,8 +77,10 @@ class NotificationApi { final id = prefs.currentNotificationId; String confirms = ""; - if (txid != null) { - confirms = " (${confirmations!}/${requiredConfirmations!})"; + if (txid != null && + confirmations != null && + requiredConfirmations != null) { + confirms = " ($confirmations/$requiredConfirmations)"; } final NotificationModel model = NotificationModel( From 2cca59532e43fc84a0d637ad3bd35032418ed0fc Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 14:14:07 -0600 Subject: [PATCH 68/80] delete by index instead of public Coin since who tf knows what it could be in our code --- lib/services/coins/firo/firo_wallet.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index ea0a255d4..44a29ee96 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -3046,10 +3046,9 @@ class FiroWallet extends CoinServiceAPI try { await db.isar.writeTxn(() async { for (final c in updatedCoins) { - await db.isar.lelantusCoins.deleteByPublicCoinWalletIdTxid( - c.publicCoin, + await db.isar.lelantusCoins.deleteByMintIndexWalletId( + c.mintIndex, c.walletId, - c.txid, ); } await db.isar.lelantusCoins.putAll(updatedCoins); From ce1dce113062ead4fbd74ef70aa5f08e19ad91ae Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 14:56:31 -0600 Subject: [PATCH 69/80] comment and fix error messages --- lib/services/coins/firo/firo_wallet.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 44a29ee96..861263625 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -1138,7 +1138,8 @@ class FiroWallet extends CoinServiceAPI } } } catch (e, s) { - Logging.instance.log("Exception rethrown from prepareSend(): $e\n$s", + Logging.instance.log( + "Exception rethrown from prepareSendPublic(): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1146,7 +1147,8 @@ class FiroWallet extends CoinServiceAPI throw ArgumentError("Invalid fee rate argument provided!"); } } catch (e, s) { - Logging.instance.log("Exception rethrown from prepareSend(): $e\n$s", + Logging.instance.log( + "Exception rethrown from prepareSendPublic(): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2346,6 +2348,8 @@ class FiroWallet extends CoinServiceAPI final lelantusEntries = await Future.wait(waitLelantusEntries); if (lelantusEntries.isNotEmpty) { + // should be redundant as _getUnspentCoins() should + // already remove all where value=0 lelantusEntries.removeWhere((element) => element.amount == 0); } From 759e5624e43d139381027264deebb7b4c444cb0b Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 15:11:34 -0600 Subject: [PATCH 70/80] stop storing public coin --- .../models/firo_specific/lelantus_coin.dart | 13 - .../models/firo_specific/lelantus_coin.g.dart | 464 +----------------- lib/services/coins/firo/firo_wallet.dart | 14 +- lib/utilities/db_version_migration.dart | 1 - 4 files changed, 16 insertions(+), 476 deletions(-) diff --git a/lib/models/isar/models/firo_specific/lelantus_coin.dart b/lib/models/isar/models/firo_specific/lelantus_coin.dart index 9ad5bc5a3..ca4c11919 100644 --- a/lib/models/isar/models/firo_specific/lelantus_coin.dart +++ b/lib/models/isar/models/firo_specific/lelantus_coin.dart @@ -9,16 +9,6 @@ class LelantusCoin { @Index() final String walletId; - @Index( - unique: true, - composite: [ - CompositeIndex("walletId"), - CompositeIndex("txid"), - ], - replace: false, - ) - final String publicCoin; - final String txid; final String value; // can't use BigInt in isar :shrug: @@ -42,7 +32,6 @@ class LelantusCoin { LelantusCoin({ required this.walletId, - required this.publicCoin, required this.txid, required this.value, required this.mintIndex, @@ -65,7 +54,6 @@ class LelantusCoin { }) { return LelantusCoin( walletId: walletId ?? this.walletId, - publicCoin: publicCoin ?? this.publicCoin, txid: txid ?? this.txid, value: value ?? this.value, mintIndex: mintIndex ?? this.mintIndex, @@ -81,7 +69,6 @@ class LelantusCoin { return 'LelantusCoin{' 'id: $id, ' 'walletId: $walletId, ' - 'publicCoin: $publicCoin, ' 'txid: $txid, ' 'value: $value, ' 'mintIndex: $mintIndex, ' diff --git a/lib/models/isar/models/firo_specific/lelantus_coin.g.dart b/lib/models/isar/models/firo_specific/lelantus_coin.g.dart index d2e27638d..4b9214889 100644 --- a/lib/models/isar/models/firo_specific/lelantus_coin.g.dart +++ b/lib/models/isar/models/firo_specific/lelantus_coin.g.dart @@ -42,23 +42,18 @@ const LelantusCoinSchema = CollectionSchema( name: r'otherData', type: IsarType.string, ), - r'publicCoin': PropertySchema( - id: 5, - name: r'publicCoin', - type: IsarType.string, - ), r'txid': PropertySchema( - id: 6, + id: 5, name: r'txid', type: IsarType.string, ), r'value': PropertySchema( - id: 7, + id: 6, name: r'value', type: IsarType.string, ), r'walletId': PropertySchema( - id: 8, + id: 7, name: r'walletId', type: IsarType.string, ) @@ -82,29 +77,6 @@ const LelantusCoinSchema = CollectionSchema( ) ], ), - r'publicCoin_walletId_txid': IndexSchema( - id: 5610740154835640070, - name: r'publicCoin_walletId_txid', - unique: true, - replace: false, - properties: [ - IndexPropertySchema( - name: r'publicCoin', - type: IndexType.hash, - caseSensitive: true, - ), - IndexPropertySchema( - name: r'walletId', - type: IndexType.hash, - caseSensitive: true, - ), - IndexPropertySchema( - name: r'txid', - type: IndexType.hash, - caseSensitive: true, - ) - ], - ), r'mintIndex_walletId': IndexSchema( id: -9147309777276196770, name: r'mintIndex_walletId', @@ -144,7 +116,6 @@ int _lelantusCoinEstimateSize( bytesCount += 3 + value.length * 3; } } - bytesCount += 3 + object.publicCoin.length * 3; bytesCount += 3 + object.txid.length * 3; bytesCount += 3 + object.value.length * 3; bytesCount += 3 + object.walletId.length * 3; @@ -162,10 +133,9 @@ void _lelantusCoinSerialize( writer.writeBool(offsets[2], object.isUsed); writer.writeLong(offsets[3], object.mintIndex); writer.writeString(offsets[4], object.otherData); - writer.writeString(offsets[5], object.publicCoin); - writer.writeString(offsets[6], object.txid); - writer.writeString(offsets[7], object.value); - writer.writeString(offsets[8], object.walletId); + writer.writeString(offsets[5], object.txid); + writer.writeString(offsets[6], object.value); + writer.writeString(offsets[7], object.walletId); } LelantusCoin _lelantusCoinDeserialize( @@ -180,10 +150,9 @@ LelantusCoin _lelantusCoinDeserialize( isUsed: reader.readBool(offsets[2]), mintIndex: reader.readLong(offsets[3]), otherData: reader.readStringOrNull(offsets[4]), - publicCoin: reader.readString(offsets[5]), - txid: reader.readString(offsets[6]), - value: reader.readString(offsets[7]), - walletId: reader.readString(offsets[8]), + txid: reader.readString(offsets[5]), + value: reader.readString(offsets[6]), + walletId: reader.readString(offsets[7]), ); object.id = id; return object; @@ -212,8 +181,6 @@ P _lelantusCoinDeserializeProp

( return (reader.readString(offset)) as P; case 7: return (reader.readString(offset)) as P; - case 8: - return (reader.readString(offset)) as P; default: throw IsarError('Unknown property with id $propertyId'); } @@ -233,106 +200,6 @@ void _lelantusCoinAttach( } extension LelantusCoinByIndex on IsarCollection { - Future getByPublicCoinWalletIdTxid( - String publicCoin, String walletId, String txid) { - return getByIndex( - r'publicCoin_walletId_txid', [publicCoin, walletId, txid]); - } - - LelantusCoin? getByPublicCoinWalletIdTxidSync( - String publicCoin, String walletId, String txid) { - return getByIndexSync( - r'publicCoin_walletId_txid', [publicCoin, walletId, txid]); - } - - Future deleteByPublicCoinWalletIdTxid( - String publicCoin, String walletId, String txid) { - return deleteByIndex( - r'publicCoin_walletId_txid', [publicCoin, walletId, txid]); - } - - bool deleteByPublicCoinWalletIdTxidSync( - String publicCoin, String walletId, String txid) { - return deleteByIndexSync( - r'publicCoin_walletId_txid', [publicCoin, walletId, txid]); - } - - Future> getAllByPublicCoinWalletIdTxid( - List publicCoinValues, - List walletIdValues, - List txidValues) { - final len = publicCoinValues.length; - assert(walletIdValues.length == len && txidValues.length == len, - 'All index values must have the same length'); - final values = >[]; - for (var i = 0; i < len; i++) { - values.add([publicCoinValues[i], walletIdValues[i], txidValues[i]]); - } - - return getAllByIndex(r'publicCoin_walletId_txid', values); - } - - List getAllByPublicCoinWalletIdTxidSync( - List publicCoinValues, - List walletIdValues, - List txidValues) { - final len = publicCoinValues.length; - assert(walletIdValues.length == len && txidValues.length == len, - 'All index values must have the same length'); - final values = >[]; - for (var i = 0; i < len; i++) { - values.add([publicCoinValues[i], walletIdValues[i], txidValues[i]]); - } - - return getAllByIndexSync(r'publicCoin_walletId_txid', values); - } - - Future deleteAllByPublicCoinWalletIdTxid(List publicCoinValues, - List walletIdValues, List txidValues) { - final len = publicCoinValues.length; - assert(walletIdValues.length == len && txidValues.length == len, - 'All index values must have the same length'); - final values = >[]; - for (var i = 0; i < len; i++) { - values.add([publicCoinValues[i], walletIdValues[i], txidValues[i]]); - } - - return deleteAllByIndex(r'publicCoin_walletId_txid', values); - } - - int deleteAllByPublicCoinWalletIdTxidSync(List publicCoinValues, - List walletIdValues, List txidValues) { - final len = publicCoinValues.length; - assert(walletIdValues.length == len && txidValues.length == len, - 'All index values must have the same length'); - final values = >[]; - for (var i = 0; i < len; i++) { - values.add([publicCoinValues[i], walletIdValues[i], txidValues[i]]); - } - - return deleteAllByIndexSync(r'publicCoin_walletId_txid', values); - } - - Future putByPublicCoinWalletIdTxid(LelantusCoin object) { - return putByIndex(r'publicCoin_walletId_txid', object); - } - - Id putByPublicCoinWalletIdTxidSync(LelantusCoin object, - {bool saveLinks = true}) { - return putByIndexSync(r'publicCoin_walletId_txid', object, - saveLinks: saveLinks); - } - - Future> putAllByPublicCoinWalletIdTxid(List objects) { - return putAllByIndex(r'publicCoin_walletId_txid', objects); - } - - List putAllByPublicCoinWalletIdTxidSync(List objects, - {bool saveLinks = true}) { - return putAllByIndexSync(r'publicCoin_walletId_txid', objects, - saveLinks: saveLinks); - } - Future getByMintIndexWalletId(int mintIndex, String walletId) { return getByIndex(r'mintIndex_walletId', [mintIndex, walletId]); } @@ -543,144 +410,6 @@ extension LelantusCoinQueryWhere }); } - QueryBuilder - publicCoinEqualToAnyWalletIdTxid(String publicCoin) { - return QueryBuilder.apply(this, (query) { - return query.addWhereClause(IndexWhereClause.equalTo( - indexName: r'publicCoin_walletId_txid', - value: [publicCoin], - )); - }); - } - - QueryBuilder - publicCoinNotEqualToAnyWalletIdTxid(String publicCoin) { - return QueryBuilder.apply(this, (query) { - if (query.whereSort == Sort.asc) { - return query - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [], - upper: [publicCoin], - includeUpper: false, - )) - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin], - includeLower: false, - upper: [], - )); - } else { - return query - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin], - includeLower: false, - upper: [], - )) - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [], - upper: [publicCoin], - includeUpper: false, - )); - } - }); - } - - QueryBuilder - publicCoinWalletIdEqualToAnyTxid(String publicCoin, String walletId) { - return QueryBuilder.apply(this, (query) { - return query.addWhereClause(IndexWhereClause.equalTo( - indexName: r'publicCoin_walletId_txid', - value: [publicCoin, walletId], - )); - }); - } - - QueryBuilder - publicCoinEqualToWalletIdNotEqualToAnyTxid( - String publicCoin, String walletId) { - return QueryBuilder.apply(this, (query) { - if (query.whereSort == Sort.asc) { - return query - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin], - upper: [publicCoin, walletId], - includeUpper: false, - )) - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin, walletId], - includeLower: false, - upper: [publicCoin], - )); - } else { - return query - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin, walletId], - includeLower: false, - upper: [publicCoin], - )) - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin], - upper: [publicCoin, walletId], - includeUpper: false, - )); - } - }); - } - - QueryBuilder - publicCoinWalletIdTxidEqualTo( - String publicCoin, String walletId, String txid) { - return QueryBuilder.apply(this, (query) { - return query.addWhereClause(IndexWhereClause.equalTo( - indexName: r'publicCoin_walletId_txid', - value: [publicCoin, walletId, txid], - )); - }); - } - - QueryBuilder - publicCoinWalletIdEqualToTxidNotEqualTo( - String publicCoin, String walletId, String txid) { - return QueryBuilder.apply(this, (query) { - if (query.whereSort == Sort.asc) { - return query - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin, walletId], - upper: [publicCoin, walletId, txid], - includeUpper: false, - )) - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin, walletId, txid], - includeLower: false, - upper: [publicCoin, walletId], - )); - } else { - return query - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin, walletId, txid], - includeLower: false, - upper: [publicCoin, walletId], - )) - .addWhereClause(IndexWhereClause.between( - indexName: r'publicCoin_walletId_txid', - lower: [publicCoin, walletId], - upper: [publicCoin, walletId, txid], - includeUpper: false, - )); - } - }); - } - QueryBuilder mintIndexEqualToAnyWalletId(int mintIndex) { return QueryBuilder.apply(this, (query) { @@ -1161,142 +890,6 @@ extension LelantusCoinQueryFilter }); } - QueryBuilder - publicCoinEqualTo( - String value, { - bool caseSensitive = true, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.equalTo( - property: r'publicCoin', - value: value, - caseSensitive: caseSensitive, - )); - }); - } - - QueryBuilder - publicCoinGreaterThan( - String value, { - bool include = false, - bool caseSensitive = true, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.greaterThan( - include: include, - property: r'publicCoin', - value: value, - caseSensitive: caseSensitive, - )); - }); - } - - QueryBuilder - publicCoinLessThan( - String value, { - bool include = false, - bool caseSensitive = true, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.lessThan( - include: include, - property: r'publicCoin', - value: value, - caseSensitive: caseSensitive, - )); - }); - } - - QueryBuilder - publicCoinBetween( - String lower, - String upper, { - bool includeLower = true, - bool includeUpper = true, - bool caseSensitive = true, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.between( - property: r'publicCoin', - lower: lower, - includeLower: includeLower, - upper: upper, - includeUpper: includeUpper, - caseSensitive: caseSensitive, - )); - }); - } - - QueryBuilder - publicCoinStartsWith( - String value, { - bool caseSensitive = true, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.startsWith( - property: r'publicCoin', - value: value, - caseSensitive: caseSensitive, - )); - }); - } - - QueryBuilder - publicCoinEndsWith( - String value, { - bool caseSensitive = true, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.endsWith( - property: r'publicCoin', - value: value, - caseSensitive: caseSensitive, - )); - }); - } - - QueryBuilder - publicCoinContains(String value, {bool caseSensitive = true}) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.contains( - property: r'publicCoin', - value: value, - caseSensitive: caseSensitive, - )); - }); - } - - QueryBuilder - publicCoinMatches(String pattern, {bool caseSensitive = true}) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.matches( - property: r'publicCoin', - wildcard: pattern, - caseSensitive: caseSensitive, - )); - }); - } - - QueryBuilder - publicCoinIsEmpty() { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.equalTo( - property: r'publicCoin', - value: '', - )); - }); - } - - QueryBuilder - publicCoinIsNotEmpty() { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.greaterThan( - property: r'publicCoin', - value: '', - )); - }); - } - QueryBuilder txidEqualTo( String value, { bool caseSensitive = true, @@ -1772,19 +1365,6 @@ extension LelantusCoinQuerySortBy }); } - QueryBuilder sortByPublicCoin() { - return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'publicCoin', Sort.asc); - }); - } - - QueryBuilder - sortByPublicCoinDesc() { - return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'publicCoin', Sort.desc); - }); - } - QueryBuilder sortByTxid() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'txid', Sort.asc); @@ -1898,19 +1478,6 @@ extension LelantusCoinQuerySortThenBy }); } - QueryBuilder thenByPublicCoin() { - return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'publicCoin', Sort.asc); - }); - } - - QueryBuilder - thenByPublicCoinDesc() { - return QueryBuilder.apply(this, (query) { - return query.addSortBy(r'publicCoin', Sort.desc); - }); - } - QueryBuilder thenByTxid() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'txid', Sort.asc); @@ -1982,13 +1549,6 @@ extension LelantusCoinQueryWhereDistinct }); } - QueryBuilder distinctByPublicCoin( - {bool caseSensitive = true}) { - return QueryBuilder.apply(this, (query) { - return query.addDistinctBy(r'publicCoin', caseSensitive: caseSensitive); - }); - } - QueryBuilder distinctByTxid( {bool caseSensitive = true}) { return QueryBuilder.apply(this, (query) { @@ -2049,12 +1609,6 @@ extension LelantusCoinQueryProperty }); } - QueryBuilder publicCoinProperty() { - return QueryBuilder.apply(this, (query) { - return query.addPropertyName(r'publicCoin'); - }); - } - QueryBuilder txidProperty() { return QueryBuilder.apply(this, (query) { return query.addPropertyName(r'txid'); diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 861263625..3b67d96c3 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -276,7 +276,7 @@ Future> isolateRestore( walletId: walletId, mintIndex: currentIndex, value: amount.toString(), - publicCoin: publicCoin, + // publicCoin: publicCoin, txid: txId, anonymitySetId: setId, isUsed: isUsed, @@ -326,7 +326,7 @@ Future> isolateRestore( walletId: walletId, mintIndex: currentIndex, value: amount.toString(), - publicCoin: publicCoin, + // publicCoin: publicCoin, txid: txId, anonymitySetId: setId, isUsed: isUsed, @@ -682,7 +682,7 @@ Future isolateCreateJoinSplitTransaction( "fee": fee, "vSize": extTx.virtualSize(), "jmintValue": changeToMint, - "publicCoin": "jmintData.publicCoin", + // "publicCoin": "jmintData.publicCoin", "spendCoinIndexes": spendCoinIndexes, "height": locktime, "txType": "Sent", @@ -2647,7 +2647,7 @@ class FiroWallet extends CoinServiceAPI "value": mintValue, "script": mint, "index": index, - "publicCoin": "", + // "publicCoin": "", }); tmpTotal = tmpTotal - (coin == Coin.firoTestNet ? MINT_LIMIT_TESTNET : MINT_LIMIT); @@ -2834,7 +2834,7 @@ class FiroWallet extends CoinServiceAPI rawValue: BigInt.from(fee), fractionDigits: coin.decimals, ).decimal.toDouble(), - "publicCoin": "", + // "publicCoin": "", "height": height, "txType": "Sent", "confirmed_status": false, @@ -3036,7 +3036,7 @@ class FiroWallet extends CoinServiceAPI walletId: walletId, mintIndex: nextFreeMintIndex, value: (transactionInfo['jmintValue'] as int? ?? 0).toString(), - publicCoin: transactionInfo['publicCoin'] as String, + // publicCoin: transactionInfo['publicCoin'] as String, txid: transactionInfo['txid'] as String, anonymitySetId: latestSetId, isUsed: false, @@ -3130,7 +3130,7 @@ class FiroWallet extends CoinServiceAPI walletId: walletId, mintIndex: index, value: (mintMap['value'] as int).toString(), - publicCoin: mintMap['publicCoin'] as String, + // publicCoin: mintMap['publicCoin'] as String, txid: transactionInfo['txid'] as String, anonymitySetId: latestSetId, isUsed: false, diff --git a/lib/utilities/db_version_migration.dart b/lib/utilities/db_version_migration.dart index d2c0adbe8..f54c2b85a 100644 --- a/lib/utilities/db_version_migration.dart +++ b/lib/utilities/db_version_migration.dart @@ -400,7 +400,6 @@ class DbVersionMigrator with WalletDB { final coin = isar_models.LelantusCoin( walletId: walletId, - publicCoin: lcoin.publicCoin, txid: lcoin.txId, value: lcoin.value.toString(), mintIndex: lcoin.index, From 7919353881c132684d23cc74a033be91836210e0 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 15:11:56 -0600 Subject: [PATCH 71/80] update mocks --- test/services/coins/manager_test.mocks.dart | 9 --------- test/widget_tests/transaction_card_test.mocks.dart | 9 --------- 2 files changed, 18 deletions(-) diff --git a/test/services/coins/manager_test.mocks.dart b/test/services/coins/manager_test.mocks.dart index 25fd46d9d..5656feb88 100644 --- a/test/services/coins/manager_test.mocks.dart +++ b/test/services/coins/manager_test.mocks.dart @@ -745,15 +745,6 @@ class MockFiroWallet extends _i1.Mock implements _i10.FiroWallet { returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); @override - _i11.Future getCoinsToJoinSplit(int? required) => - (super.noSuchMethod( - Invocation.method( - #getCoinsToJoinSplit, - [required], - ), - returnValue: _i11.Future.value(), - ) as _i11.Future); - @override _i11.Future estimateJoinSplitFee(int? spendAmount) => (super.noSuchMethod( Invocation.method( diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart index 29bd7bd29..74fa6e89e 100644 --- a/test/widget_tests/transaction_card_test.mocks.dart +++ b/test/widget_tests/transaction_card_test.mocks.dart @@ -1759,15 +1759,6 @@ class MockFiroWallet extends _i1.Mock implements _i23.FiroWallet { returnValueForMissingStub: _i19.Future.value(), ) as _i19.Future); @override - _i19.Future getCoinsToJoinSplit(int? required) => - (super.noSuchMethod( - Invocation.method( - #getCoinsToJoinSplit, - [required], - ), - returnValue: _i19.Future.value(), - ) as _i19.Future); - @override _i19.Future estimateJoinSplitFee(int? spendAmount) => (super.noSuchMethod( Invocation.method( From 90b16c576e2cacc9437230ecd9b8d066b814f98a Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 15:36:37 -0600 Subject: [PATCH 72/80] clean up --- lib/services/coins/firo/firo_wallet.dart | 84 +++--------------------- 1 file changed, 10 insertions(+), 74 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 3b67d96c3..7dedf2958 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -276,12 +276,12 @@ Future> isolateRestore( walletId: walletId, mintIndex: currentIndex, value: amount.toString(), - // publicCoin: publicCoin, txid: txId, anonymitySetId: setId, isUsed: isUsed, isJMint: false, - otherData: null, + otherData: + publicCoin, // not really needed but saved just in case ), ); Logging.instance.log( @@ -326,12 +326,12 @@ Future> isolateRestore( walletId: walletId, mintIndex: currentIndex, value: amount.toString(), - // publicCoin: publicCoin, txid: txId, anonymitySetId: setId, isUsed: isUsed, isJMint: true, - otherData: null, + otherData: + publicCoin, // not really needed but saved just in case ), ); jindexes.add(currentIndex); @@ -370,7 +370,6 @@ Future> isolateRestore( // Logging.instance.log("jmints $spendTxIds", addToDebugMessagesDB: false); result['_lelantus_coins'] = lelantusCoins; - result['mintIndex'] = lastFoundIndex + 1; result['jindex'] = jindexes; result['spendTxIds'] = spendTxIds; @@ -682,7 +681,6 @@ Future isolateCreateJoinSplitTransaction( "fee": fee, "vSize": extTx.virtualSize(), "jmintValue": changeToMint, - // "publicCoin": "jmintData.publicCoin", "spendCoinIndexes": spendCoinIndexes, "height": locktime, "txType": "Sent", @@ -1241,53 +1239,6 @@ class FiroWallet extends CoinServiceAPI } } - // /// returns txid on successful send - // /// - // /// can throw - // @override - // Future send({ - // required String toAddress, - // required int amount, - // Map args = const {}, - // }) async { - // try { - // dynamic txHexOrError = - // await _createJoinSplitTransaction(amount, toAddress, false); - // Logging.instance.log("txHexOrError $txHexOrError", level: LogLevel.Error); - // if (txHexOrError is int) { - // // Here, we assume that transaction crafting returned an error - // switch (txHexOrError) { - // case 1: - // throw Exception("Insufficient balance!"); - // default: - // throw Exception("Error Creating Transaction!"); - // } - // } else { - // if (await _submitLelantusToNetwork( - // txHexOrError as Map)) { - // final txid = txHexOrError["txid"] as String; - // - // // temporarily update apdate available balance until a full refresh is done - // Decimal sendTotal = - // Format.satoshisToAmount(txHexOrError["value"] as int, coin: coin); - // sendTotal += Decimal.parse(txHexOrError["fees"].toString()); - // final bals = await balances; - // bals[0] -= sendTotal; - // _balances = Future(() => bals); - // - // return txid; - // } else { - // //TODO provide more info - // throw Exception("Transaction failed."); - // } - // } - // } catch (e, s) { - // Logging.instance.log("Exception rethrown in firo send(): $e\n$s", - // level: LogLevel.Error); - // rethrow; - // } - // } - Future> _getMnemonicList() async { final _mnemonicString = await mnemonicString; if (_mnemonicString == null) { @@ -2642,12 +2593,10 @@ class FiroWallet extends CoinServiceAPI index, ); - // TODO publicCoin prob shouldn't be empty? mints.add({ "value": mintValue, "script": mint, "index": index, - // "publicCoin": "", }); tmpTotal = tmpTotal - (coin == Coin.firoTestNet ? MINT_LIMIT_TESTNET : MINT_LIMIT); @@ -2834,7 +2783,6 @@ class FiroWallet extends CoinServiceAPI rawValue: BigInt.from(fee), fractionDigits: coin.decimals, ).decimal.toDouble(), - // "publicCoin": "", "height": height, "txType": "Sent", "confirmed_status": false, @@ -2848,6 +2796,7 @@ class FiroWallet extends CoinServiceAPI }; } + // TODO: verify this function does what we think it does Future _refreshLelantusData() async { final lelantusCoins = await db.isar.lelantusCoins .where() @@ -2916,8 +2865,6 @@ class FiroWallet extends CoinServiceAPI } } - // TODO: optimize this whole lelantus process - final List> txnsData = []; @@ -3013,21 +2960,13 @@ class FiroWallet extends CoinServiceAPI // Update all of the coins that have been spent. for (final index in spentCoinIndexes) { - final possibleCoins = await db.isar.lelantusCoins + final possibleCoin = await db.isar.lelantusCoins .where() - .walletIdEqualTo(walletId) - .filter() - .mintIndexEqualTo(index) - .findAll(); + .mintIndexWalletIdEqualTo(index, walletId) + .findFirst(); - if (possibleCoins.isNotEmpty) { - if (possibleCoins.length > 1) { - print( - "======================= possibleCoins.length > 1 !!! ================================="); - } else { - final spentCoin = possibleCoins.first; - updatedCoins.add(spentCoin.copyWith(isUsed: true)); - } + if (possibleCoin != null) { + updatedCoins.add(possibleCoin.copyWith(isUsed: true)); } } @@ -3036,7 +2975,6 @@ class FiroWallet extends CoinServiceAPI walletId: walletId, mintIndex: nextFreeMintIndex, value: (transactionInfo['jmintValue'] as int? ?? 0).toString(), - // publicCoin: transactionInfo['publicCoin'] as String, txid: transactionInfo['txid'] as String, anonymitySetId: latestSetId, isUsed: false, @@ -3122,7 +3060,6 @@ class FiroWallet extends CoinServiceAPI final List updatedCoins = []; - // TODO: transactionInfo['mintsMap'] for (final mintMap in transactionInfo['mintsMap'] as List>) { final index = mintMap['index'] as int; @@ -3130,7 +3067,6 @@ class FiroWallet extends CoinServiceAPI walletId: walletId, mintIndex: index, value: (mintMap['value'] as int).toString(), - // publicCoin: mintMap['publicCoin'] as String, txid: transactionInfo['txid'] as String, anonymitySetId: latestSetId, isUsed: false, From c1f73a89be16827fddd36343029c60212061f948 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 15:41:06 -0600 Subject: [PATCH 73/80] store jmint separately from updated coins --- lib/services/coins/firo/firo_wallet.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 7dedf2958..2a17d0849 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -2981,9 +2981,6 @@ class FiroWallet extends CoinServiceAPI isJMint: true, otherData: null, ); - if (int.parse(jmint.value) > 0) { - updatedCoins.add(jmint); - } try { await db.isar.writeTxn(() async { @@ -2994,6 +2991,10 @@ class FiroWallet extends CoinServiceAPI ); } await db.isar.lelantusCoins.putAll(updatedCoins); + + if (int.parse(jmint.value) > 0) { + await db.isar.lelantusCoins.put(jmint); + } }); } catch (e, s) { Logging.instance.log( From 5d3e976601e7b2e9f63f456931a26301107d48e3 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 16:08:54 -0600 Subject: [PATCH 74/80] always add lelantus coin to locale db --- lib/services/coins/firo/firo_wallet.dart | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 2a17d0849..37c31dce4 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -370,7 +370,6 @@ Future> isolateRestore( // Logging.instance.log("jmints $spendTxIds", addToDebugMessagesDB: false); result['_lelantus_coins'] = lelantusCoins; - result['jindex'] = jindexes; result['spendTxIds'] = spendTxIds; return result; @@ -2992,9 +2991,7 @@ class FiroWallet extends CoinServiceAPI } await db.isar.lelantusCoins.putAll(updatedCoins); - if (int.parse(jmint.value) > 0) { - await db.isar.lelantusCoins.put(jmint); - } + await db.isar.lelantusCoins.put(jmint); }); } catch (e, s) { Logging.instance.log( @@ -3074,9 +3071,8 @@ class FiroWallet extends CoinServiceAPI isJMint: false, otherData: null, ); - if (int.parse(mint.value) > 0) { - updatedCoins.add(mint); - } + + updatedCoins.add(mint); } // Logging.instance.log(coins); try { From c3054ca753d314ad5eab3752a76804a4e105d1ab Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 20:28:27 -0600 Subject: [PATCH 75/80] fix broken used serials call and optimize cache a bit --- lib/electrumx_rpc/cached_electrumx.dart | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/electrumx_rpc/cached_electrumx.dart b/lib/electrumx_rpc/cached_electrumx.dart index 67f170bb4..91b7d1bc8 100644 --- a/lib/electrumx_rpc/cached_electrumx.dart +++ b/lib/electrumx_rpc/cached_electrumx.dart @@ -164,14 +164,16 @@ class CachedElectrumX { final _list = box.get("serials") as List?; - List cachedSerials = - _list == null ? [] : List.from(_list); + Set cachedSerials = + _list == null ? {} : List.from(_list).toSet(); - final startNumber = cachedSerials.length; + // startNumber is broken currently + final startNumber = 0; // cachedSerials.length; - final serials = - await electrumXClient.getUsedCoinSerials(startNumber: startNumber); - List newSerials = []; + final serials = await electrumXClient.getUsedCoinSerials( + startNumber: startNumber, + ); + Set newSerials = {}; for (final element in (serials["serials"] as List)) { if (!isHexadecimal(element as String)) { @@ -182,12 +184,14 @@ class CachedElectrumX { } cachedSerials.addAll(newSerials); + final resultingList = cachedSerials.toList(); + await box.put( "serials", - cachedSerials, + resultingList, ); - return cachedSerials; + return resultingList; } catch (e, s) { Logging.instance.log( "Failed to process CachedElectrumX.getTransaction(): $e\n$s", From c9da22601ef0d92057d5ebe0ad58dd5d69dab5b2 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 20:28:51 -0600 Subject: [PATCH 76/80] clean up spam logs a bit --- lib/services/coins/firo/firo_wallet.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 37c31dce4..6b2bf733f 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -349,11 +349,6 @@ Future> isolateRestore( level: LogLevel.Warning, ); } - } else { - Logging.instance.log( - "Coin not found in data with the mint tag: $mintTag", - level: LogLevel.Warning, - ); } } From 57839c2d181a06461b8a8640968af0269802220e Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 20:29:44 -0600 Subject: [PATCH 77/80] WIP fixing _refreshLelantusData --- lib/services/coins/firo/firo_wallet.dart | 116 +++++++++-------------- 1 file changed, 44 insertions(+), 72 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 6b2bf733f..da0919570 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -2797,96 +2797,68 @@ class FiroWallet extends CoinServiceAPI .walletIdEqualTo(walletId) .filter() .isUsedEqualTo(false) - .and() - .isJMintEqualTo(true) .not() .valueEqualTo(0.toString()) .findAll(); - // Get all joinsplit transaction ids + final List updatedCoins = []; - final lelantusJoinSplitTxns = await db - .getTransactions(walletId) - .filter() - .isLelantusEqualTo(true) - .and() - .subTypeEqualTo(isar_models.TransactionSubType.join) - .findAll(); + final usedSerialNumbersSet = (await getUsedCoinSerials()).toSet(); - Set joinSplitTXIDs = {}; - - // for (final tx in lelantusJoinSplitTxns) { - // joinSplitTXIDs.add(tx.txid); - // } - for (final coin in lelantusCoins) { - joinSplitTXIDs.add(coin.txid); - } - - Map> - updatedData = {}; - - // Grab the most recent information on all the joinsplits - final updatedJSplit = await getJMintTransactions( - cachedElectrumXClient, - joinSplitTXIDs.toList(), - coin, + final root = await Bip32Utils.getBip32Root( + (await mnemonic).join(" "), + (await mnemonicPassphrase)!, + _network, ); - final currentChainHeight = await chainHeight; + for (final coin in lelantusCoins) { + final _derivePath = constructDerivePath( + networkWIF: _network.wif, + chain: MINT_INDEX, + index: coin.mintIndex, + ); + final bip32.BIP32 mintKeyPair = await Bip32Utils.getBip32NodeFromRoot( + root, + _derivePath, + ); - // update all of joinsplits that are now confirmed. - for (final tx in updatedJSplit.entries) { - isar_models.Transaction? currentTx; + final String serialNumber = GetSerialNumber( + int.parse(coin.value), + Format.uint8listToString(mintKeyPair.privateKey!), + coin.mintIndex, + isTestnet: this.coin == Coin.firoTestNet, + ); + final bool isUsed = usedSerialNumbersSet.contains(serialNumber); - try { - currentTx = - lelantusJoinSplitTxns.firstWhere((e) => e.txid == tx.value.txid); - } catch (_) { - currentTx = null; + if (isUsed) { + updatedCoins.add(coin.copyWith(isUsed: isUsed)); } - if (currentTx == null) { - // this send was accidentally not included in the list - tx.value.isLelantus = true; - updatedData[tx.value.txid] = - Tuple2(tx.value.address.value ?? tx.key, tx.value); - } else if (currentTx.isConfirmed( - currentChainHeight, MINIMUM_CONFIRMATIONS) != - tx.value.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { - tx.value.isLelantus = true; - updatedData[tx.value.txid] = - Tuple2(tx.value.address.value ?? tx.key, tx.value); + final tx = await db.getTransaction(walletId, coin.txid); + if (tx == null) { + print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); } } - final List> txnsData = - []; - - for (final value in updatedData.values) { - // allow possible null address on mints as we don't display address - // this should normally never be null anyways but old (dbVersion up to 4) - // migrated transactions may not have had an address (full rescan should - // fix this) - isar_models.Address? transactionAddress; + if (updatedCoins.isNotEmpty) { try { - transactionAddress = - value.item2.subType == isar_models.TransactionSubType.mint - ? value.item1 - : value.item1!; - } catch (_) { - Logging.instance - .log("_refreshLelantusData value: $value", level: LogLevel.Fatal); + await db.isar.writeTxn(() async { + for (final c in updatedCoins) { + await db.isar.lelantusCoins.deleteByMintIndexWalletId( + c.mintIndex, + c.walletId, + ); + } + await db.isar.lelantusCoins.putAll(updatedCoins); + }); + } catch (e, s) { + Logging.instance.log( + "$e\n$s", + level: LogLevel.Fatal, + ); + rethrow; } - final outs = - value.item2.outputs.where((_) => true).toList(growable: false); - final ins = value.item2.inputs.where((_) => true).toList(growable: false); - - txnsData.add(Tuple2( - value.item2.copyWith(inputs: ins, outputs: outs).item1, - transactionAddress)); } - - await db.addNewTransactionData(txnsData, walletId); } Future _getMintHex(int amount, int index) async { From 7b8f26206e7c5883a363d2f76976fef74b0f197c Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Jul 2023 20:48:03 -0600 Subject: [PATCH 78/80] show sent to self jmint transactions correctly --- lib/services/coins/firo/firo_wallet.dart | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index da0919570..0ccc6436c 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -3538,11 +3538,21 @@ class FiroWallet extends CoinServiceAPI ), ); } + final txid = txObject["txid"] as String; const subType = isar_models.TransactionSubType.join; + final type = nonWalletAddressFoundInOutputs ? isar_models.TransactionType.outgoing - : isar_models.TransactionType.incoming; + : (await db.isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .filter() + .txidEqualTo(txid) + .findFirst()) == + null + ? isar_models.TransactionType.incoming + : isar_models.TransactionType.sentToSelf; final amount = nonWalletAddressFoundInOutputs ? totalOutputValue @@ -3569,7 +3579,7 @@ class FiroWallet extends CoinServiceAPI final tx = isar_models.Transaction( walletId: walletId, - txid: txObject["txid"] as String, + txid: txid, timestamp: txObject["blocktime"] as int? ?? (DateTime.now().millisecondsSinceEpoch ~/ 1000), type: type, From 6733a367e3461ab40a14ac0a6fb53b22de65701b Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 26 Jul 2023 11:47:49 -0600 Subject: [PATCH 79/80] create mockable wrapper function --- lib/db/isar/main_db.dart | 11 +++++++++++ lib/services/coins/firo/firo_wallet.dart | 22 ++++------------------ 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index 93c9052da..c7a593d03 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -512,4 +512,15 @@ class MainDB { isar.writeTxn(() async { await isar.ethContracts.putAll(contracts); }); + + // ========== Lelantus ======================================================= + + Future getHighestUsedMintIndex({required String walletId}) async { + return await isar.lelantusCoins + .where() + .walletIdEqualTo(walletId) + .sortByMintIndexDesc() + .mintIndexProperty() + .findFirst(); + } } diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 0ccc6436c..079b96ff4 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -2512,12 +2512,7 @@ class FiroWallet extends CoinServiceAPI Future>> createMintsFromAmount(int total) async { int tmpTotal = total; int counter = 0; - final lastUsedIndex = await db.isar.lelantusCoins - .where() - .walletIdEqualTo(walletId) - .sortByMintIndexDesc() - .mintIndexProperty() - .findFirst(); + final lastUsedIndex = await db.getHighestUsedMintIndex(walletId: walletId); final nextFreeMintIndex = (lastUsedIndex ?? 0) + 1; final root = await Bip32Utils.getBip32Root( @@ -2908,12 +2903,8 @@ class FiroWallet extends CoinServiceAPI level: LogLevel.Info); if (txid == transactionInfo['txid']) { - final lastUsedIndex = await db.isar.lelantusCoins - .where() - .walletIdEqualTo(walletId) - .sortByMintIndexDesc() - .mintIndexProperty() - .findFirst(); + final lastUsedIndex = + await db.getHighestUsedMintIndex(walletId: walletId); final nextFreeMintIndex = (lastUsedIndex ?? 0) + 1; if (transactionInfo['spendCoinIndexes'] != null) { @@ -4577,12 +4568,7 @@ class FiroWallet extends CoinServiceAPI int spendAmount, String address, bool subtractFeeFromAmount) async { final _mnemonic = await mnemonicString; final _mnemonicPassphrase = await mnemonicPassphrase; - final lastUsedIndex = await db.isar.lelantusCoins - .where() - .walletIdEqualTo(walletId) - .sortByMintIndexDesc() - .mintIndexProperty() - .findFirst(); + final lastUsedIndex = await db.getHighestUsedMintIndex(walletId: walletId); final nextFreeMintIndex = (lastUsedIndex ?? 0) + 1; final lelantusEntry = await _getLelantusEntry(); final anonymitySets = await fetchAnonymitySets(); From dbcb567d6bcdff7c7905023b2479d9955d6440d4 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 26 Jul 2023 11:54:46 -0600 Subject: [PATCH 80/80] fix tests --- .../services/coins/firo/firo_wallet_test.dart | 37 +++++++++++-------- .../coins/firo/firo_wallet_test.mocks.dart | 10 +++++ .../transaction_card_test.mocks.dart | 10 +++++ 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/test/services/coins/firo/firo_wallet_test.dart b/test/services/coins/firo/firo_wallet_test.dart index fcd7bd50e..05b4aeeff 100644 --- a/test/services/coins/firo/firo_wallet_test.dart +++ b/test/services/coins/firo/firo_wallet_test.dart @@ -11,9 +11,7 @@ import 'package:mockito/mockito.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; -import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; -import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; -import 'package:stackwallet/models/lelantus_coin.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/models/lelantus_fee_data.dart'; import 'package:stackwallet/models/paymint/transactions_model.dart' as old; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; @@ -114,10 +112,7 @@ void main() { final result = await staticProcessRestore(txData, message, currentHeight); expect(result, isA>()); - expect(result["mintIndex"], 8); - expect(result["jindex"], [2, 4, 6]); - expect( - result["_lelantus_coins"], isA>>()); + expect(result["_lelantus_coins"], isA>()); expect(result["newTxMap"], isA>()); }); @@ -532,18 +527,10 @@ void main() { group("FiroWallet service class functions that depend on shared storage", () { const testWalletId = "testWalletID"; const testWalletName = "Test Wallet"; - bool hiveAdaptersRegistered = false; setUp(() async { await setUpTestHive(); - if (!hiveAdaptersRegistered) { - hiveAdaptersRegistered = true; - - // Registering Lelantus Model Adapters - Hive.registerAdapter(LelantusCoinAdapter()); - } - final wallets = await Hive.openBox('wallets'); await wallets.put('currentWalletName', testWalletName); }); @@ -1204,13 +1191,33 @@ void main() { txHash: BuildMintTxTestParams.utxoInfo["txid"] as String, coin: Coin.firo, )).thenAnswer((_) async => BuildMintTxTestParams.cachedClientResponse); + when(cachedClient.getAnonymitySet( + groupId: "1", + coin: Coin.firo, + )).thenAnswer( + (_) async => GetAnonymitySetSampleData.data, + ); + when(cachedClient.getAnonymitySet( + groupId: "2", + coin: Coin.firo, + )).thenAnswer( + (_) async => GetAnonymitySetSampleData.data, + ); when(client.getBlockHeadTip()).thenAnswer( (_) async => {"height": 455873, "hex": "this value not used here"}); + when(client.getLatestCoinId()).thenAnswer((_) async => 2); when(mainDB.getAddress("${testWalletId}buildMintTransaction", any)) .thenAnswer((realInvocation) async => null); + when(mainDB.getHighestUsedMintIndex( + walletId: "${testWalletId}submitHexToNetwork")) + .thenAnswer((_) async => null); + when(mainDB.getHighestUsedMintIndex( + walletId: "testWalletIDbuildMintTransaction")) + .thenAnswer((_) async => null); + final firo = FiroWallet( walletName: testWalletName, walletId: "${testWalletId}buildMintTransaction", diff --git a/test/services/coins/firo/firo_wallet_test.mocks.dart b/test/services/coins/firo/firo_wallet_test.mocks.dart index 95d1750e9..2365f83b1 100644 --- a/test/services/coins/firo/firo_wallet_test.mocks.dart +++ b/test/services/coins/firo/firo_wallet_test.mocks.dart @@ -1151,4 +1151,14 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override + _i5.Future getHighestUsedMintIndex({required String? walletId}) => + (super.noSuchMethod( + Invocation.method( + #getHighestUsedMintIndex, + [], + {#walletId: walletId}, + ), + returnValue: _i5.Future.value(), + ) as _i5.Future); } diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart index 74fa6e89e..35e8a2560 100644 --- a/test/widget_tests/transaction_card_test.mocks.dart +++ b/test/widget_tests/transaction_card_test.mocks.dart @@ -3496,4 +3496,14 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { returnValue: _i19.Future.value(), returnValueForMissingStub: _i19.Future.value(), ) as _i19.Future); + @override + _i19.Future getHighestUsedMintIndex({required String? walletId}) => + (super.noSuchMethod( + Invocation.method( + #getHighestUsedMintIndex, + [], + {#walletId: walletId}, + ), + returnValue: _i19.Future.value(), + ) as _i19.Future); }