diff --git a/.gitignore b/.gitignore index efa6e25e7..597ed4be4 100644 --- a/.gitignore +++ b/.gitignore @@ -101,21 +101,7 @@ pubspec.yaml # FVM Version Cache .fvm/ -android/app/src/main/jniLibs/arm64-v8a/libwownero_wallet2_api_c.so -android/app/src/main/jniLibs/arm64-v8a/libmonero_wallet2_api_c.so -android/app/src/main/jniLibs/armeabi-v7a/libmonero_wallet2_api_c.so -android/app/src/main/jniLibs/armeabi-v7a/libwownero_wallet2_api_c.so -android/app/src/main/jniLibs/x86_64/libmonero_wallet2_api_c.so -android/app/src/main/jniLibs/x86_64/libwownero_wallet2_api_c.so -macos/monero_wallet2_api_c.dylib -macos/wownero_wallet2_api_c.dylib -/macos/monero_libwallet2_api_c.dylib -/macos/wownero_libwallet2_api_c.dylib -/ios/monero_libwallet2_api_c.dylib -/ios/wownero_libwallet2_api_c.dylib -/android/app/src/main/jniLibs/arm64-v8a/libmonero_libwallet2_api_c.so -/android/app/src/main/jniLibs/armeabi-v7a/libmonero_libwallet2_api_c.so -/android/app/src/main/jniLibs/x86_64/libmonero_libwallet2_api_c.so -/android/app/src/main/jniLibs/arm64-v8a/libwownero_libwallet2_api_c.so -/android/app/src/main/jniLibs/armeabi-v7a/libwownero_libwallet2_api_c.so -/android/app/src/main/jniLibs/x86_64/libwownero_libwallet2_api_c.so +scripts/linux/build/libsecret/subprojects/gi-docgen/.meson-subproject-wrap-hash.txt + +crypto_plugins/cs_monero/built_outputs +crypto_plugins/cs_monero/build diff --git a/.gitmodules b/.gitmodules index 925be21c0..2186826df 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "crypto_plugins/flutter_libepiccash"] path = crypto_plugins/flutter_libepiccash url = https://github.com/cypherstack/flutter_libepiccash.git -[submodule "crypto_plugins/flutter_libmonero"] - path = crypto_plugins/flutter_libmonero - url = https://github.com/cypherstack/flutter_libmonero.git [submodule "crypto_plugins/flutter_liblelantus"] path = crypto_plugins/flutter_liblelantus url = https://github.com/cypherstack/flutter_liblelantus.git diff --git a/android/app/src/main/jniLibs/arm64-v8a/.gitkeep b/android/app/src/main/jniLibs/arm64-v8a/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/android/app/src/main/jniLibs/armeabi-v7a/.gitkeep b/android/app/src/main/jniLibs/armeabi-v7a/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/android/app/src/main/jniLibs/x86_64/.gitkeep b/android/app/src/main/jniLibs/x86_64/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/android/build.gradle b/android/build.gradle index 28e4d5fc8..d2ffbffa4 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,16 +1,3 @@ -buildscript { - ext.kotlin_version = '2.0.20' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - allprojects { repositories { google() @@ -18,12 +5,12 @@ allprojects { } } -rootProject.buildDir = '../build' +rootProject.buildDir = "../build" subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { - project.evaluationDependsOn(':app') + project.evaluationDependsOn(":app") } tasks.register("clean", Delete) { diff --git a/android/gradle.properties b/android/gradle.properties index 38c8d4544..7803bf46c 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,4 +1,3 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true +org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G android.useAndroidX=true -android.enableJetifier=true +android.enableJetifier=true \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 6b665338b..3c85cfe05 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip diff --git a/android/settings.gradle b/android/settings.gradle index 44e62bcf0..a38bba1fb 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,11 +1,25 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version '8.6.0' apply false + id "org.jetbrains.kotlin.android" version "1.8.22" apply false +} + +include ":app" diff --git a/asset_sources/default_themes/stack_wallet/dark.zip b/asset_sources/default_themes/stack_wallet/dark.zip index 1e5f6136e..df24199c4 100644 Binary files a/asset_sources/default_themes/stack_wallet/dark.zip and b/asset_sources/default_themes/stack_wallet/dark.zip differ diff --git a/asset_sources/default_themes/stack_wallet/light.zip b/asset_sources/default_themes/stack_wallet/light.zip index bc7a95771..9e0c82d9d 100644 Binary files a/asset_sources/default_themes/stack_wallet/light.zip and b/asset_sources/default_themes/stack_wallet/light.zip differ diff --git a/asset_sources/svg/campfire/churn.svg b/asset_sources/svg/campfire/churn.svg new file mode 100644 index 000000000..12929f15b --- /dev/null +++ b/asset_sources/svg/campfire/churn.svg @@ -0,0 +1,3 @@ + + + diff --git a/asset_sources/svg/stack_duo/churn.svg b/asset_sources/svg/stack_duo/churn.svg new file mode 100644 index 000000000..12929f15b --- /dev/null +++ b/asset_sources/svg/stack_duo/churn.svg @@ -0,0 +1,3 @@ + + + diff --git a/asset_sources/svg/stack_wallet/churn.svg b/asset_sources/svg/stack_wallet/churn.svg new file mode 100644 index 000000000..12929f15b --- /dev/null +++ b/asset_sources/svg/stack_wallet/churn.svg @@ -0,0 +1,3 @@ + + + diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index 46a7da857..1d48c0a8a 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit 46a7da857d4113eb3998567b18ac0b33a470f4fd +Subproject commit 1d48c0a8aa394324e7c39267e5654038834aff95 diff --git a/crypto_plugins/flutter_liblelantus b/crypto_plugins/flutter_liblelantus index f8746dbef..8e9e20e2f 160000 --- a/crypto_plugins/flutter_liblelantus +++ b/crypto_plugins/flutter_liblelantus @@ -1 +1 @@ -Subproject commit f8746dbef5c5ad5ed2dad12f615723d087083e9c +Subproject commit 8e9e20e2f90387dcc6e23833d186a84ad3ac372a diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero deleted file mode 160000 index 52bdb85f0..000000000 --- a/crypto_plugins/flutter_libmonero +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 52bdb85f0a87793327a794aba477ac8b967c315f diff --git a/crypto_plugins/frostdart b/crypto_plugins/frostdart index 2a74a97fb..2451deab8 160000 --- a/crypto_plugins/frostdart +++ b/crypto_plugins/frostdart @@ -1 +1 @@ -Subproject commit 2a74a97fb0f0e22a5280b22c010b710cdeec33bb +Subproject commit 2451deab817b456ad93d5579c0d0687cb681392a diff --git a/docs/building.md b/docs/building.md index 614282512..492639b05 100644 --- a/docs/building.md +++ b/docs/building.md @@ -13,12 +13,12 @@ Here you will find instructions on how to install the necessary tools for buildi The following instructions are for building and running on a Linux host. Alternatively, see the [Mac](#mac-host) and/or [Windows](#windows-host) section. This entire section (except for the Android Studio section) needs to be completed in WSL if building on a Windows host. ### Flutter -Install Flutter 3.24.2 by [following their guide](https://docs.flutter.dev/get-started/install/linux/desktop?tab=download#install-the-flutter-sdk). You can also clone https://github.com/flutter/flutter, check out the `3.24.2` tag, and add its `flutter/bin` folder to your PATH as in +Install Flutter 3.24.3 by [following their guide](https://docs.flutter.dev/get-started/install/linux/desktop?tab=download#install-the-flutter-sdk). You can also clone https://github.com/flutter/flutter, check out the `3.24.3` tag, and add its `flutter/bin` folder to your PATH as in ```sh FLUTTER_DIR="$HOME/development/flutter" git clone https://github.com/flutter/flutter.git "$FLUTTER_DIR" cd "$FLUTTER_DIR" -git checkout 3.24.2 +git checkout 3.24.3 echo 'export PATH="$PATH:'"$FLUTTER_DIR"'/bin"' >> "$HOME/.profile" source "$HOME/.profile" flutter precache @@ -93,6 +93,7 @@ rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-andro Linux desktop specific dependencies: ``` sudo apt-get install clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev meson python3-pip libgirepository1.0-dev valac xsltproc docbook-xsl +pip3 install --upgrade meson==0.64.1 markdown==3.4.1 markupsafe==2.1.1 jinja2==3.1.2 pygments==2.13.0 toml==0.10.2 typogrify==2.0.7 tomli==2.0.1 ``` ### Clone the repository and initialize submodules @@ -242,7 +243,7 @@ rustup target add aarch64-apple-ios aarch64-apple-darwin Optionally download [Android Studio](https://developer.android.com/studio) as an IDE and activate its Dart and Flutter plugins. VS Code may work as an alternative, but this is not recommended. ### Flutter -Install [Flutter](https://docs.flutter.dev/get-started/install) 3.24.2 on your Mac host by following [these instructions](https://docs.flutter.dev/get-started/install/macos). Run `flutter doctor` in a terminal to confirm its installation. +Install [Flutter](https://docs.flutter.dev/get-started/install) 3.24.3 on your Mac host by following [these instructions](https://docs.flutter.dev/get-started/install/macos). Run `flutter doctor` in a terminal to confirm its installation. ### Build plugins and configure #### Building plugins for iOS @@ -312,13 +313,13 @@ If the DLLs were built on the WSL filesystem instead of on Windows, copy the res Frostdart will be built by the Windows host later. ### Install Flutter on Windows host -Install Flutter 3.24.2 on your Windows host (not in WSL2) by [following their guide](https://docs.flutter.dev/get-started/install/windows/desktop?tab=download#install-the-flutter-sdk) or by cloning https://github.com/flutter/flutter, checking out the `3.24.2` tag, and adding its `flutter/bin` folder to your PATH as in +Install Flutter 3.24.3 on your Windows host (not in WSL2) by [following their guide](https://docs.flutter.dev/get-started/install/windows/desktop?tab=download#install-the-flutter-sdk) or by cloning https://github.com/flutter/flutter, checking out the `3.24.3` tag, and adding its `flutter/bin` folder to your PATH as in ```bat @echo off set "FLUTTER_DIR=%USERPROFILE%\development\flutter" git clone https://github.com/flutter/flutter.git "%FLUTTER_DIR%" cd /d "%FLUTTER_DIR%" -git checkout 3.24.2 +git checkout 3.24.3 setx PATH "%PATH%;%FLUTTER_DIR%\bin" echo Flutter setup completed. Please restart your command prompt. ``` diff --git a/ios/MoneroWallet.framework/.gitignore b/ios/MoneroWallet.framework/.gitignore deleted file mode 100644 index 38de9b351..000000000 --- a/ios/MoneroWallet.framework/.gitignore +++ /dev/null @@ -1 +0,0 @@ -MoneroWallet \ No newline at end of file diff --git a/ios/MoneroWallet.framework/Info.plist b/ios/MoneroWallet.framework/Info.plist deleted file mode 100644 index de2be3211..000000000 --- a/ios/MoneroWallet.framework/Info.plist +++ /dev/null @@ -1,57 +0,0 @@ - - - - - BuildMachineOSBuild - 23E224 - CFBundleDevelopmentRegion - en - CFBundleExecutable - MoneroWallet - CFBundleIdentifier - com.cypherstack.MoneroWallet - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - MoneroWallet - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ??? - CFBundleSupportedPlatforms - - iPhoneOS - - CFBundleVersion - 1 - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 21E210 - DTPlatformName - iphoneos - DTPlatformVersion - 17.4 - DTSDKBuild - 21E210 - DTSDKName - iphoneos17.4 - DTXcode - 1530 - DTXcodeBuild - 15E204a - MinimumOSVersion - 16.0 - UIDeviceFamily - - 1 - 2 - - UIRequiredDeviceCapabilities - - arm64 - - - diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5607f33db..4ca2f124b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -9,6 +9,8 @@ PODS: - connectivity_plus (0.0.1): - Flutter - ReachabilitySwift + - cs_monero_flutter_libs (0.0.1): + - Flutter - device_info_plus (0.0.1): - Flutter - devicelocale (0.0.1): @@ -50,8 +52,6 @@ PODS: - Flutter (1.0.0) - flutter_libepiccash (0.0.1): - Flutter - - flutter_libmonero (0.0.1): - - Flutter - flutter_libsparkmobile (0.0.1): - Flutter - flutter_local_notifications (0.0.1): @@ -67,15 +67,16 @@ PODS: - Flutter - lelantus (0.0.1): - Flutter - - local_auth (0.0.1): + - local_auth_darwin (0.0.1): - Flutter + - FlutterMacOS - MTBBarcodeScanner (5.0.11) - package_info_plus (0.4.5): - Flutter - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - - permission_handler_apple (9.1.1): + - permission_handler_apple (9.3.0): - Flutter - ReachabilitySwift (5.0.0) - SDWebImage (5.13.2): @@ -86,6 +87,8 @@ PODS: - "sqlite3 (3.46.0+1)": - "sqlite3/common (= 3.46.0+1)" - "sqlite3/common (3.46.0+1)" + - "sqlite3/dbstatvtab (3.46.0+1)": + - sqlite3/common - "sqlite3/fts5 (3.46.0+1)": - sqlite3/common - "sqlite3/perf-threadsafe (3.46.0+1)": @@ -94,7 +97,8 @@ PODS: - sqlite3/common - sqlite3_flutter_libs (0.0.1): - Flutter - - sqlite3 (~> 3.46.0) + - "sqlite3 (~> 3.46.0+1)" + - sqlite3/dbstatvtab - sqlite3/fts5 - sqlite3/perf-threadsafe - sqlite3/rtree @@ -106,19 +110,19 @@ PODS: - Flutter - url_launcher_ios (0.0.1): - Flutter - - wakelock (0.0.1): + - wakelock_plus (0.0.1): - Flutter DEPENDENCIES: - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`) - coinlib_flutter (from `.symlinks/plugins/coinlib_flutter/darwin`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) + - cs_monero_flutter_libs (from `.symlinks/plugins/cs_monero_flutter_libs/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - Flutter (from `Flutter`) - flutter_libepiccash (from `.symlinks/plugins/flutter_libepiccash/ios`) - - flutter_libmonero (from `.symlinks/plugins/flutter_libmonero/ios`) - flutter_libsparkmobile (from `.symlinks/plugins/flutter_libsparkmobile/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) @@ -127,7 +131,7 @@ DEPENDENCIES: - integration_test (from `.symlinks/plugins/integration_test/ios`) - isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`) - lelantus (from `.symlinks/plugins/lelantus/ios`) - - local_auth (from `.symlinks/plugins/local_auth/ios`) + - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) @@ -136,7 +140,7 @@ DEPENDENCIES: - stack_wallet_backup (from `.symlinks/plugins/stack_wallet_backup/ios`) - tor_ffi_plugin (from `.symlinks/plugins/tor_ffi_plugin/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - - wakelock (from `.symlinks/plugins/wakelock/ios`) + - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) SPEC REPOS: trunk: @@ -156,6 +160,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/coinlib_flutter/darwin" connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/ios" + cs_monero_flutter_libs: + :path: ".symlinks/plugins/cs_monero_flutter_libs/ios" device_info_plus: :path: ".symlinks/plugins/device_info_plus/ios" devicelocale: @@ -166,8 +172,6 @@ EXTERNAL SOURCES: :path: Flutter flutter_libepiccash: :path: ".symlinks/plugins/flutter_libepiccash/ios" - flutter_libmonero: - :path: ".symlinks/plugins/flutter_libmonero/ios" flutter_libsparkmobile: :path: ".symlinks/plugins/flutter_libsparkmobile/ios" flutter_local_notifications: @@ -184,8 +188,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/isar_flutter_libs/ios" lelantus: :path: ".symlinks/plugins/lelantus/ios" - local_auth: - :path: ".symlinks/plugins/local_auth/ios" + local_auth_darwin: + :path: ".symlinks/plugins/local_auth_darwin/darwin" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: @@ -202,45 +206,45 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/tor_ffi_plugin/ios" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" - wakelock: - :path: ".symlinks/plugins/wakelock/ios" + wakelock_plus: + :path: ".symlinks/plugins/wakelock_plus/ios" SPEC CHECKSUMS: barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0 coinlib_flutter: 9275e8255ef67d3da33beb6e117d09ced4f46eb5 connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a + cs_monero_flutter_libs: 43cda3474c2bc907f2b2b5bb26fd89cb864fcfc6 device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d - devicelocale: b22617f40038496deffba44747101255cee005b0 + devicelocale: 35ba84dc7f45f527c3001535d8c8d104edd5d926 DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_libepiccash: 36241aa7d3126f6521529985ccb3dc5eaf7bb317 - flutter_libmonero: da68a616b73dd0374a8419c684fa6b6df2c44ffe flutter_libsparkmobile: 6373955cc3327a926d17059e7405dde2fb12f99f flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086 flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be frostdart: 4c72b69ccac2f13ede744107db046a125acce597 integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 - isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073 + isar_flutter_libs: fdf730ca925d05687f36d7f1d355e482529ed097 lelantus: 417f0221260013dfc052cae9cf4b741b6479edba - local_auth: 1740f55d7af0a2e2a8684ce225fe79d8931e808c + local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3 MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb - package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7 - path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 - permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 + package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 SDWebImage: 72f86271a6f3139cc7e4a89220946489d4b9a866 - share_plus: 599aa54e4ea31d4b4c0e9c911bcc26c55e791028 + share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5 sqlite3: 292c3e1bfe89f64e51ea7fc7dab9182a017c8630 - sqlite3_flutter_libs: 0d611efdf6d1c9297d5ab03dab21b75aeebdae31 + sqlite3_flutter_libs: c00457ebd31e59fa6bb830380ddba24d44fbcd3b stack_wallet_backup: 5b8563aba5d8ffbf2ce1944331ff7294a0ec7c03 SwiftProtobuf: 6ef3f0e422ef90d6605ca20b21a94f6c1324d6b3 SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780 tor_ffi_plugin: d80e291b649379c8176e1be739e49be007d4ef93 - url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 - wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f + url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe + wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1 PODFILE CHECKSUM: 57c8aed26fba39d3ec9424816221f294a07c58eb diff --git a/ios/WowneroWallet.framework/.gitignore b/ios/WowneroWallet.framework/.gitignore deleted file mode 100644 index 98afbebec..000000000 --- a/ios/WowneroWallet.framework/.gitignore +++ /dev/null @@ -1 +0,0 @@ -WowneroWallet \ No newline at end of file diff --git a/ios/WowneroWallet.framework/Info.plist b/ios/WowneroWallet.framework/Info.plist deleted file mode 100644 index d1d435920..000000000 --- a/ios/WowneroWallet.framework/Info.plist +++ /dev/null @@ -1,57 +0,0 @@ - - - - - BuildMachineOSBuild - 23E224 - CFBundleDevelopmentRegion - en - CFBundleExecutable - WowneroWallet - CFBundleIdentifier - com.cypherstack.WowneroWallet - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - WowneroWallet - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ??? - CFBundleSupportedPlatforms - - iPhoneOS - - CFBundleVersion - 1 - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 21E210 - DTPlatformName - iphoneos - DTPlatformVersion - 17.4 - DTSDKBuild - 21E210 - DTSDKName - iphoneos17.4 - DTXcode - 1530 - DTXcodeBuild - 15E204a - MinimumOSVersion - 16.0 - UIDeviceFamily - - 1 - 2 - - UIRequiredDeviceCapabilities - - arm64 - - - diff --git a/lib/app_config.dart b/lib/app_config.dart index 5f9a95829..62ce560c3 100644 --- a/lib/app_config.dart +++ b/lib/app_config.dart @@ -27,6 +27,8 @@ abstract class AppConfig { static List get coins => _supportedCoins; + static ({String from, String to}) get swapDefaults => _swapDefaults; + static bool get isSingleCoinApp => coins.length == 1; static CryptoCurrency? getCryptoCurrencyFor(String coinIdentifier) { diff --git a/lib/db/hive/db.dart b/lib/db/hive/db.dart index 1e4c670e1..c71826fbc 100644 --- a/lib/db/hive/db.dart +++ b/lib/db/hive/db.dart @@ -10,7 +10,7 @@ import 'dart:isolate'; -import 'package:cw_core/wallet_info.dart' as xmr; +import 'package:compat/compat.dart' as lib_monero_compat; import 'package:hive/hive.dart' show Box; import 'package:hive/src/hive_impl.dart'; import 'package:mutex/mutex.dart'; @@ -71,7 +71,7 @@ class DB { Box? _boxTradesV2; Box? _boxTradeNotes; Box? _boxFavoriteWallets; - Box? _walletInfoSource; + Box? _walletInfoSource; Box? _boxPrefs; Box? _boxTradeLookup; Box? _boxDBInfo; @@ -85,7 +85,8 @@ class DB { final Map> _getSparkUsedCoinsTagsCacheBoxes = {}; // exposed for monero - Box get moneroWalletInfoBox => _walletInfoSource!; + Box get moneroWalletInfoBox => + _walletInfoSource!; // mutex for stack backup final mutex = Mutex(); @@ -147,8 +148,8 @@ class DB { _boxTradesV2 = await hive.openBox(boxNameTradesV2); _boxTradeNotes = await hive.openBox(boxNameTradeNotes); _boxTradeLookup = await hive.openBox(boxNameTradeLookup); - _walletInfoSource = - await hive.openBox(xmr.WalletInfo.boxName); + _walletInfoSource = await hive.openBox( + lib_monero_compat.WalletInfo.boxName); _boxFavoriteWallets = await hive.openBox(boxNameFavoriteWallets); await Future.wait([ diff --git a/lib/db/sqlite/firo_cache_writer.dart b/lib/db/sqlite/firo_cache_writer.dart index d42c48834..99d318444 100644 --- a/lib/db/sqlite/firo_cache_writer.dart +++ b/lib/db/sqlite/firo_cache_writer.dart @@ -19,8 +19,8 @@ FCResult _updateSparkUsedTagsWith( ) { // hash the tags here since this function is called in a background isolate final hashedTags = LibSpark.hashTags( - base64Tags: tags.map((e) => e[0] as String), - ); + base64Tags: tags.map((e) => e[0] as String).toSet(), + ).toList(); if (hashedTags.isEmpty) { // nothing to add, return early diff --git a/lib/electrumx_rpc/client_manager.dart b/lib/electrumx_rpc/client_manager.dart index 662c218ea..fb8b920cc 100644 --- a/lib/electrumx_rpc/client_manager.dart +++ b/lib/electrumx_rpc/client_manager.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'package:electrum_adapter/electrum_adapter.dart'; + +import '../utilities/logger.dart'; import '../wallets/crypto_currency/crypto_currency.dart'; class ClientManager { @@ -37,13 +39,19 @@ class ClientManager { } _heightCompleters[key] = Completer(); - _subscriptions[key] = client.subscribeHeaders().listen((event) { - _heights[key] = event.height; + _subscriptions[key] = client.subscribeHeaders().listen( + (event) { + _heights[key] = event.height; - if (!_heightCompleters[key]!.isCompleted) { - _heightCompleters[key]!.complete(event.height); - } - }); + if (!_heightCompleters[key]!.isCompleted) { + _heightCompleters[key]!.complete(event.height); + } + }, + onError: (Object err, StackTrace s) => Logging.instance.log( + "ClientManager listen: $err\n$s", + level: LogLevel.Error, + ), + ); } Future getChainHeightFor(CryptoCurrency cryptoCurrency) async { diff --git a/lib/electrumx_rpc/electrumx_client.dart b/lib/electrumx_rpc/electrumx_client.dart index c31a8eac5..bceb03fac 100644 --- a/lib/electrumx_rpc/electrumx_client.dart +++ b/lib/electrumx_rpc/electrumx_client.dart @@ -490,7 +490,15 @@ class ElectrumXClient { command: 'server.ping', requestTimeout: const Duration(seconds: 2), retries: retryCount, - ).timeout(const Duration(seconds: 2)) as bool; + ).timeout( + const Duration(seconds: 2), + onTimeout: () { + Logging.instance.log( + "ElectrumxClient.ping timed out with retryCount=$retryCount, host=$_host", + level: LogLevel.Debug, + ); + }, + ) as bool; } catch (e) { rethrow; } diff --git a/lib/main.dart b/lib/main.dart index c7b3fccac..e2cae6f72 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -13,15 +13,11 @@ import 'dart:io'; import 'dart:math'; import 'package:coinlib_flutter/coinlib_flutter.dart'; -import 'package:cw_core/node.dart'; -import 'package:cw_core/pathForWallet.dart'; -import 'package:cw_core/unspent_coins_info.dart'; -import 'package:cw_core/wallet_info.dart'; -import 'package:cw_core/wallet_type.dart'; +import 'package:compat/compat.dart' as lib_monero_compat; +import 'package:cs_monero/cs_monero.dart' as lib_monero; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_libmonero/monero/monero.dart'; -import 'package:flutter_libmonero/wownero/wownero.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -94,12 +90,6 @@ void main(List args) async { StackFileSystem.setDesktopOverrideDir(args.last); } - // Tell flutter_libmonero how to get access to the application dir - FS.setApplicationRootDirectoryFunction( - StackFileSystem.applicationRootDirectory, - ); - // TODO set any other external libs file paths (bad external lib design workaround) - final loadCoinlibFuture = loadCoinlib(); GoogleFonts.config.allowRuntimeFetching = false; @@ -172,15 +162,14 @@ void main(List args) async { // node model adapter DB.instance.hive.registerAdapter(NodeModelAdapter()); - DB.instance.hive.registerAdapter(NodeAdapter()); - - if (!DB.instance.hive.isAdapterRegistered(WalletInfoAdapter().typeId)) { - DB.instance.hive.registerAdapter(WalletInfoAdapter()); + if (!DB.instance.hive + .isAdapterRegistered(lib_monero_compat.WalletInfoAdapter().typeId)) { + DB.instance.hive.registerAdapter(lib_monero_compat.WalletInfoAdapter()); } - DB.instance.hive.registerAdapter(WalletTypeAdapter()); + DB.instance.hive.registerAdapter(lib_monero_compat.WalletTypeAdapter()); - DB.instance.hive.registerAdapter(UnspentCoinsInfoAdapter()); + lib_monero.Logging.useLogger = kDebugMode; DB.instance.hive.init( (await StackFileSystem.applicationHiveDirectory()).path, @@ -237,9 +226,6 @@ void main(List args) async { } } - monero.onStartup(); - wownero.onStartup(); - // SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, // overlays: [SystemUiOverlay.bottom]); unawaited(NotificationApi.init()); diff --git a/lib/models/isar/exchange_cache/currency.g.dart b/lib/models/isar/exchange_cache/currency.g.dart index 8f81bfdc0..89d93a11d 100644 --- a/lib/models/isar/exchange_cache/currency.g.dart +++ b/lib/models/isar/exchange_cache/currency.g.dart @@ -7,7 +7,7 @@ part of 'currency.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetCurrencyCollection on Isar { IsarCollection get currencies => this.collection(); @@ -135,7 +135,7 @@ const CurrencySchema = CollectionSchema( getId: _currencyGetId, getLinks: _currencyGetLinks, attach: _currencyAttach, - version: '3.0.5', + version: '3.1.8', ); int _currencyEstimateSize( diff --git a/lib/models/isar/exchange_cache/pair.g.dart b/lib/models/isar/exchange_cache/pair.g.dart index eae9ee5b5..0f9b6435d 100644 --- a/lib/models/isar/exchange_cache/pair.g.dart +++ b/lib/models/isar/exchange_cache/pair.g.dart @@ -7,7 +7,7 @@ part of 'pair.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetPairCollection on Isar { IsarCollection get pairs => this.collection(); @@ -92,7 +92,7 @@ const PairSchema = CollectionSchema( getId: _pairGetId, getLinks: _pairGetLinks, attach: _pairAttach, - version: '3.0.5', + version: '3.1.8', ); int _pairEstimateSize( diff --git a/lib/models/isar/models/address_label.g.dart b/lib/models/isar/models/address_label.g.dart index 2a6b41e70..a87af5963 100644 --- a/lib/models/isar/models/address_label.g.dart +++ b/lib/models/isar/models/address_label.g.dart @@ -7,7 +7,7 @@ part of 'address_label.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetAddressLabelCollection on Isar { IsarCollection get addressLabels => this.collection(); @@ -81,7 +81,7 @@ const AddressLabelSchema = CollectionSchema( getId: _addressLabelGetId, getLinks: _addressLabelGetLinks, attach: _addressLabelAttach, - version: '3.0.5', + version: '3.1.8', ); int _addressLabelEstimateSize( diff --git a/lib/models/isar/models/block_explorer.g.dart b/lib/models/isar/models/block_explorer.g.dart index f524392d5..0c4be65bc 100644 --- a/lib/models/isar/models/block_explorer.g.dart +++ b/lib/models/isar/models/block_explorer.g.dart @@ -7,7 +7,7 @@ part of 'block_explorer.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetTransactionBlockExplorerCollection on Isar { IsarCollection get transactionBlockExplorers => @@ -54,7 +54,7 @@ const TransactionBlockExplorerSchema = CollectionSchema( getId: _transactionBlockExplorerGetId, getLinks: _transactionBlockExplorerGetLinks, attach: _transactionBlockExplorerAttach, - version: '3.0.5', + version: '3.1.8', ); int _transactionBlockExplorerEstimateSize( diff --git a/lib/models/isar/models/blockchain_data/address.dart b/lib/models/isar/models/blockchain_data/address.dart index bcc7d22c5..584636050 100644 --- a/lib/models/isar/models/blockchain_data/address.dart +++ b/lib/models/isar/models/blockchain_data/address.dart @@ -11,6 +11,7 @@ import 'dart:convert'; import 'package:isar/isar.dart'; + import '../../../../exceptions/address/address_exception.dart'; import 'crypto_currency_address.dart'; import 'transaction.dart'; @@ -27,6 +28,7 @@ class Address extends CryptoCurrencyAddress { required this.derivationPath, required this.type, required this.subType, + this.zSafeFrost, this.otherData, }); @@ -55,6 +57,8 @@ class Address extends CryptoCurrencyAddress { final transactions = IsarLinks(); + late final bool? zSafeFrost; + int derivationChain() { if (subType == AddressSubType.receiving) { return 0; // 0 for receiving (external) @@ -80,6 +84,7 @@ class Address extends CryptoCurrencyAddress { AddressType? type, AddressSubType? subType, DerivationPath? derivationPath, + bool? zSafeFrost, String? otherData, }) { return Address( @@ -90,6 +95,7 @@ class Address extends CryptoCurrencyAddress { type: type ?? this.type, subType: subType ?? this.subType, derivationPath: derivationPath ?? this.derivationPath, + zSafeFrost: zSafeFrost ?? this.zSafeFrost, otherData: otherData ?? this.otherData, ); } @@ -105,6 +111,7 @@ class Address extends CryptoCurrencyAddress { "subType: ${subType.name}, " "transactionsLength: ${transactions.length} " "derivationPath: $derivationPath, " + "zSafeFrost: $zSafeFrost, " "otherData: $otherData, " "}"; @@ -117,6 +124,7 @@ class Address extends CryptoCurrencyAddress { "type": type.name, "subType": subType.name, "derivationPath": derivationPath?.value, + "zSafeFrost": zSafeFrost, "otherData": otherData, }; return jsonEncode(result); @@ -143,6 +151,7 @@ class Address extends CryptoCurrencyAddress { derivationPath: derivationPath, type: AddressType.values.byName(json["type"] as String), subType: AddressSubType.values.byName(json["subType"] as String), + zSafeFrost: json["zSafeFrost"] as bool?, otherData: json["otherData"] as String?, ); } @@ -165,7 +174,8 @@ enum AddressType { tezos, frostMS, p2tr, - solana; + solana, + cardanoShelley; String get readableName { switch (this) { @@ -201,6 +211,8 @@ enum AddressType { return "Solana"; case AddressType.p2tr: return "P2TR (taproot)"; + case AddressType.cardanoShelley: + return "Cardano Shelley"; } } } diff --git a/lib/models/isar/models/blockchain_data/address.g.dart b/lib/models/isar/models/blockchain_data/address.g.dart index 7e78cbee8..092198990 100644 --- a/lib/models/isar/models/blockchain_data/address.g.dart +++ b/lib/models/isar/models/blockchain_data/address.g.dart @@ -7,7 +7,7 @@ part of 'address.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetAddressCollection on Isar { IsarCollection
get addresses => this.collection(); @@ -59,6 +59,11 @@ const AddressSchema = CollectionSchema( id: 7, name: r'walletId', type: IsarType.string, + ), + r'zSafeFrost': PropertySchema( + id: 8, + name: r'zSafeFrost', + type: IsarType.bool, ) }, estimateSize: _addressEstimateSize, @@ -124,7 +129,7 @@ const AddressSchema = CollectionSchema( getId: _addressGetId, getLinks: _addressGetLinks, attach: _addressAttach, - version: '3.0.5', + version: '3.1.8', ); int _addressEstimateSize( @@ -172,6 +177,7 @@ void _addressSerialize( writer.writeByte(offsets[5], object.type.index); writer.writeString(offsets[6], object.value); writer.writeString(offsets[7], object.walletId); + writer.writeBool(offsets[8], object.zSafeFrost); } Address _addressDeserialize( @@ -195,6 +201,7 @@ Address _addressDeserialize( AddressType.p2pkh, value: reader.readString(offsets[6]), walletId: reader.readString(offsets[7]), + zSafeFrost: reader.readBoolOrNull(offsets[8]), ); object.id = id; return object; @@ -229,6 +236,8 @@ P _addressDeserializeProp

( return (reader.readString(offset)) as P; case 7: return (reader.readString(offset)) as P; + case 8: + return (reader.readBoolOrNull(offset)) as P; default: throw IsarError('Unknown property with id $propertyId'); } @@ -1474,6 +1483,32 @@ extension AddressQueryFilter )); }); } + + QueryBuilder zSafeFrostIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'zSafeFrost', + )); + }); + } + + QueryBuilder zSafeFrostIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'zSafeFrost', + )); + }); + } + + QueryBuilder zSafeFrostEqualTo( + bool? value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'zSafeFrost', + value: value, + )); + }); + } } extension AddressQueryObject @@ -1621,6 +1656,18 @@ extension AddressQuerySortBy on QueryBuilder { return query.addSortBy(r'walletId', Sort.desc); }); } + + QueryBuilder sortByZSafeFrost() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'zSafeFrost', Sort.asc); + }); + } + + QueryBuilder sortByZSafeFrostDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'zSafeFrost', Sort.desc); + }); + } } extension AddressQuerySortThenBy @@ -1708,6 +1755,18 @@ extension AddressQuerySortThenBy return query.addSortBy(r'walletId', Sort.desc); }); } + + QueryBuilder thenByZSafeFrost() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'zSafeFrost', Sort.asc); + }); + } + + QueryBuilder thenByZSafeFrostDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'zSafeFrost', Sort.desc); + }); + } } extension AddressQueryWhereDistinct @@ -1756,6 +1815,12 @@ extension AddressQueryWhereDistinct return query.addDistinctBy(r'walletId', caseSensitive: caseSensitive); }); } + + QueryBuilder distinctByZSafeFrost() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'zSafeFrost'); + }); + } } extension AddressQueryProperty @@ -1814,6 +1879,12 @@ extension AddressQueryProperty return query.addPropertyName(r'walletId'); }); } + + QueryBuilder zSafeFrostProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'zSafeFrost'); + }); + } } // ************************************************************************** @@ -1821,7 +1892,7 @@ extension AddressQueryProperty // ************************************************************************** // 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 +// 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, always_specify_types const DerivationPathSchema = Schema( name: r'DerivationPath', diff --git a/lib/models/isar/models/blockchain_data/input.g.dart b/lib/models/isar/models/blockchain_data/input.g.dart index 608446fea..a08dc7637 100644 --- a/lib/models/isar/models/blockchain_data/input.g.dart +++ b/lib/models/isar/models/blockchain_data/input.g.dart @@ -7,7 +7,7 @@ part of 'input.dart'; // ************************************************************************** // 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 +// 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, always_specify_types const InputSchema = Schema( name: r'Input', diff --git a/lib/models/isar/models/blockchain_data/output.g.dart b/lib/models/isar/models/blockchain_data/output.g.dart index 5e3bbf02d..6a5812373 100644 --- a/lib/models/isar/models/blockchain_data/output.g.dart +++ b/lib/models/isar/models/blockchain_data/output.g.dart @@ -7,7 +7,7 @@ part of 'output.dart'; // ************************************************************************** // 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 +// 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, always_specify_types const OutputSchema = Schema( name: r'Output', diff --git a/lib/models/isar/models/blockchain_data/transaction.g.dart b/lib/models/isar/models/blockchain_data/transaction.g.dart index 965a64870..0d34d133d 100644 --- a/lib/models/isar/models/blockchain_data/transaction.g.dart +++ b/lib/models/isar/models/blockchain_data/transaction.g.dart @@ -7,7 +7,7 @@ part of 'transaction.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetTransactionCollection on Isar { IsarCollection get transactions => this.collection(); @@ -171,7 +171,7 @@ const TransactionSchema = CollectionSchema( getId: _transactionGetId, getLinks: _transactionGetLinks, attach: _transactionAttach, - version: '3.0.5', + version: '3.1.8', ); int _transactionEstimateSize( diff --git a/lib/models/isar/models/blockchain_data/utxo.dart b/lib/models/isar/models/blockchain_data/utxo.dart index 7bbf50896..dd492d9b8 100644 --- a/lib/models/isar/models/blockchain_data/utxo.dart +++ b/lib/models/isar/models/blockchain_data/utxo.dart @@ -8,6 +8,7 @@ * */ +import 'dart:convert'; import 'dart:math'; import 'package:isar/isar.dart'; @@ -84,6 +85,20 @@ class UTXO { return confirmations >= minimumConfirms; } + @ignore + String? get keyImage { + if (otherData == null) { + return null; + } + + try { + final map = jsonDecode(otherData!) as Map; + return map["keyImage"] as String; + } catch (_) { + return null; + } + } + UTXO copyWith({ Id? id, String? walletId, diff --git a/lib/models/isar/models/blockchain_data/utxo.g.dart b/lib/models/isar/models/blockchain_data/utxo.g.dart index b12e9b470..0d2a0fcd7 100644 --- a/lib/models/isar/models/blockchain_data/utxo.g.dart +++ b/lib/models/isar/models/blockchain_data/utxo.g.dart @@ -7,7 +7,7 @@ part of 'utxo.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetUTXOCollection on Isar { IsarCollection get utxos => this.collection(); @@ -149,7 +149,7 @@ const UTXOSchema = CollectionSchema( getId: _uTXOGetId, getLinks: _uTXOGetLinks, attach: _uTXOAttach, - version: '3.0.5', + version: '3.1.8', ); int _uTXOEstimateSize( diff --git a/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart b/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart index c1a3b781b..fb0e9dd61 100644 --- a/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart +++ b/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart @@ -7,7 +7,7 @@ part of 'input_v2.dart'; // ************************************************************************** // 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 +// 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, always_specify_types const OutpointV2Schema = Schema( name: r'OutpointV2', @@ -330,7 +330,7 @@ extension OutpointV2QueryObject on QueryBuilder {} // 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 +// 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, always_specify_types const InputV2Schema = Schema( name: r'InputV2', diff --git a/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart b/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart index e26075d44..539ad6dbd 100644 --- a/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart +++ b/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart @@ -7,7 +7,7 @@ part of 'output_v2.dart'; // ************************************************************************** // 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 +// 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, always_specify_types const OutputV2Schema = Schema( name: r'OutputV2', diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart index 465dd3b13..4582ef47d 100644 --- a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart @@ -134,6 +134,14 @@ class TransactionV2 { } Amount getAmountReceivedInThisWallet({required int fractionDigits}) { + if (_isMonero()) { + if (type == TransactionType.incoming) { + return _getMoneroAmount()!; + } else { + return Amount.zeroWith(fractionDigits: fractionDigits); + } + } + final outSum = outputs .where((e) => e.walletOwns) .fold(BigInt.zero, (p, e) => p + e.value); @@ -151,6 +159,14 @@ class TransactionV2 { } Amount getAmountSentFromThisWallet({required int fractionDigits}) { + if (_isMonero()) { + if (type == TransactionType.outgoing) { + return _getMoneroAmount()!; + } else { + return Amount.zeroWith(fractionDigits: fractionDigits); + } + } + final inSum = inputs .where((e) => e.walletOwns) .fold(BigInt.zero, (p, e) => p + e.value); @@ -191,6 +207,21 @@ class TransactionV2 { } } + Amount? _getMoneroAmount() { + try { + return Amount.fromSerializedJsonString( + _getFromOtherData(key: TxV2OdKeys.moneroAmount) as String, + ); + } catch (_) { + return null; + } + } + + bool _isMonero() { + final value = _getFromOtherData(key: TxV2OdKeys.isMoneroTransaction); + return value is bool ? value : false; + } + String statusLabel({ required int currentChainHeight, required int minConfirms, @@ -307,4 +338,7 @@ abstract final class TxV2OdKeys { static const contractAddress = "contractAddress"; static const nonce = "nonce"; static const overrideFee = "overrideFee"; + static const moneroAmount = "moneroAmount"; + static const moneroAccountIndex = "moneroAccountIndex"; + static const isMoneroTransaction = "isMoneroTransaction"; } diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart index 83006da89..68d8a18c5 100644 --- a/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart @@ -7,7 +7,7 @@ part of 'transaction_v2.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetTransactionV2Collection on Isar { IsarCollection get transactionV2s => this.collection(); @@ -177,7 +177,7 @@ const TransactionV2Schema = CollectionSchema( getId: _transactionV2GetId, getLinks: _transactionV2GetLinks, attach: _transactionV2Attach, - version: '3.0.5', + version: '3.1.8', ); int _transactionV2EstimateSize( diff --git a/lib/models/isar/models/contact_entry.g.dart b/lib/models/isar/models/contact_entry.g.dart index dc1eb2b61..282112f55 100644 --- a/lib/models/isar/models/contact_entry.g.dart +++ b/lib/models/isar/models/contact_entry.g.dart @@ -7,7 +7,7 @@ part of 'contact_entry.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetContactEntryCollection on Isar { IsarCollection get contactEntrys => this.collection(); @@ -69,7 +69,7 @@ const ContactEntrySchema = CollectionSchema( getId: _contactEntryGetId, getLinks: _contactEntryGetLinks, attach: _contactEntryAttach, - version: '3.0.5', + version: '3.1.8', ); int _contactEntryEstimateSize( @@ -1142,7 +1142,7 @@ extension ContactEntryQueryProperty // ************************************************************************** // 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 +// 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, always_specify_types const ContactAddressEntrySchema = Schema( name: r'ContactAddressEntry', diff --git a/lib/models/isar/models/encrypted_string_value.g.dart b/lib/models/isar/models/encrypted_string_value.g.dart index fdfe5527a..5b3490dcc 100644 --- a/lib/models/isar/models/encrypted_string_value.g.dart +++ b/lib/models/isar/models/encrypted_string_value.g.dart @@ -7,7 +7,7 @@ part of 'encrypted_string_value.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetEncryptedStringValueCollection on Isar { IsarCollection get encryptedStringValues => @@ -54,7 +54,7 @@ const EncryptedStringValueSchema = CollectionSchema( getId: _encryptedStringValueGetId, getLinks: _encryptedStringValueGetLinks, attach: _encryptedStringValueAttach, - version: '3.0.5', + version: '3.1.8', ); int _encryptedStringValueEstimateSize( diff --git a/lib/models/isar/models/ethereum/eth_contract.g.dart b/lib/models/isar/models/ethereum/eth_contract.g.dart index bc9548e8d..fcb1af11d 100644 --- a/lib/models/isar/models/ethereum/eth_contract.g.dart +++ b/lib/models/isar/models/ethereum/eth_contract.g.dart @@ -7,7 +7,7 @@ part of 'eth_contract.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetEthContractCollection on Isar { IsarCollection get ethContracts => this.collection(); @@ -74,7 +74,7 @@ const EthContractSchema = CollectionSchema( getId: _ethContractGetId, getLinks: _ethContractGetLinks, attach: _ethContractAttach, - version: '3.0.5', + version: '3.1.8', ); int _ethContractEstimateSize( 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 4b9214889..1c0f4d405 100644 --- a/lib/models/isar/models/firo_specific/lelantus_coin.g.dart +++ b/lib/models/isar/models/firo_specific/lelantus_coin.g.dart @@ -7,7 +7,7 @@ part of 'lelantus_coin.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetLelantusCoinCollection on Isar { IsarCollection get lelantusCoins => this.collection(); @@ -101,7 +101,7 @@ const LelantusCoinSchema = CollectionSchema( getId: _lelantusCoinGetId, getLinks: _lelantusCoinGetLinks, attach: _lelantusCoinAttach, - version: '3.0.5', + version: '3.1.8', ); int _lelantusCoinEstimateSize( diff --git a/lib/models/isar/models/log.g.dart b/lib/models/isar/models/log.g.dart index 8a4cf22b1..ebad873f2 100644 --- a/lib/models/isar/models/log.g.dart +++ b/lib/models/isar/models/log.g.dart @@ -7,7 +7,7 @@ part of 'log.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetLogCollection on Isar { IsarCollection get logs => this.collection(); @@ -59,7 +59,7 @@ const LogSchema = CollectionSchema( getId: _logGetId, getLinks: _logGetLinks, attach: _logAttach, - version: '3.0.5', + version: '3.1.8', ); int _logEstimateSize( diff --git a/lib/models/isar/models/sent_to_address.g.dart b/lib/models/isar/models/sent_to_address.g.dart index 304d2c5fc..88153da9d 100644 --- a/lib/models/isar/models/sent_to_address.g.dart +++ b/lib/models/isar/models/sent_to_address.g.dart @@ -7,7 +7,7 @@ part of 'sent_to_address.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetSentToAddressCollection on Isar { IsarCollection get sentToAddress => this.collection(); @@ -81,7 +81,7 @@ const SentToAddressSchema = CollectionSchema( getId: _sentToAddressGetId, getLinks: _sentToAddressGetLinks, attach: _sentToAddressAttach, - version: '3.0.5', + version: '3.1.8', ); int _sentToAddressEstimateSize( diff --git a/lib/models/isar/models/transaction_note.g.dart b/lib/models/isar/models/transaction_note.g.dart index 152070328..67af8cdca 100644 --- a/lib/models/isar/models/transaction_note.g.dart +++ b/lib/models/isar/models/transaction_note.g.dart @@ -7,7 +7,7 @@ part of 'transaction_note.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetTransactionNoteCollection on Isar { IsarCollection get transactionNotes => this.collection(); @@ -76,7 +76,7 @@ const TransactionNoteSchema = CollectionSchema( getId: _transactionNoteGetId, getLinks: _transactionNoteGetLinks, attach: _transactionNoteAttach, - version: '3.0.5', + version: '3.1.8', ); int _transactionNoteEstimateSize( diff --git a/lib/models/isar/ordinal.g.dart b/lib/models/isar/ordinal.g.dart index 89c967cb0..5c23e11bb 100644 --- a/lib/models/isar/ordinal.g.dart +++ b/lib/models/isar/ordinal.g.dart @@ -7,7 +7,7 @@ part of 'ordinal.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetOrdinalCollection on Isar { IsarCollection get ordinals => this.collection(); @@ -83,7 +83,7 @@ const OrdinalSchema = CollectionSchema( getId: _ordinalGetId, getLinks: _ordinalGetLinks, attach: _ordinalAttach, - version: '3.0.5', + version: '3.1.8', ); int _ordinalEstimateSize( diff --git a/lib/models/isar/stack_theme.g.dart b/lib/models/isar/stack_theme.g.dart index 03c543ff0..c77d979f5 100644 --- a/lib/models/isar/stack_theme.g.dart +++ b/lib/models/isar/stack_theme.g.dart @@ -7,7 +7,7 @@ part of 'stack_theme.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetStackThemeCollection on Isar { IsarCollection get stackThemes => this.collection(); @@ -860,7 +860,7 @@ const StackThemeSchema = CollectionSchema( getId: _stackThemeGetId, getLinks: _stackThemeGetLinks, attach: _stackThemeAttach, - version: '3.0.5', + version: '3.1.8', ); int _stackThemeEstimateSize( @@ -18012,7 +18012,7 @@ extension StackThemeQueryProperty // ************************************************************************** // 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 +// 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, always_specify_types const ThemeAssetsSchema = Schema( name: r'ThemeAssets', @@ -25833,7 +25833,7 @@ extension ThemeAssetsQueryObject on QueryBuilder {} // 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 +// 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, always_specify_types const ThemeAssetsV2Schema = Schema( name: r'ThemeAssetsV2', @@ -29441,7 +29441,7 @@ extension ThemeAssetsV2QueryObject on QueryBuilder {} // 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 +// 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, always_specify_types const ThemeAssetsV3Schema = Schema( name: r'ThemeAssetsV3', diff --git a/lib/models/keys/view_only_wallet_data.dart b/lib/models/keys/view_only_wallet_data.dart new file mode 100644 index 000000000..92c23b082 --- /dev/null +++ b/lib/models/keys/view_only_wallet_data.dart @@ -0,0 +1,164 @@ +import 'dart:convert'; + +import '../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart'; +import 'key_data_interface.dart'; + +// do not remove or change the order of these enum values +enum ViewOnlyWalletType { + cryptonote, + addressOnly, + xPub; +} + +sealed class ViewOnlyWalletData with KeyDataInterface { + @override + final String walletId; + + ViewOnlyWalletType get type; + + ViewOnlyWalletData({ + required this.walletId, + }); + + static ViewOnlyWalletData fromJsonEncodedString( + String jsonEncodedString, { + required String walletId, + }) { + final map = jsonDecode(jsonEncodedString) as Map; + final json = Map.from(map); + final type = ViewOnlyWalletType.values[json["type"] as int]; + + switch (type) { + case ViewOnlyWalletType.cryptonote: + return CryptonoteViewOnlyWalletData.fromJsonEncodedString( + jsonEncodedString, + walletId: walletId, + ); + + case ViewOnlyWalletType.addressOnly: + return AddressViewOnlyWalletData.fromJsonEncodedString( + jsonEncodedString, + walletId: walletId, + ); + + case ViewOnlyWalletType.xPub: + return ExtendedKeysViewOnlyWalletData.fromJsonEncodedString( + jsonEncodedString, + walletId: walletId, + ); + } + } + + String toJsonEncodedString(); +} + +class CryptonoteViewOnlyWalletData extends ViewOnlyWalletData { + @override + final type = ViewOnlyWalletType.cryptonote; + + final String address; + final String privateViewKey; + + CryptonoteViewOnlyWalletData({ + required super.walletId, + required this.address, + required this.privateViewKey, + }); + + static CryptonoteViewOnlyWalletData fromJsonEncodedString( + String jsonEncodedString, { + required String walletId, + }) { + final map = jsonDecode(jsonEncodedString) as Map; + final json = Map.from(map); + + return CryptonoteViewOnlyWalletData( + walletId: walletId, + address: json["address"] as String, + privateViewKey: json["privateViewKey"] as String, + ); + } + + @override + String toJsonEncodedString() => jsonEncode({ + "type": type.index, + "address": address, + "privateViewKey": privateViewKey, + }); +} + +class AddressViewOnlyWalletData extends ViewOnlyWalletData { + @override + final type = ViewOnlyWalletType.addressOnly; + + final String address; + + AddressViewOnlyWalletData({ + required super.walletId, + required this.address, + }); + + static AddressViewOnlyWalletData fromJsonEncodedString( + String jsonEncodedString, { + required String walletId, + }) { + final map = jsonDecode(jsonEncodedString) as Map; + final json = Map.from(map); + + return AddressViewOnlyWalletData( + walletId: walletId, + address: json["address"] as String, + ); + } + + @override + String toJsonEncodedString() => jsonEncode({ + "type": type.index, + "address": address, + }); +} + +class ExtendedKeysViewOnlyWalletData extends ViewOnlyWalletData { + @override + final type = ViewOnlyWalletType.xPub; + + final List xPubs; + + ExtendedKeysViewOnlyWalletData({ + required super.walletId, + required List xPubs, + }) : xPubs = List.unmodifiable(xPubs); + + static ExtendedKeysViewOnlyWalletData fromJsonEncodedString( + String jsonEncodedString, { + required String walletId, + }) { + final map = jsonDecode(jsonEncodedString) as Map; + final json = Map.from(map); + + return ExtendedKeysViewOnlyWalletData( + walletId: walletId, + xPubs: List>.from((json["xPubs"] as List)) + .map( + (e) => XPub( + path: e["path"] as String, + encoded: e["encoded"] as String, + ), + ) + .toList(growable: false), + ); + } + + @override + String toJsonEncodedString() => jsonEncode({ + "type": type.index, + "xPubs": [ + ...xPubs.map( + (e) => { + "path": e.path, + "encoded": e.encoded, + }, + ), + ], + }); +} diff --git a/lib/networking/http.dart b/lib/networking/http.dart index a4f25c225..ae2a3b97b 100644 --- a/lib/networking/http.dart +++ b/lib/networking/http.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:socks5_proxy/socks_client.dart'; + import '../utilities/logger.dart'; // WIP wrapper layer @@ -118,6 +119,10 @@ class HTTP { onDone: () => completer.complete( Uint8List.fromList(bytes), ), + onError: (Object err, StackTrace s) => Logging.instance.log( + "Http wrapper layer listen: $err\n$s", + level: LogLevel.Error, + ), ); return completer.future; } diff --git a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart index deb38a648..2920bbc48 100644 --- a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart +++ b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart @@ -69,6 +69,7 @@ class _AddWalletViewState extends ConsumerState { ...AppConfig.coins.where((e) => e.network == CryptoCurrencyNetwork.main), ]; final List coinEntities = []; + final List coinTestnetEntities = []; final List tokenEntities = []; final bool isDesktop = Util.isDesktop; @@ -139,7 +140,7 @@ class _AddWalletViewState extends ConsumerState { coinEntities.addAll(_coins.map((e) => CoinEntity(e))); if (ref.read(prefsChangeNotifierProvider).showTestNetCoins) { - coinEntities.addAll(_coinsTestnet.map((e) => CoinEntity(e))); + coinTestnetEntities.addAll(_coinsTestnet.map((e) => CoinEntity(e))); } if (AppConfig.coins.whereType().isNotEmpty) { @@ -286,6 +287,14 @@ class _AddWalletViewState extends ConsumerState { initialState: ExpandableState.expanded, animationDurationMultiplier: 0.5, ), + if (coinTestnetEntities.isNotEmpty) + ExpandingSubListItem( + title: "Testnet", + entities: + filter(_searchTerm, coinTestnetEntities), + initialState: ExpandableState.expanded, + animationDurationMultiplier: 0.5, + ), if (tokenEntities.isNotEmpty) ExpandingSubListItem( title: "Tokens", @@ -419,6 +428,13 @@ class _AddWalletViewState extends ConsumerState { entities: filter(_searchTerm, coinEntities), initialState: ExpandableState.expanded, ), + if (coinTestnetEntities.isNotEmpty) + ExpandingSubListItem( + title: "Testnet", + entities: + filter(_searchTerm, coinTestnetEntities), + initialState: ExpandableState.expanded, + ), if (tokenEntities.isNotEmpty) ExpandingSubListItem( title: "Tokens", diff --git a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart index 29742f251..f17ed06ff 100644 --- a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart +++ b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart @@ -25,6 +25,7 @@ import '../../../utilities/name_generator.dart'; import '../../../utilities/text_styles.dart'; import '../../../utilities/util.dart'; import '../../../wallets/crypto_currency/crypto_currency.dart'; +import '../../../wallets/crypto_currency/interfaces/view_only_option_currency_interface.dart'; import '../../../wallets/crypto_currency/intermediate/frost_currency.dart'; import '../../../wallets/isar/models/wallet_info.dart'; import '../../../widgets/background.dart'; @@ -104,7 +105,9 @@ class _NameYourWalletViewState extends ConsumerState { case AddWalletType.New: unawaited( Navigator.of(context).pushNamed( - coin.hasMnemonicPassphraseSupport + coin.possibleMnemonicLengths.length > 1 || + coin.hasMnemonicPassphraseSupport || + coin is ViewOnlyOptionCurrencyInterface ? NewWalletOptionsView.routeName : NewWalletRecoveryPhraseWarningView.routeName, arguments: Tuple2( diff --git a/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart b/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart index 1008fd5df..bfe41c3fe 100644 --- a/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart +++ b/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart @@ -12,9 +12,11 @@ import '../../../utilities/constants.dart'; import '../../../utilities/text_styles.dart'; import '../../../utilities/util.dart'; import '../../../wallets/crypto_currency/crypto_currency.dart'; +import '../../../wallets/crypto_currency/interfaces/view_only_option_currency_interface.dart'; import '../../../widgets/background.dart'; import '../../../widgets/conditional_parent.dart'; import '../../../widgets/custom_buttons/app_bar_icon_button.dart'; +import '../../../widgets/custom_buttons/checkbox_text_button.dart'; import '../../../widgets/desktop/desktop_app_bar.dart'; import '../../../widgets/desktop/desktop_scaffold.dart'; import '../../../widgets/desktop/primary_button.dart'; @@ -25,8 +27,12 @@ import '../new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_wa import '../restore_wallet_view/restore_options_view/sub_widgets/mobile_mnemonic_length_selector.dart'; import '../restore_wallet_view/sub_widgets/mnemonic_word_count_select_sheet.dart'; -final pNewWalletOptions = - StateProvider<({String mnemonicPassphrase, int mnemonicWordsCount})?>( +final pNewWalletOptions = StateProvider< + ({ + String mnemonicPassphrase, + int mnemonicWordsCount, + bool convertToViewOnly, + })?>( (ref) => null, ); @@ -59,6 +65,8 @@ class _NewWalletOptionsViewState extends ConsumerState { bool hidePassword = true; NewWalletOptions _selectedOptions = NewWalletOptions.Default; + bool _convertToViewOnly = false; + @override void initState() { passwordController = TextEditingController(); @@ -210,7 +218,7 @@ class _NewWalletOptionsViewState extends ConsumerState { if (_selectedOptions == NewWalletOptions.Advanced) Column( children: [ - if (Util.isDesktop) + if (Util.isDesktop && lengths.length > 1) DropdownButtonHideUnderline( child: DropdownButton2( value: ref @@ -265,7 +273,7 @@ class _NewWalletOptionsViewState extends ConsumerState { ), ), ), - if (!Util.isDesktop) + if (!Util.isDesktop && lengths.length > 1) MobileMnemonicLengthSelector( chooseMnemonicLength: () { showModalBottomSheet( @@ -284,91 +292,109 @@ class _NewWalletOptionsViewState extends ConsumerState { ); }, ), - const SizedBox( - height: 24, - ), - RoundedWhiteContainer( - child: Center( - child: Text( - "You may add a BIP39 passphrase. This is optional. " - "You will need BOTH your seed and your passphrase to recover the wallet.", - style: Util.isDesktop - ? STextStyles.desktopTextExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ) - : STextStyles.itemSubtitle(context), + if (widget.coin.hasMnemonicPassphraseSupport) + const SizedBox( + height: 24, + ), + if (widget.coin.hasMnemonicPassphraseSupport) + RoundedWhiteContainer( + child: Center( + child: Text( + "You may add a BIP39 passphrase. This is optional. " + "You will need BOTH your seed and your passphrase to recover the wallet.", + style: Util.isDesktop + ? STextStyles.desktopTextExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ) + : STextStyles.itemSubtitle(context), + ), ), ), - ), - const SizedBox( - height: 8, - ), - ClipRRect( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, + if (widget.coin.hasMnemonicPassphraseSupport) + const SizedBox( + height: 8, ), - child: TextField( - key: const Key("mnemonicPassphraseFieldKey1"), - focusNode: passwordFocusNode, - controller: passwordController, - style: Util.isDesktop - ? STextStyles.desktopTextMedium(context).copyWith( - height: 2, - ) - : STextStyles.field(context), - obscureText: hidePassword, - enableSuggestions: false, - autocorrect: false, - decoration: standardInputDecoration( - "BIP39 passphrase", - passwordFocusNode, - context, - ).copyWith( - suffixIcon: UnconstrainedBox( - child: ConditionalParent( - condition: Util.isDesktop, - builder: (child) => SizedBox( - height: 70, - child: child, - ), - child: Row( - children: [ - SizedBox( - width: Util.isDesktop ? 24 : 16, - ), - GestureDetector( - key: const Key( - "mnemonicPassphraseFieldShowPasswordButtonKey", - ), - onTap: () async { - setState(() { - hidePassword = !hidePassword; - }); - }, - child: SvgPicture.asset( - hidePassword - ? Assets.svg.eye - : Assets.svg.eyeSlash, - color: Theme.of(context) - .extension()! - .textDark3, + if (widget.coin.hasMnemonicPassphraseSupport) + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + key: const Key("mnemonicPassphraseFieldKey1"), + focusNode: passwordFocusNode, + controller: passwordController, + style: Util.isDesktop + ? STextStyles.desktopTextMedium(context).copyWith( + height: 2, + ) + : STextStyles.field(context), + obscureText: hidePassword, + enableSuggestions: false, + autocorrect: false, + decoration: standardInputDecoration( + "BIP39 passphrase", + passwordFocusNode, + context, + ).copyWith( + suffixIcon: UnconstrainedBox( + child: ConditionalParent( + condition: Util.isDesktop, + builder: (child) => SizedBox( + height: 70, + child: child, + ), + child: Row( + children: [ + SizedBox( width: Util.isDesktop ? 24 : 16, - height: Util.isDesktop ? 24 : 16, ), - ), - const SizedBox( - width: 12, - ), - ], + GestureDetector( + key: const Key( + "mnemonicPassphraseFieldShowPasswordButtonKey", + ), + onTap: () async { + setState(() { + hidePassword = !hidePassword; + }); + }, + child: SvgPicture.asset( + hidePassword + ? Assets.svg.eye + : Assets.svg.eyeSlash, + color: Theme.of(context) + .extension()! + .textDark3, + width: Util.isDesktop ? 24 : 16, + height: Util.isDesktop ? 24 : 16, + ), + ), + const SizedBox( + width: 12, + ), + ], + ), ), ), ), ), ), - ), + if (widget.coin is ViewOnlyOptionCurrencyInterface) + const SizedBox( + height: 24, + ), + if (widget.coin is ViewOnlyOptionCurrencyInterface) + CheckboxTextButton( + label: "Convert to view only wallet. " + "You will only be shown the seed phrase once. " + "Save it somewhere. " + "If you lose it you will lose access to any funds in this wallet.", + onChanged: (value) { + _convertToViewOnly = value; + }, + ), ], ), if (!Util.isDesktop) const Spacer(), @@ -383,6 +409,7 @@ class _NewWalletOptionsViewState extends ConsumerState { mnemonicWordsCount: ref.read(mnemonicWordCountStateProvider.state).state, mnemonicPassphrase: passwordController.text, + convertToViewOnly: _convertToViewOnly, ); } else { ref.read(pNewWalletOptions.notifier).state = null; diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart index 42836e117..73acccb9d 100644 --- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart +++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart @@ -560,6 +560,8 @@ class _NewWalletRecoveryPhraseWarningViewState wordCount = info .coin.defaultSeedPhraseLength; + // TODO: Refactor these to generate each coin in their respective classes + // This code should not be in a random view page file if (coin is Monero || coin is Wownero) { // currently a special case due to the @@ -580,7 +582,12 @@ class _NewWalletRecoveryPhraseWarningViewState ) .state! .mnemonicPassphrase; - } else {} + } else { + // this may not be epiccash specific? + if (coin is Epiccash) { + mnemonicPassphrase = ""; + } + } wordCount = ref .read( diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart index 0b7fcc37b..384cacb0c 100644 --- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart +++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart @@ -23,6 +23,8 @@ import '../../../../utilities/format.dart'; import '../../../../utilities/text_styles.dart'; import '../../../../utilities/util.dart'; import '../../../../wallets/crypto_currency/crypto_currency.dart'; +import '../../../../wallets/crypto_currency/interfaces/view_only_option_currency_interface.dart'; +import '../../../../wallets/crypto_currency/intermediate/cryptonote_currency.dart'; import '../../../../widgets/conditional_parent.dart'; import '../../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../../widgets/custom_buttons/checkbox_text_button.dart'; @@ -32,7 +34,9 @@ import '../../../../widgets/desktop/desktop_scaffold.dart'; import '../../../../widgets/expandable.dart'; import '../../../../widgets/rounded_white_container.dart'; import '../../../../widgets/stack_text_field.dart'; +import '../../../../widgets/toggle.dart'; import '../../create_or_restore_wallet_view/sub_widgets/coin_image.dart'; +import '../restore_view_only_wallet_view.dart'; import '../restore_wallet_view.dart'; import '../sub_widgets/mnemonic_word_count_select_sheet.dart'; import 'sub_widgets/mobile_mnemonic_length_selector.dart'; @@ -67,9 +71,8 @@ class _RestoreOptionsViewState extends ConsumerState { late final TextEditingController passwordController; final bool _nextEnabled = true; - DateTime _restoreFromDate = DateTime.fromMillisecondsSinceEpoch(0); + DateTime? _restoreFromDate; bool hidePassword = true; - bool _expandedAdavnced = false; bool get supportsMnemonicPassphrase => coin.hasMnemonicPassphraseSupport; @@ -99,27 +102,46 @@ class _RestoreOptionsViewState extends ConsumerState { super.dispose(); } + bool _nextLock = false; Future nextPressed() async { - if (!isDesktop) { - // hide keyboard if has focus - if (FocusScope.of(context).hasFocus) { - FocusScope.of(context).unfocus(); - await Future.delayed(const Duration(milliseconds: 75)); + if (_nextLock) return; + _nextLock = true; + try { + if (!isDesktop) { + // hide keyboard if has focus + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future.delayed(const Duration(milliseconds: 75)); + } } - } - if (mounted) { - await Navigator.of(context).pushNamed( - RestoreWalletView.routeName, - arguments: Tuple6( - walletName, - coin, - ref.read(mnemonicWordCountStateProvider.state).state, - _restoreFromDate, - passwordController.text, - enableLelantusScanning, - ), - ); + if (mounted) { + if (!_showViewOnlyOption) { + await Navigator.of(context).pushNamed( + RestoreWalletView.routeName, + arguments: Tuple6( + walletName, + coin, + ref.read(mnemonicWordCountStateProvider.state).state, + _restoreFromDate, + passwordController.text, + enableLelantusScanning, + ), + ); + } else { + await Navigator.of(context).pushNamed( + RestoreViewOnlyWalletView.routeName, + arguments: ( + walletName: walletName, + coin: coin, + restoreFromDate: _restoreFromDate, + enableLelantusScanning: enableLelantusScanning, + ), + ); + } + } + } finally { + _nextLock = false; } } @@ -164,17 +186,12 @@ class _RestoreOptionsViewState extends ConsumerState { ); } + bool _showViewOnlyOption = false; + @override Widget build(BuildContext context) { debugPrint("BUILD: $runtimeType with ${coin.identifier} $walletName"); - final lengths = coin.possibleMnemonicLengths; - - final isMoneroAnd25 = coin is Monero && - ref.watch(mnemonicWordCountStateProvider.state).state == 25; - final isWowneroAnd25 = coin is Wownero && - ref.watch(mnemonicWordCountStateProvider.state).state == 25; - return MasterScaffold( isDesktop: isDesktop, appBar: isDesktop @@ -227,288 +244,57 @@ class _RestoreOptionsViewState extends ConsumerState { SizedBox( height: isDesktop ? 40 : 24, ), - if (isMoneroAnd25 || coin is Epiccash || isWowneroAnd25) - Text( - "Choose start date", - style: isDesktop - ? STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textDark3, - ) - : STextStyles.smallMed12(context), - textAlign: TextAlign.left, - ), - if (isMoneroAnd25 || coin is Epiccash || isWowneroAnd25) + if (coin is ViewOnlyOptionCurrencyInterface) SizedBox( - height: isDesktop ? 16 : 8, - ), - if (isMoneroAnd25 || coin is Epiccash || isWowneroAnd25) - if (!isDesktop) - RestoreFromDatePicker( - onTap: chooseDate, - controller: _dateController, - ), - if (isMoneroAnd25 || coin is Epiccash || isWowneroAnd25) - if (isDesktop) - // TODO desktop date picker - RestoreFromDatePicker( - onTap: chooseDesktopDate, - controller: _dateController, - ), - if (isMoneroAnd25 || coin is Epiccash || isWowneroAnd25) - const SizedBox( - height: 8, - ), - if (isMoneroAnd25 || coin is Epiccash || isWowneroAnd25) - RoundedWhiteContainer( - child: Center( - child: Text( - "Choose the date you made the wallet (approximate is fine)", - style: isDesktop - ? STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ) - : STextStyles.smallMed12(context).copyWith( - fontSize: 10, - ), - ), - ), - ), - if (isMoneroAnd25 || coin is Epiccash || isWowneroAnd25) - SizedBox( - height: isDesktop ? 24 : 16, - ), - Text( - "Choose recovery phrase length", - style: isDesktop - ? STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textDark3, - ) - : STextStyles.smallMed12(context), - textAlign: TextAlign.left, - ), - SizedBox( - height: isDesktop ? 16 : 8, - ), - if (isDesktop) - DropdownButtonHideUnderline( - child: DropdownButton2( - value: - ref.watch(mnemonicWordCountStateProvider.state).state, - items: [ - ...lengths.map( - (e) => DropdownMenuItem( - value: e, - child: Text( - "$e words", - style: STextStyles.desktopTextMedium(context), - ), - ), - ), - ], - onChanged: (value) { - if (value is int) { - ref.read(mnemonicWordCountStateProvider.state).state = - value; - } + height: isDesktop ? 56 : 48, + width: isDesktop ? 490 : null, + child: Toggle( + key: UniqueKey(), + onText: "Seed", + offText: "View Only", + onColor: + Theme.of(context).extension()!.popupBG, + offColor: Theme.of(context) + .extension()! + .textFieldDefaultBG, + isOn: _showViewOnlyOption, + onValueChanged: (value) { + setState(() { + _showViewOnlyOption = value; + }); }, - isExpanded: true, - iconStyleData: IconStyleData( - icon: SvgPicture.asset( - Assets.svg.chevronDown, - width: 12, - height: 6, - color: Theme.of(context) - .extension()! - .textFieldActiveSearchIconRight, - ), - ), - dropdownStyleData: DropdownStyleData( - offset: const Offset(0, -10), - elevation: 0, - decoration: BoxDecoration( - color: Theme.of(context) - .extension()! - .textFieldDefaultBG, - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - ), - ), - menuItemStyleData: const MenuItemStyleData( - padding: EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, + decoration: BoxDecoration( + color: Colors.transparent, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, ), ), ), ), - if (!isDesktop) - MobileMnemonicLengthSelector( - chooseMnemonicLength: chooseMnemonicLength, - ), - if (supportsMnemonicPassphrase) + if (coin is ViewOnlyOptionCurrencyInterface) SizedBox( - height: isDesktop ? 24 : 16, + height: isDesktop ? 40 : 24, ), - if (supportsMnemonicPassphrase) - Expandable( - onExpandChanged: (state) { - setState(() { - _expandedAdavnced = state == ExpandableState.expanded; - }); - }, - header: Container( - color: Colors.transparent, - child: Padding( - padding: const EdgeInsets.only( - top: 8.0, - bottom: 8.0, - right: 10, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Advanced", - style: isDesktop - ? STextStyles.desktopTextExtraExtraSmall( - context, - ).copyWith( - color: Theme.of(context) - .extension()! - .textDark3, - ) - : STextStyles.smallMed12(context), - textAlign: TextAlign.left, - ), - SvgPicture.asset( - _expandedAdavnced - ? Assets.svg.chevronUp - : Assets.svg.chevronDown, - width: 12, - height: 6, - color: Theme.of(context) - .extension()! - .textFieldActiveSearchIconRight, - ), - ], - ), + _showViewOnlyOption + ? ViewOnlyRestoreOption( + coin: coin, + dateController: _dateController, + dateChooserFunction: + isDesktop ? chooseDesktopDate : chooseDate, + ) + : SeedRestoreOption( + coin: coin, + dateController: _dateController, + pwController: passwordController, + pwFocusNode: passwordFocusNode, + supportsMnemonicPassphrase: supportsMnemonicPassphrase, + dateChooserFunction: + isDesktop ? chooseDesktopDate : chooseDate, + chooseMnemonicLength: chooseMnemonicLength, + lelScanChanged: (value) { + enableLelantusScanning = value; + }, ), - ), - body: Container( - color: Colors.transparent, - child: Column( - children: [ - if (coin is Firo) - CheckboxTextButton( - label: "Scan for Lelantus transactions", - onChanged: (newValue) { - setState(() { - enableLelantusScanning = newValue ?? true; - }); - }, - ), - if (coin is Firo) - const SizedBox( - height: 8, - ), - ClipRRect( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - child: TextField( - key: const Key("mnemonicPassphraseFieldKey1"), - focusNode: passwordFocusNode, - controller: passwordController, - style: isDesktop - ? STextStyles.desktopTextMedium(context) - .copyWith( - height: 2, - ) - : STextStyles.field(context), - obscureText: hidePassword, - enableSuggestions: false, - autocorrect: false, - decoration: standardInputDecoration( - "BIP39 passphrase", - passwordFocusNode, - context, - ).copyWith( - suffixIcon: UnconstrainedBox( - child: ConditionalParent( - condition: isDesktop, - builder: (child) => SizedBox( - height: 70, - child: child, - ), - child: Row( - children: [ - SizedBox( - width: isDesktop ? 24 : 16, - ), - GestureDetector( - key: const Key( - "mnemonicPassphraseFieldShowPasswordButtonKey", - ), - onTap: () async { - setState(() { - hidePassword = !hidePassword; - }); - }, - child: SvgPicture.asset( - hidePassword - ? Assets.svg.eye - : Assets.svg.eyeSlash, - color: Theme.of(context) - .extension()! - .textDark3, - width: isDesktop ? 24 : 16, - height: isDesktop ? 24 : 16, - ), - ), - const SizedBox( - width: 12, - ), - ], - ), - ), - ), - ), - ), - ), - const SizedBox( - height: 8, - ), - RoundedWhiteContainer( - child: Center( - child: Text( - "If the recovery phrase you are about to restore " - "was created with an optional BIP39 passphrase " - "you can enter it here.", - style: isDesktop - ? STextStyles.desktopTextExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ) - : STextStyles.itemSubtitle(context), - ), - ), - ), - const SizedBox( - height: 16, - ), - ], - ), - ), - ), if (!isDesktop) const Spacer( flex: 3, @@ -532,3 +318,394 @@ class _RestoreOptionsViewState extends ConsumerState { ); } } + +class SeedRestoreOption extends ConsumerStatefulWidget { + const SeedRestoreOption({ + super.key, + required this.coin, + required this.dateController, + required this.pwController, + required this.pwFocusNode, + required this.supportsMnemonicPassphrase, + required this.dateChooserFunction, + required this.chooseMnemonicLength, + required this.lelScanChanged, + }); + + final CryptoCurrency coin; + final TextEditingController dateController; + final TextEditingController pwController; + final FocusNode pwFocusNode; + final bool supportsMnemonicPassphrase; + + final Future Function() dateChooserFunction; + final Future Function() chooseMnemonicLength; + final void Function(bool) lelScanChanged; + + @override + ConsumerState createState() => _SeedRestoreOptionState(); +} + +class _SeedRestoreOptionState extends ConsumerState { + bool _hidePassword = true; + bool _expandedAdvanced = false; + bool _enableLelantusScanning = false; + + @override + Widget build(BuildContext context) { + final lengths = widget.coin.possibleMnemonicLengths; + + final isMoneroAnd25 = widget.coin is Monero && + ref.watch(mnemonicWordCountStateProvider.state).state == 25; + final isWowneroAnd25 = widget.coin is Wownero && + ref.watch(mnemonicWordCountStateProvider.state).state == 25; + + return Column( + children: [ + if (isMoneroAnd25 || widget.coin is Epiccash || isWowneroAnd25) + Text( + "Choose start date", + style: Util.isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: + Theme.of(context).extension()!.textDark3, + ) + : STextStyles.smallMed12(context), + textAlign: TextAlign.left, + ), + if (isMoneroAnd25 || widget.coin is Epiccash || isWowneroAnd25) + SizedBox( + height: Util.isDesktop ? 16 : 8, + ), + if (isMoneroAnd25 || widget.coin is Epiccash || isWowneroAnd25) + RestoreFromDatePicker( + onTap: widget.dateChooserFunction, + controller: widget.dateController, + ), + if (isMoneroAnd25 || widget.coin is Epiccash || isWowneroAnd25) + const SizedBox( + height: 8, + ), + if (isMoneroAnd25 || widget.coin is Epiccash || isWowneroAnd25) + RoundedWhiteContainer( + child: Center( + child: Text( + "Choose the date you made the wallet (approximate is fine)", + style: Util.isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ) + : STextStyles.smallMed12(context).copyWith( + fontSize: 10, + ), + ), + ), + ), + if (isMoneroAnd25 || widget.coin is Epiccash || isWowneroAnd25) + SizedBox( + height: Util.isDesktop ? 24 : 16, + ), + Text( + "Choose recovery phrase length", + style: Util.isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context).extension()!.textDark3, + ) + : STextStyles.smallMed12(context), + textAlign: TextAlign.left, + ), + SizedBox( + height: Util.isDesktop ? 16 : 8, + ), + if (Util.isDesktop) + DropdownButtonHideUnderline( + child: DropdownButton2( + value: ref.watch(mnemonicWordCountStateProvider.state).state, + items: [ + ...lengths.map( + (e) => DropdownMenuItem( + value: e, + child: Text( + "$e words", + style: STextStyles.desktopTextMedium(context), + ), + ), + ), + ], + onChanged: (value) { + if (value is int) { + ref.read(mnemonicWordCountStateProvider.state).state = value; + } + }, + isExpanded: true, + iconStyleData: IconStyleData( + icon: SvgPicture.asset( + Assets.svg.chevronDown, + width: 12, + height: 6, + color: Theme.of(context) + .extension()! + .textFieldActiveSearchIconRight, + ), + ), + dropdownStyleData: DropdownStyleData( + offset: const Offset(0, -10), + elevation: 0, + decoration: BoxDecoration( + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + ), + menuItemStyleData: const MenuItemStyleData( + padding: EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + ), + ), + ), + if (!Util.isDesktop) + MobileMnemonicLengthSelector( + chooseMnemonicLength: widget.chooseMnemonicLength, + ), + if (widget.supportsMnemonicPassphrase) + SizedBox( + height: Util.isDesktop ? 24 : 16, + ), + if (widget.supportsMnemonicPassphrase) + Expandable( + onExpandChanged: (state) { + setState(() { + _expandedAdvanced = state == ExpandableState.expanded; + }); + }, + header: Container( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.only( + top: 8.0, + bottom: 8.0, + right: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Advanced", + style: Util.isDesktop + ? STextStyles.desktopTextExtraExtraSmall( + context, + ).copyWith( + color: Theme.of(context) + .extension()! + .textDark3, + ) + : STextStyles.smallMed12(context), + textAlign: TextAlign.left, + ), + SvgPicture.asset( + _expandedAdvanced + ? Assets.svg.chevronUp + : Assets.svg.chevronDown, + width: 12, + height: 6, + color: Theme.of(context) + .extension()! + .textFieldActiveSearchIconRight, + ), + ], + ), + ), + ), + body: Container( + color: Colors.transparent, + child: Column( + children: [ + if (widget.coin is Firo) + CheckboxTextButton( + label: "Scan for Lelantus transactions", + onChanged: (newValue) { + setState(() { + _enableLelantusScanning = newValue ?? true; + }); + + widget.lelScanChanged(_enableLelantusScanning); + }, + ), + if (widget.coin is Firo) + const SizedBox( + height: 8, + ), + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + key: const Key("mnemonicPassphraseFieldKey1"), + focusNode: widget.pwFocusNode, + controller: widget.pwController, + style: Util.isDesktop + ? STextStyles.desktopTextMedium(context).copyWith( + height: 2, + ) + : STextStyles.field(context), + obscureText: _hidePassword, + enableSuggestions: false, + autocorrect: false, + decoration: standardInputDecoration( + "BIP39 passphrase", + widget.pwFocusNode, + context, + ).copyWith( + suffixIcon: UnconstrainedBox( + child: ConditionalParent( + condition: Util.isDesktop, + builder: (child) => SizedBox( + height: 70, + child: child, + ), + child: Row( + children: [ + SizedBox( + width: Util.isDesktop ? 24 : 16, + ), + GestureDetector( + key: const Key( + "mnemonicPassphraseFieldShowPasswordButtonKey", + ), + onTap: () async { + setState(() { + _hidePassword = !_hidePassword; + }); + }, + child: SvgPicture.asset( + _hidePassword + ? Assets.svg.eye + : Assets.svg.eyeSlash, + color: Theme.of(context) + .extension()! + .textDark3, + width: Util.isDesktop ? 24 : 16, + height: Util.isDesktop ? 24 : 16, + ), + ), + const SizedBox( + width: 12, + ), + ], + ), + ), + ), + ), + ), + ), + const SizedBox( + height: 8, + ), + RoundedWhiteContainer( + child: Center( + child: Text( + "If the recovery phrase you are about to restore " + "was created with an optional BIP39 passphrase " + "you can enter it here.", + style: Util.isDesktop + ? STextStyles.desktopTextExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ) + : STextStyles.itemSubtitle(context), + ), + ), + ), + const SizedBox( + height: 16, + ), + ], + ), + ), + ), + ], + ); + } +} + +class ViewOnlyRestoreOption extends StatefulWidget { + const ViewOnlyRestoreOption({ + super.key, + required this.coin, + required this.dateController, + required this.dateChooserFunction, + }); + + final CryptoCurrency coin; + final TextEditingController dateController; + + final Future Function() dateChooserFunction; + + @override + State createState() => _ViewOnlyRestoreOptionState(); +} + +class _ViewOnlyRestoreOptionState extends State { + @override + Widget build(BuildContext context) { + final showDateOption = widget.coin is CryptonoteCurrency; + return Column( + children: [ + if (showDateOption) + Text( + "Choose start date", + style: Util.isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: + Theme.of(context).extension()!.textDark3, + ) + : STextStyles.smallMed12(context), + textAlign: TextAlign.left, + ), + if (showDateOption) + SizedBox( + height: Util.isDesktop ? 16 : 8, + ), + if (showDateOption) + RestoreFromDatePicker( + onTap: widget.dateChooserFunction, + controller: widget.dateController, + ), + if (showDateOption) + const SizedBox( + height: 8, + ), + if (showDateOption) + RoundedWhiteContainer( + child: Center( + child: Text( + "Choose the date you made the wallet (approximate is fine)", + style: Util.isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ) + : STextStyles.smallMed12(context).copyWith( + fontSize: 10, + ), + ), + ), + ), + if (showDateOption) + SizedBox( + height: Util.isDesktop ? 24 : 16, + ), + ], + ); + } +} diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_view_only_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_view_only_wallet_view.dart new file mode 100644 index 000000000..3a7131762 --- /dev/null +++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_view_only_wallet_view.dart @@ -0,0 +1,592 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:cs_monero/src/deprecated/get_height_by_date.dart' + as cs_monero_deprecated; +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; + +import '../../../models/keys/view_only_wallet_data.dart'; +import '../../../pages_desktop_specific/desktop_home_view.dart'; +import '../../../pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart'; +import '../../../providers/db/main_db_provider.dart'; +import '../../../providers/global/secure_store_provider.dart'; +import '../../../providers/providers.dart'; +import '../../../themes/stack_colors.dart'; +import '../../../utilities/assets.dart'; +import '../../../utilities/barcode_scanner_interface.dart'; +import '../../../utilities/clipboard_interface.dart'; +import '../../../utilities/constants.dart'; +import '../../../utilities/text_styles.dart'; +import '../../../utilities/util.dart'; +import '../../../wallets/crypto_currency/crypto_currency.dart'; +import '../../../wallets/crypto_currency/interfaces/electrumx_currency_interface.dart'; +import '../../../wallets/crypto_currency/intermediate/bip39_hd_currency.dart'; +import '../../../wallets/crypto_currency/intermediate/cryptonote_currency.dart'; +import '../../../wallets/isar/models/wallet_info.dart'; +import '../../../wallets/wallet/impl/epiccash_wallet.dart'; +import '../../../wallets/wallet/impl/monero_wallet.dart'; +import '../../../wallets/wallet/impl/wownero_wallet.dart'; +import '../../../wallets/wallet/wallet.dart'; +import '../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart'; +import '../../../widgets/custom_buttons/app_bar_icon_button.dart'; +import '../../../widgets/desktop/desktop_app_bar.dart'; +import '../../../widgets/desktop/desktop_scaffold.dart'; +import '../../../widgets/desktop/primary_button.dart'; +import '../../../widgets/stack_text_field.dart'; +import '../../../widgets/toggle.dart'; +import '../../home_view/home_view.dart'; +import 'confirm_recovery_dialog.dart'; +import 'sub_widgets/restore_failed_dialog.dart'; +import 'sub_widgets/restore_succeeded_dialog.dart'; +import 'sub_widgets/restoring_dialog.dart'; + +class RestoreViewOnlyWalletView extends ConsumerStatefulWidget { + const RestoreViewOnlyWalletView({ + super.key, + required this.walletName, + required this.coin, + required this.restoreFromDate, + this.enableLelantusScanning = false, + this.barcodeScanner = const BarcodeScannerWrapper(), + this.clipboard = const ClipboardWrapper(), + }); + + static const routeName = "/restoreViewOnlyWallet"; + + final String walletName; + final CryptoCurrency coin; + final DateTime? restoreFromDate; + final bool enableLelantusScanning; + final BarcodeScannerInterface barcodeScanner; + final ClipboardInterface clipboard; + + @override + ConsumerState createState() => + _RestoreViewOnlyWalletViewState(); +} + +class _RestoreViewOnlyWalletViewState + extends ConsumerState { + late final TextEditingController addressController; + late final TextEditingController viewKeyController; + + late String _currentDropDownValue; + + bool _enableRestoreButton = false; + bool _addressOnly = false; + + bool _buttonLock = false; + + Future _requestRestore() async { + if (_buttonLock) return; + _buttonLock = true; + + try { + if (!Util.isDesktop) { + // wait for keyboard to disappear + FocusScope.of(context).unfocus(); + await Future.delayed( + const Duration(milliseconds: 100), + ); + } + + if (mounted) { + await showDialog( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return ConfirmRecoveryDialog( + onConfirm: _attemptRestore, + ); + }, + ); + } + } finally { + _buttonLock = false; + } + } + + Future _attemptRestore() async { + int height = 0; + final Map otherDataJson = { + WalletInfoKeys.isViewOnlyKey: true, + }; + + final ViewOnlyWalletType viewOnlyWalletType; + if (widget.coin is Bip39HDCurrency) { + if (widget.coin is Firo) { + otherDataJson.addAll( + { + WalletInfoKeys.lelantusCoinIsarRescanRequired: false, + WalletInfoKeys.enableLelantusScanning: + widget.enableLelantusScanning, + }, + ); + } + viewOnlyWalletType = _addressOnly + ? ViewOnlyWalletType.addressOnly + : ViewOnlyWalletType.xPub; + } else if (widget.coin is CryptonoteCurrency) { + if (widget.restoreFromDate != null) { + if (widget.coin is Monero) { + height = cs_monero_deprecated.getMoneroHeightByDate( + date: widget.restoreFromDate!, + ); + } + if (widget.coin is Wownero) { + height = cs_monero_deprecated.getWowneroHeightByDate( + date: widget.restoreFromDate!, + ); + } + if (height < 0) height = 0; + } + + viewOnlyWalletType = ViewOnlyWalletType.cryptonote; + } else { + throw Exception( + "Unsupported view only wallet currency type found: ${widget.coin.runtimeType}", + ); + } + otherDataJson[WalletInfoKeys.viewOnlyTypeIndexKey] = + viewOnlyWalletType.index; + + if (!Platform.isLinux && !Util.isDesktop) await WakelockPlus.enable(); + + try { + final info = WalletInfo.createNew( + coin: widget.coin, + name: widget.walletName, + restoreHeight: height, + otherDataJsonString: jsonEncode(otherDataJson), + ); + + bool isRestoring = true; + // show restoring in progress + + if (mounted) { + unawaited( + showDialog( + context: context, + useSafeArea: false, + barrierDismissible: false, + builder: (context) { + return RestoringDialog( + onCancel: () async { + isRestoring = false; + + await ref.read(pWallets).deleteWallet( + info, + ref.read(secureStoreProvider), + ); + }, + ); + }, + ), + ); + } + + final ViewOnlyWalletData viewOnlyData; + switch (viewOnlyWalletType) { + case ViewOnlyWalletType.cryptonote: + if (addressController.text.isEmpty || + viewKeyController.text.isEmpty) { + throw Exception("Missing address and/or private view key fields"); + } + viewOnlyData = CryptonoteViewOnlyWalletData( + walletId: info.walletId, + address: addressController.text, + privateViewKey: viewKeyController.text, + ); + break; + + case ViewOnlyWalletType.addressOnly: + if (addressController.text.isEmpty) { + throw Exception("Address is empty"); + } + viewOnlyData = AddressViewOnlyWalletData( + walletId: info.walletId, + address: addressController.text, + ); + break; + + case ViewOnlyWalletType.xPub: + viewOnlyData = ExtendedKeysViewOnlyWalletData( + walletId: info.walletId, + xPubs: [ + XPub( + path: _currentDropDownValue, + encoded: viewKeyController.text, + ), + ], + ); + break; + } + + var node = ref + .read(nodeServiceChangeNotifierProvider) + .getPrimaryNodeFor(currency: widget.coin); + + if (node == null) { + node = widget.coin.defaultNode; + await ref.read(nodeServiceChangeNotifierProvider).setPrimaryNodeFor( + coin: widget.coin, + node: node, + ); + } + + try { + final wallet = await Wallet.create( + walletInfo: info, + mainDB: ref.read(mainDBProvider), + secureStorageInterface: ref.read(secureStoreProvider), + nodeService: ref.read(nodeServiceChangeNotifierProvider), + prefs: ref.read(prefsChangeNotifierProvider), + viewOnlyData: viewOnlyData, + ); + + // TODO: extract interface with isRestore param + switch (wallet.runtimeType) { + case const (EpiccashWallet): + await (wallet as EpiccashWallet).init(isRestore: true); + break; + + case const (MoneroWallet): + await (wallet as MoneroWallet).init(isRestore: true); + break; + + case const (WowneroWallet): + await (wallet as WowneroWallet).init(isRestore: true); + break; + + default: + await wallet.init(); + } + + await wallet.recover(isRescan: false); + + // check if state is still active before continuing + if (mounted) { + // don't remove this setMnemonicVerified thing + await wallet.info.setMnemonicVerified( + isar: ref.read(mainDBProvider).isar, + ); + + ref.read(pWallets).addWallet(wallet); + + if (mounted) { + if (Util.isDesktop) { + Navigator.of(context).popUntil( + ModalRoute.withName( + DesktopHomeView.routeName, + ), + ); + } else { + unawaited( + Navigator.of(context).pushNamedAndRemoveUntil( + HomeView.routeName, + (route) => false, + ), + ); + } + + await showDialog( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return const RestoreSucceededDialog(); + }, + ); + } + } + } catch (e) { + // check if state is still active and restore wasn't cancelled + // before continuing + if (mounted && isRestoring) { + // pop waiting dialog + Navigator.pop(context); + + // show restoring wallet failed dialog + await showDialog( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return RestoreFailedDialog( + errorMessage: e.toString(), + walletId: info.walletId, + walletName: info.name, + ); + }, + ); + } + } + } finally { + if (!Platform.isLinux && !Util.isDesktop) await WakelockPlus.disable(); + } + } + + @override + void initState() { + super.initState(); + addressController = TextEditingController(); + viewKeyController = TextEditingController(); + + if (widget.coin is Bip39HDCurrency) { + _currentDropDownValue = (widget.coin as Bip39HDCurrency) + .supportedHardenedDerivationPaths + .last; + } + } + + @override + void dispose() { + addressController.dispose(); + viewKeyController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final isDesktop = Util.isDesktop; + + final isElectrumX = widget.coin is ElectrumXCurrencyInterface; + + return MasterScaffold( + isDesktop: isDesktop, + appBar: isDesktop + ? const DesktopAppBar( + isCompactHeight: false, + leading: AppBarBackButton(), + trailing: ExitToMyStackButton(), + ) + : AppBar( + leading: AppBarBackButton( + onPressed: () async { + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future.delayed( + const Duration(milliseconds: 50), + ); + } + if (context.mounted) { + Navigator.of(context).pop(); + } + }, + ), + ), + body: Container( + color: Theme.of(context).extension()!.background, + child: LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + maxWidth: isDesktop ? 480 : double.infinity, + ), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + if (isDesktop) + const Spacer( + flex: 10, + ), + if (!isDesktop) + Text( + widget.walletName, + style: STextStyles.itemSubtitle(context), + ), + SizedBox( + height: isDesktop ? 0 : 4, + ), + Text( + "Enter view only details", + style: isDesktop + ? STextStyles.desktopH2(context) + : STextStyles.pageTitleH1(context), + ), + if (isElectrumX) + SizedBox( + height: isDesktop ? 24 : 16, + ), + if (isElectrumX) + SizedBox( + height: isDesktop ? 56 : 48, + width: isDesktop ? 490 : null, + child: Toggle( + key: UniqueKey(), + onText: "Extended pub key", + offText: "Single address", + onColor: Theme.of(context) + .extension()! + .popupBG, + offColor: Theme.of(context) + .extension()! + .textFieldDefaultBG, + isOn: _addressOnly, + onValueChanged: (value) { + setState(() { + _addressOnly = value; + }); + }, + decoration: BoxDecoration( + color: Colors.transparent, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + ), + ), + SizedBox( + height: isDesktop ? 24 : 16, + ), + if (!isElectrumX || _addressOnly) + FullTextField( + key: const Key("viewOnlyAddressRestoreFieldKey"), + label: "Address", + controller: addressController, + onChanged: (newValue) { + if (isElectrumX) { + viewKeyController.text = ""; + setState(() { + _enableRestoreButton = newValue.isNotEmpty; + }); + } else { + setState(() { + _enableRestoreButton = newValue.isNotEmpty && + viewKeyController.text.isNotEmpty; + }); + } + }, + ), + if (!isElectrumX) + SizedBox( + height: isDesktop ? 16 : 12, + ), + if (isElectrumX && !_addressOnly) + DropdownButtonHideUnderline( + child: DropdownButton2( + value: _currentDropDownValue, + items: [ + ...(widget.coin as Bip39HDCurrency) + .supportedHardenedDerivationPaths + .map( + (e) => DropdownMenuItem( + value: e, + child: Text( + e, + style: STextStyles.w500_14(context), + ), + ), + ), + ], + onChanged: (value) { + if (value is String) { + setState(() { + _currentDropDownValue = value; + }); + } + }, + isExpanded: true, + buttonStyleData: ButtonStyleData( + decoration: BoxDecoration( + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + ), + iconStyleData: IconStyleData( + icon: Padding( + padding: const EdgeInsets.only(right: 10), + child: SvgPicture.asset( + Assets.svg.chevronDown, + width: 12, + height: 6, + color: Theme.of(context) + .extension()! + .textFieldActiveSearchIconRight, + ), + ), + ), + dropdownStyleData: DropdownStyleData( + offset: const Offset(0, -10), + elevation: 0, + decoration: BoxDecoration( + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + ), + menuItemStyleData: const MenuItemStyleData( + padding: EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + ), + ), + ), + if (isElectrumX && !_addressOnly) + SizedBox( + height: isDesktop ? 16 : 12, + ), + if (!isElectrumX || !_addressOnly) + FullTextField( + key: const Key("viewOnlyKeyRestoreFieldKey"), + label: + "${isElectrumX ? "Extended" : "Private View"} Key", + controller: viewKeyController, + onChanged: (value) { + if (isElectrumX) { + addressController.text = ""; + setState(() { + _enableRestoreButton = value.isNotEmpty; + }); + } else { + setState(() { + _enableRestoreButton = value.isNotEmpty && + addressController.text.isNotEmpty; + }); + } + }, + ), + if (!isDesktop) const Spacer(), + SizedBox( + height: isDesktop ? 24 : 16, + ), + PrimaryButton( + enabled: _enableRestoreButton, + onPressed: _requestRestore, + width: isDesktop ? 480 : null, + label: "Restore", + ), + if (isDesktop) + const Spacer( + flex: 15, + ), + ], + ), + ), + ), + ), + ); + }, + ), + ), + ); + } +} diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart index 4c26ff3fa..2fae2352c 100644 --- a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart +++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart @@ -16,13 +16,14 @@ import 'dart:math'; import 'package:bip39/bip39.dart' as bip39; import 'package:bip39/src/wordlists/english.dart' as bip39wordlist; +import 'package:cs_monero/cs_monero.dart' as lib_monero; +import 'package:cs_monero/src/deprecated/get_height_by_date.dart' + as cs_monero_deprecated; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_libmonero/monero/monero.dart' as libxmr; -import 'package:flutter_libmonero/wownero/wownero.dart' as libwow; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:wakelock/wakelock.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; import '../../../notifications/show_flush_bar.dart'; import '../../../pages_desktop_specific/desktop_home_view.dart'; @@ -86,7 +87,7 @@ class RestoreWalletView extends ConsumerStatefulWidget { final CryptoCurrency coin; final String mnemonicPassphrase; final int seedWordsLength; - final DateTime restoreFromDate; + final DateTime? restoreFromDate; final bool enableLelantusScanning; final BarcodeScannerInterface barcodeScanner; @@ -181,7 +182,7 @@ class _RestoreWalletViewState extends ConsumerState { if (widget.coin is Monero) { switch (widget.seedWordsLength) { case 25: - return libxmr.monero.getMoneroWordList("English").contains(word); + return lib_monero.getMoneroWordList("English").contains(word); case 16: return Monero.sixteenWordsWordList.contains(word); default: @@ -189,7 +190,7 @@ class _RestoreWalletViewState extends ConsumerState { } } if (widget.coin is Wownero) { - final wowneroWordList = libwow.wownero.getWowneroWordList( + final wowneroWordList = lib_monero.getWowneroWordList( "English", seedWordsLength: widget.seedWordsLength, ); @@ -219,29 +220,35 @@ class _RestoreWalletViewState extends ConsumerState { int height = 0; String? otherDataJsonString; - if (widget.coin is Monero) { - height = libxmr.monero.getHeigthByDate(date: widget.restoreFromDate); - } else if (widget.coin is Wownero) { - height = libwow.wownero.getHeightByDate(date: widget.restoreFromDate); + if (widget.restoreFromDate != null) { + if (widget.coin is Monero) { + height = cs_monero_deprecated.getMoneroHeightByDate( + date: widget.restoreFromDate!, + ); + } + if (widget.coin is Wownero) { + height = cs_monero_deprecated.getWowneroHeightByDate( + date: widget.restoreFromDate!, + ); + } + if (height < 0) { + height = 0; + } } - // todo: wait until this implemented - // else if (widget.coin is Wownero) { - // height = wownero.getHeightByDate(date: widget.restoreFromDate); - // } // TODO: make more robust estimate of date maybe using https://explorer.epic.tech/api-index if (widget.coin is Epiccash) { - final int secondsSinceEpoch = - widget.restoreFromDate.millisecondsSinceEpoch ~/ 1000; - const int epicCashFirstBlock = 1565370278; - const double overestimateSecondsPerBlock = 61; - final int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock; - final int approximateHeight = - chosenSeconds ~/ overestimateSecondsPerBlock; - //todo: check if print needed - // debugPrint( - // "approximate height: $approximateHeight chosen_seconds: $chosenSeconds"); - height = approximateHeight; + if (widget.restoreFromDate != null) { + final int secondsSinceEpoch = + widget.restoreFromDate!.millisecondsSinceEpoch ~/ 1000; + const int epicCashFirstBlock = 1565370278; + const double overestimateSecondsPerBlock = 61; + final int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock; + final int approximateHeight = + chosenSeconds ~/ overestimateSecondsPerBlock; + + height = approximateHeight; + } if (height < 0) { height = 0; } @@ -282,7 +289,7 @@ class _RestoreWalletViewState extends ConsumerState { ), ); } else { - if (!Platform.isLinux) await Wakelock.enable(); + if (!Platform.isLinux) await WakelockPlus.enable(); final info = WalletInfo.createNew( coin: widget.coin, @@ -426,12 +433,12 @@ class _RestoreWalletViewState extends ConsumerState { } if (!Platform.isLinux && !isDesktop) { - await Wakelock.disable(); + await WakelockPlus.disable(); } } } catch (e) { if (!Platform.isLinux && !isDesktop) { - await Wakelock.disable(); + await WakelockPlus.disable(); } // if (e is HiveError && @@ -463,7 +470,7 @@ class _RestoreWalletViewState extends ConsumerState { } if (!Platform.isLinux && !isDesktop) { - await Wakelock.disable(); + await WakelockPlus.disable(); } } } @@ -648,16 +655,18 @@ class _RestoreWalletViewState extends ConsumerState { const Duration(milliseconds: 100), ); - await showDialog( - context: context, - useSafeArea: false, - barrierDismissible: true, - builder: (context) { - return ConfirmRecoveryDialog( - onConfirm: attemptRestore, - ); - }, - ); + if (mounted) { + await showDialog( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return ConfirmRecoveryDialog( + onConfirm: attemptRestore, + ); + }, + ); + } } @override diff --git a/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart b/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart index 2a7a9fcae..e95e33539 100644 --- a/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart +++ b/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart @@ -9,13 +9,17 @@ */ import 'dart:async'; +import 'dart:convert'; import 'dart:math'; +import 'package:cs_monero/src/deprecated/get_height_by_date.dart' + as cs_monero_deprecated; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:tuple/tuple.dart'; +import '../../../models/keys/view_only_wallet_data.dart'; import '../../../notifications/show_flush_bar.dart'; import '../../../pages_desktop_specific/desktop_home_view.dart'; import '../../../pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart'; @@ -25,14 +29,25 @@ import '../../../providers/providers.dart'; import '../../../themes/stack_colors.dart'; import '../../../utilities/assets.dart'; import '../../../utilities/constants.dart'; +import '../../../utilities/logger.dart'; +import '../../../utilities/show_loading.dart'; import '../../../utilities/text_styles.dart'; import '../../../utilities/util.dart'; -import '../../../wallets/crypto_currency/coins/ethereum.dart'; +import '../../../wallets/crypto_currency/crypto_currency.dart'; +import '../../../wallets/crypto_currency/intermediate/bip39_hd_currency.dart'; +import '../../../wallets/isar/models/wallet_info.dart'; import '../../../wallets/isar/providers/wallet_info_provider.dart'; +import '../../../wallets/wallet/impl/epiccash_wallet.dart'; +import '../../../wallets/wallet/impl/monero_wallet.dart'; +import '../../../wallets/wallet/impl/wownero_wallet.dart'; +import '../../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../../wallets/wallet/wallet.dart'; +import '../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart'; +import '../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../widgets/desktop/desktop_app_bar.dart'; import '../../../widgets/desktop/desktop_scaffold.dart'; +import '../../../widgets/stack_dialog.dart'; import '../../home_view/home_view.dart'; import '../add_token_view/edit_wallet_tokens_view.dart'; import '../new_wallet_options/new_wallet_options_view.dart'; @@ -64,46 +79,25 @@ class _VerifyRecoveryPhraseViewState extends ConsumerState // with WidgetsBindingObserver { - late Wallet _wallet; + late String _walletId; + late CryptoCurrency _coin; late List _mnemonic; late final bool isDesktop; @override void initState() { - _wallet = widget.wallet; + _walletId = widget.wallet.walletId; + _coin = widget.wallet.cryptoCurrency; _mnemonic = widget.mnemonic; isDesktop = Util.isDesktop; - // WidgetsBinding.instance?.addObserver(this); super.initState(); } @override dispose() { - // WidgetsBinding.instance?.removeObserver(this); super.dispose(); } - // @override - // void didChangeAppLifecycleState(AppLifecycleState state) { - // switch (state) { - // case AppLifecycleState.inactive: - // debugPrint( - // "VerifyRecoveryPhraseView ========================= Inactive"); - // break; - // case AppLifecycleState.paused: - // debugPrint("VerifyRecoveryPhraseView ========================= Paused"); - // break; - // case AppLifecycleState.resumed: - // debugPrint( - // "VerifyRecoveryPhraseView ========================= Resumed"); - // break; - // case AppLifecycleState.detached: - // debugPrint( - // "VerifyRecoveryPhraseView ========================= Detached"); - // break; - // } - // } - Future _verifyMnemonicPassphrase() async { final result = await showDialog( context: context, @@ -113,6 +107,157 @@ class _VerifyRecoveryPhraseViewState return result == "verified"; } + Future _convertToViewOnly() async { + int height = 0; + final Map otherDataJson = { + WalletInfoKeys.isViewOnlyKey: true, + }; + + final ViewOnlyWalletType viewOnlyWalletType; + if (widget.wallet is ExtendedKeysInterface) { + if (widget.wallet.cryptoCurrency is Firo) { + otherDataJson.addAll( + { + WalletInfoKeys.lelantusCoinIsarRescanRequired: false, + WalletInfoKeys.enableLelantusScanning: false, + }, + ); + } + viewOnlyWalletType = ViewOnlyWalletType.xPub; + } else if (widget.wallet is LibMoneroWallet) { + if (widget.wallet.cryptoCurrency is Monero) { + height = cs_monero_deprecated.getMoneroHeightByDate( + date: DateTime.now().subtract(const Duration(days: 7)), + ); + } + if (widget.wallet.cryptoCurrency is Wownero) { + height = cs_monero_deprecated.getWowneroHeightByDate( + date: DateTime.now().subtract(const Duration(days: 7)), + ); + } + if (height < 0) height = 0; + + viewOnlyWalletType = ViewOnlyWalletType.cryptonote; + } else { + throw Exception( + "Unsupported view only wallet type found: ${widget.wallet.runtimeType}", + ); + } + + otherDataJson[WalletInfoKeys.viewOnlyTypeIndexKey] = + viewOnlyWalletType.index; + + final voInfo = WalletInfo.createNew( + coin: _coin, + name: widget.wallet.info.name, + restoreHeight: height, + otherDataJsonString: jsonEncode(otherDataJson), + ); + + final ViewOnlyWalletData viewOnlyData; + if (widget.wallet is ExtendedKeysInterface) { + final extendedKeyInfo = + await (widget.wallet as ExtendedKeysInterface).getXPubs(); + final testPath = (_coin as Bip39HDCurrency).constructDerivePath( + derivePathType: (_coin as Bip39HDCurrency).defaultDerivePathType, + chain: 0, + index: 0, + ); + + XPub? xPub; + for (final pub in extendedKeyInfo.xpubs) { + if (testPath.startsWith(pub.path)) { + xPub = pub; + break; + } + } + + if (xPub == null) { + throw Exception("Default derivation path not matched in xPubs"); + } + + viewOnlyData = ExtendedKeysViewOnlyWalletData( + walletId: voInfo.walletId, + xPubs: [xPub], + ); + } else if (widget.wallet is LibMoneroWallet) { + final w = widget.wallet as LibMoneroWallet; + + final info = await w + .hackToCreateNewViewOnlyWalletDataFromNewlyCreatedWalletThisFunctionShouldNotBeCalledUnlessYouKnowWhatYouAreDoing(); + final address = info.$1; + final privateViewKey = info.$2; + + await w.exit(); + + viewOnlyData = CryptonoteViewOnlyWalletData( + walletId: voInfo.walletId, + address: address, + privateViewKey: privateViewKey, + ); + } else { + throw Exception( + "Unsupported view only wallet type found: ${widget.wallet.runtimeType}", + ); + } + + final voWallet = await Wallet.create( + walletInfo: voInfo, + mainDB: ref.read(mainDBProvider), + secureStorageInterface: ref.read(secureStoreProvider), + nodeService: ref.read(nodeServiceChangeNotifierProvider), + prefs: ref.read(prefsChangeNotifierProvider), + viewOnlyData: viewOnlyData, + ); + + try { + // TODO: extract interface with isRestore param + switch (voWallet.runtimeType) { + case const (EpiccashWallet): + await (voWallet as EpiccashWallet).init(isRestore: true); + break; + + case const (MoneroWallet): + await (voWallet as MoneroWallet).init(isRestore: true); + break; + + case const (WowneroWallet): + await (voWallet as WowneroWallet).init(isRestore: true); + break; + + default: + await voWallet.init(); + } + + await voWallet.recover(isRescan: false); + + // don't remove this setMnemonicVerified thing + await voWallet.info.setMnemonicVerified( + isar: ref.read(mainDBProvider).isar, + ); + + ref.read(pWallets).addWallet(voWallet); + + await voWallet.exit(); + + await ref.read(pWallets).deleteWallet( + widget.wallet.info, + ref.read(secureStoreProvider), + ); + } catch (e) { + await ref.read(pWallets).deleteWallet( + widget.wallet.info, + ref.read(secureStoreProvider), + ); + await ref.read(pWallets).deleteWallet( + voWallet.info, + ref.read(secureStoreProvider), + ); + + rethrow; + } + } + Future _continue(bool isMatch) async { if (isMatch) { if (ref.read(pNewWalletOptions) != null && @@ -124,11 +269,11 @@ class _VerifyRecoveryPhraseViewState } } - await ref.read(pWalletInfo(_wallet.walletId)).setMnemonicVerified( + await ref.read(pWalletInfo(widget.wallet.walletId)).setMnemonicVerified( isar: ref.read(mainDBProvider).isar, ); - ref.read(pWallets).addWallet(_wallet); + ref.read(pWallets).addWallet(widget.wallet); final isCreateSpecialEthWallet = ref.read(createSpecialEthWalletRoutingFlag); @@ -142,6 +287,51 @@ class _VerifyRecoveryPhraseViewState .state; } + if (mounted && + ref.read(pNewWalletOptions)?.convertToViewOnly == true && + widget.wallet is ViewOnlyOptionInterface) { + try { + Exception? ex; + await showLoading( + whileFuture: _convertToViewOnly(), + context: context, + message: "Converting to view only wallet", + rootNavigator: Util.isDesktop, + onException: (e) { + ex = e; + }, + ); + + if (ex != null) { + throw ex!; + } + } catch (e, s) { + Logging.instance.log( + "$e\n$s", + level: LogLevel.Fatal, + ); + + if (mounted) { + await showDialog( + context: context, + builder: (_) => StackOkDialog( + title: e.toString(), + desktopPopRootNavigator: Util.isDesktop, + ), + ); + } + + if (mounted) { + Navigator.of(context).popUntil( + ModalRoute.withName( + NewWalletRecoveryPhraseView.routeName, + ), + ); + } + return; + } + } + if (mounted) { if (isDesktop) { if (isCreateSpecialEthWallet) { @@ -156,7 +346,7 @@ class _VerifyRecoveryPhraseViewState DesktopHomeView.routeName, ), ); - if (widget.wallet.info.coin is Ethereum) { + if (_coin is Ethereum) { unawaited( Navigator.of(context).pushNamed( EditWalletTokensView.routeName, @@ -179,7 +369,7 @@ class _VerifyRecoveryPhraseViewState (route) => false, ), ); - if (widget.wallet.info.coin is Ethereum) { + if (_coin is Ethereum) { unawaited( Navigator.of(context).pushNamed( EditWalletTokensView.routeName, @@ -269,7 +459,7 @@ class _VerifyRecoveryPhraseViewState Future delete() async { await ref.read(pWallets).deleteWallet( - _wallet.info, + widget.wallet.info, ref.read(secureStoreProvider), ); } @@ -299,7 +489,7 @@ class _VerifyRecoveryPhraseViewState trailing: ExitToMyStackButton( onPressed: () async { await delete(); - if (mounted) { + if (context.mounted) { Navigator.of(context).popUntil( ModalRoute.withName(DesktopHomeView.routeName), ); diff --git a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart index ba57db69b..d84cee567 100644 --- a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart +++ b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart @@ -66,6 +66,62 @@ class _NewContactAddressEntryFormState List coins = []; + void _onQrTapped() async { + try { + // ref + // .read(shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = false; + final qrResult = await widget.barcodeScanner.scan(); + + // Future.delayed( + // const Duration(seconds: 2), + // () => ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = true, + // ); + + final paymentData = AddressUtils.parsePaymentUri( + qrResult.rawContent, + logging: Logging.instance, + ); + + if (paymentData != null) { + addressController.text = paymentData.address; + ref.read(addressEntryDataProvider(widget.id)).address = + addressController.text.isEmpty ? null : addressController.text; + + addressLabelController.text = + paymentData.label ?? addressLabelController.text; + ref.read(addressEntryDataProvider(widget.id)).addressLabel = + addressLabelController.text.isEmpty + ? null + : addressLabelController.text; + + // now check for non standard encoded basic address + } else if (ref.read(addressEntryDataProvider(widget.id)).coin != null) { + if (ref.read(addressEntryDataProvider(widget.id)).coin!.validateAddress( + qrResult.rawContent, + )) { + addressController.text = qrResult.rawContent; + ref.read(addressEntryDataProvider(widget.id)).address = + qrResult.rawContent; + } + } + } on PlatformException catch (e, s) { + // ref + // .read(shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = true; + Logging.instance.log( + "Failed to get camera permissions to scan address qr code: $e\n$s", + level: LogLevel.Warning, + ); + } + } + @override void initState() { addressLabelController = TextEditingController() @@ -404,71 +460,7 @@ class _NewContactAddressEntryFormState null) TextFieldIconButton( key: const Key("addAddressBookEntryScanQrButtonKey"), - onTap: () async { - try { - // ref - // .read(shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = false; - final qrResult = await widget.barcodeScanner.scan(); - - // Future.delayed( - // const Duration(seconds: 2), - // () => ref - // .read( - // shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = true, - // ); - - final results = - AddressUtils.parseUri(qrResult.rawContent); - if (results.isNotEmpty) { - addressController.text = results["address"] ?? ""; - ref - .read(addressEntryDataProvider(widget.id)) - .address = - addressController.text.isEmpty - ? null - : addressController.text; - - addressLabelController.text = results["label"] ?? - addressLabelController.text; - ref - .read(addressEntryDataProvider(widget.id)) - .addressLabel = - addressLabelController.text.isEmpty - ? null - : addressLabelController.text; - - // now check for non standard encoded basic address - } else if (ref - .read(addressEntryDataProvider(widget.id)) - .coin != - null) { - if (ref - .read(addressEntryDataProvider(widget.id)) - .coin! - .validateAddress( - qrResult.rawContent, - )) { - addressController.text = qrResult.rawContent; - ref - .read(addressEntryDataProvider(widget.id)) - .address = qrResult.rawContent; - } - } - } on PlatformException catch (e, s) { - // ref - // .read(shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = true; - Logging.instance.log( - "Failed to get camera permissions to scan address qr code: $e\n$s", - level: LogLevel.Warning, - ); - } - }, + onTap: _onQrTapped, child: const QrCodeIcon(), ), const SizedBox( diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index 26ab7f254..f47831547 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -713,6 +713,60 @@ class _BuyFormState extends ConsumerState { } } + void _onQrTapped() async { + try { + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future.delayed( + const Duration(milliseconds: 75), + ); + } + + final qrResult = await scanner.scan(); + + Logging.instance.log( + "qrResult content: ${qrResult.rawContent}", + level: LogLevel.Info, + ); + + final paymentData = AddressUtils.parsePaymentUri( + qrResult.rawContent, + logging: Logging.instance, + ); + + Logging.instance.log( + "qrResult parsed: $paymentData", + level: LogLevel.Info, + ); + + if (paymentData != null) { + // auto fill address + _address = paymentData.address; + _receiveAddressController.text = _address!; + + setState(() { + _addressToggleFlag = _receiveAddressController.text.isNotEmpty; + }); + + // now check for non standard encoded basic address + } else { + _address = qrResult.rawContent; + _receiveAddressController.text = _address ?? ""; + + setState(() { + _addressToggleFlag = _receiveAddressController.text.isNotEmpty; + }); + } + } on PlatformException catch (e, s) { + // here we ignore the exception caused by not giving permission + // to use the camera to scan a qr code + Logging.instance.log( + "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", + level: LogLevel.Warning, + ); + } + } + @override void initState() { _receiveAddressController = TextEditingController(); @@ -1375,63 +1429,7 @@ class _BuyFormState extends ConsumerState { !isDesktop) TextFieldIconButton( key: const Key("buyViewScanQrButtonKey"), - onTap: () async { - try { - if (FocusScope.of(context).hasFocus) { - FocusScope.of(context).unfocus(); - await Future.delayed( - const Duration(milliseconds: 75), - ); - } - - final qrResult = await scanner.scan(); - - Logging.instance.log( - "qrResult content: ${qrResult.rawContent}", - level: LogLevel.Info, - ); - - final results = AddressUtils.parseUri( - qrResult.rawContent, - ); - - Logging.instance.log( - "qrResult parsed: $results", - level: LogLevel.Info, - ); - - if (results.isNotEmpty) { - // auto fill address - _address = results["address"] ?? ""; - _receiveAddressController.text = _address!; - - setState(() { - _addressToggleFlag = - _receiveAddressController - .text.isNotEmpty; - }); - - // now check for non standard encoded basic address - } else { - _address = qrResult.rawContent; - _receiveAddressController.text = - _address ?? ""; - - setState(() { - _addressToggleFlag = - _receiveAddressController - .text.isNotEmpty; - }); - } - } on PlatformException catch (e, s) { - // here we ignore the exception caused by not giving permission - // to use the camera to scan a qr code - Logging.instance.log( - "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", - level: LogLevel.Warning, - ); - } - }, + onTap: _onQrTapped, child: const QrCodeIcon(), ), ], diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index e4d787903..022fa0861 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -12,7 +12,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:wakelock/wakelock.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; import '../../pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; import '../../providers/cash_fusion/fusion_progress_ui_state_provider.dart'; @@ -85,7 +85,7 @@ class _FusionProgressViewState extends ConsumerState { message: "Stopping fusion", ); - await Wakelock.disable(); + await WakelockPlus.disable(); return true; } else { @@ -101,7 +101,7 @@ class _FusionProgressViewState extends ConsumerState { @override void dispose() { - Wakelock.disable(); + WakelockPlus.disable(); super.dispose(); } @@ -117,7 +117,7 @@ class _FusionProgressViewState extends ConsumerState { .watch(fusionProgressUIStateProvider(widget.walletId)) .fusionRoundsCompleted; - Wakelock.enable(); + WakelockPlus.enable(); return WillPopScope( onWillPop: () async { diff --git a/lib/pages/churning/churn_error_dialog.dart b/lib/pages/churning/churn_error_dialog.dart new file mode 100644 index 000000000..c9335faff --- /dev/null +++ b/lib/pages/churning/churn_error_dialog.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import '../../providers/churning/churning_service_provider.dart'; +import '../../utilities/text_styles.dart'; +import '../../utilities/util.dart'; +import '../../widgets/conditional_parent.dart'; +import '../../widgets/desktop/desktop_dialog.dart'; +import '../../widgets/desktop/primary_button.dart'; +import '../../widgets/desktop/secondary_button.dart'; +import '../../widgets/stack_dialog.dart'; + +class ChurnErrorDialog extends ConsumerWidget { + const ChurnErrorDialog({ + super.key, + required this.error, + required this.walletId, + }); + + final String error; + final String walletId; + + static const errorTitle = "An error occurred"; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return ConditionalParent( + condition: Util.isDesktop, + builder: (child) => DesktopDialog( + maxHeight: double.infinity, + child: child, + ), + child: ConditionalParent( + condition: !Util.isDesktop, + builder: (child) => StackDialogBase( + child: child, + ), + child: Column( + children: [ + Util.isDesktop + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 32, top: 32), + child: Text( + errorTitle, + style: STextStyles.desktopH2(context), + ), + ), + ], + ) + : Text( + errorTitle, + style: STextStyles.pageTitleH2(context), + ), + const SizedBox( + height: 20, + ), + Padding( + padding: Util.isDesktop + ? const EdgeInsets.all(32) + : const EdgeInsets.all(20), + child: Row( + children: [ + Flexible( + child: SelectableText( + error.startsWith("Exception:") + ? error.substring(10).trim() + : error, + ), + ), + ], + ), + ), + const SizedBox( + height: 20, + ), + Padding( + padding: Util.isDesktop + ? const EdgeInsets.all(32) + : const EdgeInsets.all(20), + child: Text( + "Stop churning or try and continue?", + style: Util.isDesktop + ? STextStyles.w600_14(context) + : STextStyles.w600_14(context), + ), + ), + Padding( + padding: EdgeInsets.only( + left: Util.isDesktop ? 32 : 20, + bottom: Util.isDesktop ? 32 : 20, + right: Util.isDesktop ? 32 : 20, + ), + child: Row( + children: [ + Expanded( + child: SecondaryButton( + label: "Stop", + onPressed: () { + ref.read(pChurningService(walletId)).stopChurning(); + Navigator.of(context).pop(); + }, + ), + ), + SizedBox( + width: Util.isDesktop ? 20 : 16, + ), + Expanded( + child: PrimaryButton( + label: "Continue", + onPressed: () { + ref.read(pChurningService(walletId)).unpause(); + Navigator.of(context).pop(); + }, + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/churning/churning_progress_view.dart b/lib/pages/churning/churning_progress_view.dart new file mode 100644 index 000000000..8e732e643 --- /dev/null +++ b/lib/pages/churning/churning_progress_view.dart @@ -0,0 +1,259 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; + +import '../../providers/churning/churning_service_provider.dart'; +import '../../themes/stack_colors.dart'; +import '../../utilities/assets.dart'; +import '../../utilities/text_styles.dart'; +import '../../widgets/background.dart'; +import '../../widgets/churning/churn_progress_item.dart'; +import '../../widgets/custom_buttons/app_bar_icon_button.dart'; +import '../../widgets/desktop/primary_button.dart'; +import '../../widgets/desktop/secondary_button.dart'; +import '../../widgets/rounded_container.dart'; +import '../../widgets/stack_dialog.dart'; +import 'churn_error_dialog.dart'; + +class ChurningProgressView extends ConsumerStatefulWidget { + const ChurningProgressView({ + super.key, + required this.walletId, + }); + + static const routeName = "/churningProgressView"; + + final String walletId; + @override + ConsumerState createState() => + _ChurningProgressViewState(); +} + +class _ChurningProgressViewState extends ConsumerState { + Future _requestAndProcessCancel() async { + final shouldCancel = await showDialog( + context: context, + barrierDismissible: false, + builder: (_) => StackDialog( + title: "Cancel churning?", + leftButton: SecondaryButton( + label: "No", + buttonHeight: null, + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + rightButton: PrimaryButton( + label: "Yes", + buttonHeight: null, + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ), + ); + + if (shouldCancel == true && mounted) { + ref.read(pChurningService(widget.walletId)).stopChurning(); + + await WakelockPlus.disable(); + + return true; + } else { + return false; + } + } + + @override + void initState() { + super.initState(); + + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) ref.read(pChurningService(widget.walletId)).churn(); + }); + } + + @override + void dispose() { + WakelockPlus.disable(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final bool _succeeded = ref.watch( + pChurningService(widget.walletId).select((s) => s.done), + ); + + final int _roundsCompleted = ref.watch( + pChurningService(widget.walletId).select((s) => s.roundsCompleted), + ); + + WakelockPlus.enable(); + + ref.listen( + pChurningService(widget.walletId).select((s) => s.lastSeenError), + (p, n) { + if (!ref.read(pChurningService(widget.walletId)).ignoreErrors && + n != null) { + if (context.mounted) { + showDialog( + context: context, + builder: (context) => ChurnErrorDialog( + error: n.toString(), + walletId: widget.walletId, + ), + ); + } + } + }, + ); + + return WillPopScope( + onWillPop: () async { + return await _requestAndProcessCancel(); + }, + child: Background( + child: SafeArea( + child: Scaffold( + backgroundColor: + Theme.of(context).extension()!.background, + appBar: AppBar( + automaticallyImplyLeading: false, + leading: AppBarBackButton( + onPressed: () async { + if (await _requestAndProcessCancel()) { + if (context.mounted) { + Navigator.of(context).pop(); + } + } + }, + ), + title: Text( + "Churning progress", + style: STextStyles.navBarTitle(context), + ), + titleSpacing: 0, + ), + body: LayoutBuilder( + builder: (builderContext, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (_roundsCompleted == 0) + RoundedContainer( + color: Theme.of(context) + .extension()! + .snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: + STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension()! + .snackBarTextError, + ), + textAlign: TextAlign.center, + ), + ), + if (_roundsCompleted > 0) + RoundedContainer( + color: Theme.of(context) + .extension()! + .snackBarBackInfo, + child: Text( + "Churning rounds completed: $_roundsCompleted", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .snackBarTextInfo, + ), + textAlign: TextAlign.center, + ), + ), + const SizedBox( + height: 20, + ), + ProgressItem( + iconAsset: Assets.svg.alertCircle, + label: "Waiting for balance to unlock ${ref.watch( + pChurningService(widget.walletId) + .select((s) => s.confirmsInfo), + ) ?? ""}", + status: ref.watch( + pChurningService(widget.walletId) + .select((s) => s.waitingForUnlockedBalance), + ), + ), + const SizedBox( + height: 12, + ), + ProgressItem( + iconAsset: Assets.svg.churn, + label: "Creating churn transaction", + status: ref.watch( + pChurningService(widget.walletId) + .select((s) => s.makingChurnTransaction), + ), + ), + const SizedBox( + height: 12, + ), + ProgressItem( + iconAsset: Assets.svg.checkCircle, + label: "Complete", + status: ref.watch( + pChurningService(widget.walletId) + .select((s) => s.completedStatus), + ), + ), + const Spacer(), + const SizedBox( + height: 16, + ), + if (_succeeded) + PrimaryButton( + label: "Churn again", + onPressed: ref + .read(pChurningService(widget.walletId)) + .churn, + ), + if (_succeeded) + const SizedBox( + height: 16, + ), + SecondaryButton( + label: "Cancel", + onPressed: () async { + if (await _requestAndProcessCancel()) { + if (context.mounted) { + Navigator.of(context).pop(); + } + } + }, + ), + ], + ), + ), + ), + ), + ); + }, + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/churning/churning_rounds_selection_sheet.dart b/lib/pages/churning/churning_rounds_selection_sheet.dart new file mode 100644 index 000000000..de21964e8 --- /dev/null +++ b/lib/pages/churning/churning_rounds_selection_sheet.dart @@ -0,0 +1,159 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; + +import '../../themes/stack_colors.dart'; +import '../../utilities/constants.dart'; +import '../../utilities/extensions/extensions.dart'; +import '../../utilities/text_styles.dart'; + +enum ChurnOption { + continuous, + custom; +} + +class ChurnRoundCountSelectSheet extends HookWidget { + const ChurnRoundCountSelectSheet({ + super.key, + required this.currentOption, + }); + + final ChurnOption currentOption; + + @override + Widget build(BuildContext context) { + final option = useState(currentOption); + + return WillPopScope( + onWillPop: () async { + Navigator.of(context).pop(option.value); + return false; + }, + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).extension()!.popupBG, + borderRadius: const BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + child: Padding( + padding: const EdgeInsets.only( + left: 24, + right: 24, + top: 10, + bottom: 0, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Container( + decoration: BoxDecoration( + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + width: 60, + height: 4, + ), + ), + const SizedBox( + height: 36, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Rounds of churn", + style: STextStyles.pageTitleH2(context), + textAlign: TextAlign.left, + ), + const SizedBox( + height: 20, + ), + for (int i = 0; i < ChurnOption.values.length; i++) + Column( + children: [ + GestureDetector( + onTap: () { + option.value = ChurnOption.values[i]; + Navigator.of(context).pop(option.value); + }, + child: Container( + color: Colors.transparent, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Column( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + SizedBox( + width: 20, + height: 20, + child: Radio( + activeColor: Theme.of(context) + .extension()! + .radioButtonIconEnabled, + value: ChurnOption.values[i], + groupValue: option.value, + onChanged: (_) { + option.value = ChurnOption.values[i]; + Navigator.of(context).pop(option.value); + }, + ), + ), + // ], + // ), + const SizedBox( + width: 12, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + ChurnOption.values[i].name.capitalize(), + style: STextStyles.titleBold12(context), + textAlign: TextAlign.left, + ), + const SizedBox( + height: 2, + ), + Text( + ChurnOption.values[i] == + ChurnOption.continuous + ? "Keep churning until manually stopped" + : "Stop after a set number of churns", + style: STextStyles.itemSubtitle12(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark3, + ), + textAlign: TextAlign.left, + ), + ], + ), + ], + ), + ), + ), + const SizedBox( + height: 16, + ), + ], + ), + const SizedBox( + height: 16, + ), + ], + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/churning/churning_view.dart b/lib/pages/churning/churning_view.dart new file mode 100644 index 000000000..d59042e5e --- /dev/null +++ b/lib/pages/churning/churning_view.dart @@ -0,0 +1,292 @@ +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 '../../providers/churning/churning_service_provider.dart'; +import '../../themes/stack_colors.dart'; +import '../../utilities/assets.dart'; +import '../../utilities/constants.dart'; +import '../../utilities/extensions/extensions.dart'; +import '../../utilities/text_styles.dart'; +import '../../widgets/background.dart'; +import '../../widgets/custom_buttons/app_bar_icon_button.dart'; +import '../../widgets/custom_buttons/checkbox_text_button.dart'; +import '../../widgets/desktop/primary_button.dart'; +import '../../widgets/rounded_container.dart'; +import '../../widgets/rounded_white_container.dart'; +import '../../widgets/stack_dialog.dart'; +import '../../widgets/stack_text_field.dart'; +import 'churning_progress_view.dart'; +import 'churning_rounds_selection_sheet.dart'; + +class ChurningView extends ConsumerStatefulWidget { + const ChurningView({ + super.key, + required this.walletId, + }); + + static const routeName = "/churnView"; + + final String walletId; + + @override + ConsumerState createState() => _ChurnViewState(); +} + +class _ChurnViewState extends ConsumerState { + late final TextEditingController churningRoundController; + late final FocusNode churningRoundFocusNode; + + bool _enableStartButton = false; + + ChurnOption _option = ChurnOption.continuous; + + Future _startChurn() async { + final churningService = ref.read(pChurningService(widget.walletId)); + + final int rounds = _option == ChurnOption.continuous + ? 0 + : int.parse(churningRoundController.text); + + churningService.rounds = rounds; + + await Navigator.of(context).pushNamed( + ChurningProgressView.routeName, + arguments: widget.walletId, + ); + } + + @override + void initState() { + churningRoundController = TextEditingController(); + + churningRoundFocusNode = FocusNode(); + + final rounds = ref.read(pChurningService(widget.walletId)).rounds; + + _option = rounds == 0 ? ChurnOption.continuous : ChurnOption.custom; + churningRoundController.text = rounds.toString(); + + _enableStartButton = churningRoundController.text.isNotEmpty; + + super.initState(); + } + + @override + void dispose() { + churningRoundController.dispose(); + churningRoundFocusNode.dispose(); + + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Background( + child: SafeArea( + child: Scaffold( + backgroundColor: + Theme.of(context).extension()!.background, + appBar: AppBar( + automaticallyImplyLeading: false, + leading: const AppBarBackButton(), + title: Text( + "Churn", + style: STextStyles.navBarTitle(context), + ), + titleSpacing: 0, + actions: [ + AspectRatio( + aspectRatio: 1, + child: AppBarIconButton( + size: 36, + icon: SvgPicture.asset( + Assets.svg.circleQuestion, + width: 20, + height: 20, + color: Theme.of(context) + .extension()! + .topNavIconPrimary, + ), + onPressed: () async { + await showDialog( + context: context, + builder: (context) => const StackOkDialog( + title: "What is churning?", + message: "Churning in a Monero wallet involves" + " sending Monero to oneself in multiple" + " transactions, which can enhance privacy" + " by making it harder for observers to " + "link your transactions. This process" + " re-mixes the funds within the network," + " helping obscure transaction history. " + "Churning is optional and mainly beneficial" + " in scenarios where maximum privacy is" + " desired or if you received the Monero from" + " a source from which you'd like to disassociate.", + ), + ); + }, + ), + ), + ], + ), + body: LayoutBuilder( + builder: (builderContext, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RoundedWhiteContainer( + child: Text( + "Churning helps anonymize your coins by mixing them.", + style: STextStyles.w500_12(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + ), + ), + const SizedBox( + height: 16, + ), + const SizedBox( + height: 16, + ), + Text( + "Configuration", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textDark3, + ), + ), + const SizedBox( + height: 12, + ), + RoundedContainer( + onPressed: () async { + final option = + await showModalBottomSheet( + backgroundColor: Colors.transparent, + context: context, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + builder: (_) { + return ChurnRoundCountSelectSheet( + currentOption: _option, + ); + }, + ); + if (option != null) { + setState(() { + _option = option; + }); + } + }, + color: Theme.of(context) + .extension()! + .textFieldActiveBG, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + _option.name.capitalize(), + style: STextStyles.w500_12(context), + ), + SvgPicture.asset( + Assets.svg.chevronDown, + width: 12, + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + ], + ), + ), + ), + if (_option == ChurnOption.custom) + const SizedBox( + height: 10, + ), + if (_option == ChurnOption.custom) + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: false, + enableSuggestions: false, + controller: churningRoundController, + focusNode: churningRoundFocusNode, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + keyboardType: TextInputType.number, + onChanged: (value) { + setState(() { + _enableStartButton = value.isNotEmpty; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Number of churns", + churningRoundFocusNode, + context, + ).copyWith( + labelText: "Enter number of churns..", + ), + ), + ), + const SizedBox( + height: 16, + ), + CheckboxTextButton( + label: "Pause on errors", + initialValue: !ref + .read(pChurningService(widget.walletId)) + .ignoreErrors, + onChanged: (value) { + ref + .read(pChurningService(widget.walletId)) + .ignoreErrors = !value; + }, + ), + const SizedBox( + height: 16, + ), + const Spacer(), + PrimaryButton( + label: "Start", + enabled: _enableStartButton, + onPressed: _startChurn, + ), + ], + ), + ), + ), + ), + ); + }, + ), + ), + ), + ); + } +} diff --git a/lib/pages/coin_control/utxo_details_view.dart b/lib/pages/coin_control/utxo_details_view.dart index 54a6f6e5a..d2b378f79 100644 --- a/lib/pages/coin_control/utxo_details_view.dart +++ b/lib/pages/coin_control/utxo_details_view.dart @@ -13,9 +13,9 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:isar/isar.dart'; + import '../../db/isar/main_db.dart'; import '../../models/isar/models/isar_models.dart'; -import '../wallet_view/transaction_views/transaction_details_view.dart'; import '../../providers/global/wallets_provider.dart'; import '../../themes/stack_colors.dart'; import '../../utilities/amount/amount.dart'; @@ -33,6 +33,7 @@ import '../../widgets/desktop/desktop_dialog_close_button.dart'; import '../../widgets/desktop/secondary_button.dart'; import '../../widgets/icon_widgets/utxo_status_icon.dart'; import '../../widgets/rounded_container.dart'; +import '../wallet_view/transaction_views/transaction_details_view.dart'; class UtxoDetailsView extends ConsumerStatefulWidget { const UtxoDetailsView({ diff --git a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart index 461dc2935..028ce0ac4 100644 --- a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart +++ b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart @@ -70,6 +70,78 @@ class _Step2ViewState extends ConsumerState { bool enableNext = false; + void _onRefundQrTapped() async { + try { + final qrResult = await scanner.scan(); + + final paymentData = AddressUtils.parsePaymentUri( + qrResult.rawContent, + logging: Logging.instance, + ); + + if (paymentData != null) { + // auto fill address + _refundController.text = paymentData.address; + model.refundAddress = _refundController.text; + + setState(() { + enableNext = _toController.text.isNotEmpty && + _refundController.text.isNotEmpty; + }); + } else { + _refundController.text = qrResult.rawContent; + model.refundAddress = _refundController.text; + + setState(() { + enableNext = _toController.text.isNotEmpty && + _refundController.text.isNotEmpty; + }); + } + } on PlatformException catch (e, s) { + Logging.instance.log( + "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", + level: LogLevel.Warning, + ); + } + } + + void _onToQrTapped() async { + try { + final qrResult = await scanner.scan(); + + final paymentData = AddressUtils.parsePaymentUri( + qrResult.rawContent, + logging: Logging.instance, + ); + + if (paymentData != null) { + // auto fill address + _toController.text = paymentData.address; + model.recipientAddress = _toController.text; + + setState(() { + enableNext = _toController.text.isNotEmpty && + (_refundController.text.isNotEmpty || + !ref.read(efExchangeProvider).supportsRefundAddress); + }); + } else { + _toController.text = qrResult.rawContent; + model.recipientAddress = _toController.text; + + setState(() { + enableNext = _toController.text.isNotEmpty && + (_refundController.text.isNotEmpty || + !!ref.read(efExchangeProvider).supportsRefundAddress); + }); + } + } on PlatformException catch (e, s) { + Logging.instance.log( + "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", + level: LogLevel.Warning, + ); + } + } + @override void initState() { model = widget.model; @@ -137,7 +209,7 @@ class _Step2ViewState extends ConsumerState { FocusScope.of(context).unfocus(); await Future.delayed(const Duration(milliseconds: 75)); } - if (mounted) { + if (context.mounted) { Navigator.of(context).pop(); } }, @@ -405,50 +477,7 @@ class _Step2ViewState extends ConsumerState { key: const Key( "sendViewScanQrButtonKey", ), - onTap: () async { - try { - final qrResult = - await scanner.scan(); - - final results = - AddressUtils.parseUri( - qrResult.rawContent, - ); - if (results.isNotEmpty) { - // auto fill address - _toController.text = - results["address"] ?? ""; - model.recipientAddress = - _toController.text; - - setState(() { - enableNext = _toController - .text.isNotEmpty && - (_refundController.text - .isNotEmpty || - !supportsRefund); - }); - } else { - _toController.text = - qrResult.rawContent; - model.recipientAddress = - _toController.text; - - setState(() { - enableNext = _toController - .text.isNotEmpty && - (_refundController.text - .isNotEmpty || - !supportsRefund); - }); - } - } on PlatformException catch (e, s) { - Logging.instance.log( - "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", - level: LogLevel.Warning, - ); - } - }, + onTap: _onToQrTapped, child: const QrCodeIcon(), ), ], @@ -685,51 +714,7 @@ class _Step2ViewState extends ConsumerState { key: const Key( "sendViewScanQrButtonKey", ), - onTap: () async { - try { - final qrResult = - await scanner.scan(); - - final results = - AddressUtils.parseUri( - qrResult.rawContent, - ); - if (results.isNotEmpty) { - // auto fill address - _refundController.text = - results["address"] ?? - ""; - model.refundAddress = - _refundController.text; - - setState(() { - enableNext = _toController - .text - .isNotEmpty && - _refundController - .text.isNotEmpty; - }); - } else { - _refundController.text = - qrResult.rawContent; - model.refundAddress = - _refundController.text; - - setState(() { - enableNext = _toController - .text - .isNotEmpty && - _refundController - .text.isNotEmpty; - }); - } - } on PlatformException catch (e, s) { - Logging.instance.log( - "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", - level: LogLevel.Warning, - ); - } - }, + onTap: _onRefundQrTapped, child: const QrCodeIcon(), ), ], diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart index 643768f19..f499775b1 100644 --- a/lib/pages/exchange_view/send_from_view.dart +++ b/lib/pages/exchange_view/send_from_view.dart @@ -35,7 +35,7 @@ import '../../wallets/crypto_currency/crypto_currency.dart'; import '../../wallets/isar/providers/wallet_info_provider.dart'; import '../../wallets/models/tx_data.dart'; import '../../wallets/wallet/impl/firo_wallet.dart'; -import '../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; +import '../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../widgets/background.dart'; import '../../widgets/conditional_parent.dart'; import '../../widgets/custom_buttons/app_bar_icon_button.dart'; @@ -277,7 +277,7 @@ class _SendFromCardState extends ConsumerState { // access to this screen but this is needed to get past an error that // would occur only to lead to another error which is why xmr/wow wallets // don't have access to this screen currently - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { await wallet.init(); await wallet.open(); } diff --git a/lib/pages/paynym/paynym_claim_view.dart b/lib/pages/paynym/paynym_claim_view.dart index 9bf9cb3cd..acabb388d 100644 --- a/lib/pages/paynym/paynym_claim_view.dart +++ b/lib/pages/paynym/paynym_claim_view.dart @@ -13,10 +13,8 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; + import '../../models/paynym/paynym_account.dart'; -import 'dialogs/claiming_paynym_dialog.dart'; -import 'paynym_home_view.dart'; -import '../wallet_view/wallet_view.dart'; import '../../providers/global/paynym_api_provider.dart'; import '../../providers/global/wallets_provider.dart'; import '../../providers/wallet/my_paynym_account_state_provider.dart'; @@ -30,6 +28,9 @@ import '../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../widgets/desktop/desktop_app_bar.dart'; import '../../widgets/desktop/desktop_scaffold.dart'; import '../../widgets/desktop/primary_button.dart'; +import '../wallet_view/wallet_view.dart'; +import 'dialogs/claiming_paynym_dialog.dart'; +import 'paynym_home_view.dart'; class PaynymClaimView extends ConsumerStatefulWidget { const PaynymClaimView({ @@ -197,7 +198,7 @@ class _PaynymClaimViewState extends ConsumerState { if (shouldCancel) return; - // attempt to create new entry in paynym.is db + // attempt to create new entry in [PaynymIsApi.baseURL] db final created = await ref .read(paynymAPIProvider) .create(pCode.toString()); diff --git a/lib/pages/paynym/subwidgets/paynym_bot.dart b/lib/pages/paynym/subwidgets/paynym_bot.dart index 1a6d6e469..384e471e5 100644 --- a/lib/pages/paynym/subwidgets/paynym_bot.dart +++ b/lib/pages/paynym/subwidgets/paynym_bot.dart @@ -11,8 +11,10 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; + import '../../../networking/http.dart'; import '../../../services/tor_service.dart'; +import '../../../utilities/paynym_is_api.dart'; import '../../../utilities/prefs.dart'; class PayNymBot extends StatelessWidget { @@ -50,7 +52,8 @@ class PayNymBot extends StatelessWidget { Future _fetchImage() async { final HTTP client = HTTP(); - final Uri uri = Uri.parse("https://paynym.is/$paymentCodeString/avatar"); + final Uri uri = + Uri.parse("${PaynymIsApi.baseURL}/$paymentCodeString/avatar"); final response = await client.get( url: uri, diff --git a/lib/pages/pinpad_views/lock_screen_view.dart b/lib/pages/pinpad_views/lock_screen_view.dart index 3c52c8efc..711a25a45 100644 --- a/lib/pages/pinpad_views/lock_screen_view.dart +++ b/lib/pages/pinpad_views/lock_screen_view.dart @@ -26,7 +26,7 @@ import '../../utilities/biometrics.dart'; import '../../utilities/flutter_secure_storage_interface.dart'; import '../../utilities/show_loading.dart'; import '../../utilities/text_styles.dart'; -import '../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; +import '../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../widgets/background.dart'; import '../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../widgets/custom_buttons/blue_text_button.dart'; @@ -102,7 +102,7 @@ class _LockscreenViewState extends ConsumerState { final wallet = ref.read(pWallets).getWallet(walletId); final Future loadFuture; - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { loadFuture = wallet.init().then((value) async => await (wallet).open()); } else { diff --git a/lib/pages/receive_view/addresses/address_details_view.dart b/lib/pages/receive_view/addresses/address_details_view.dart index 2006e900b..25e18becb 100644 --- a/lib/pages/receive_view/addresses/address_details_view.dart +++ b/lib/pages/receive_view/addresses/address_details_view.dart @@ -8,6 +8,7 @@ * */ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:isar/isar.dart'; @@ -147,6 +148,7 @@ class _AddressDetailsViewState extends ConsumerState { @override Widget build(BuildContext context) { final coin = ref.watch(pWalletCoin(widget.walletId)); + final wallet = ref.watch(pWallets).getWallet(widget.walletId); return ConditionalParent( condition: !isDesktop, builder: (child) => Background( @@ -372,13 +374,21 @@ class _AddressDetailsViewState extends ConsumerState { detail: address.subType.prettyName, button: Container(), ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is Bip39HDWallet) + if (kDebugMode) const _Div( height: 12, ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is Bip39HDWallet) + if (kDebugMode) + DetailItem( + title: "frost secure (kDebugMode)", + detail: address.zSafeFrost.toString(), + button: Container(), + ), + if (wallet is Bip39HDWallet && !wallet.isViewOnly) + const _Div( + height: 12, + ), + if (wallet is Bip39HDWallet && !wallet.isViewOnly) AddressPrivateKey( walletId: widget.walletId, address: address, diff --git a/lib/pages/receive_view/addresses/wallet_addresses_view.dart b/lib/pages/receive_view/addresses/wallet_addresses_view.dart index f464d0e57..6c1441b43 100644 --- a/lib/pages/receive_view/addresses/wallet_addresses_view.dart +++ b/lib/pages/receive_view/addresses/wallet_addresses_view.dart @@ -67,6 +67,19 @@ class _WalletAddressesViewState extends ConsumerState { .and() .not() .typeEqualTo(AddressType.nonWallet) + .and() + .group( + (q) => q + .group( + (q2) => q2 + .typeEqualTo(AddressType.frostMS) + .and() + .zSafeFrostEqualTo(true), + ) + .or() + .not() + .typeEqualTo(AddressType.frostMS), + ) .sortByDerivationIndex() .idProperty() .findAll(); @@ -114,6 +127,19 @@ class _WalletAddressesViewState extends ConsumerState { .and() .not() .typeEqualTo(AddressType.nonWallet) + .and() + .group( + (q) => q + .group( + (q2) => q2 + .typeEqualTo(AddressType.frostMS) + .and() + .zSafeFrostEqualTo(true), + ) + .or() + .not() + .typeEqualTo(AddressType.frostMS), + ) .sortByDerivationIndex() .idProperty() .findAll(); diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart index f9049a538..dfe85d934 100644 --- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart +++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart @@ -97,7 +97,7 @@ class _GenerateUriQrCodeViewState extends State { initialDirectory: dir.path, ); - if (path != null) { + if (path != null && mounted) { final file = File(path); if (file.existsSync()) { unawaited( @@ -109,13 +109,15 @@ class _GenerateUriQrCodeViewState extends State { ); } else { await file.writeAsBytes(pngBytes); - unawaited( - showFloatingFlushBar( - type: FlushBarType.success, - message: "$path saved!", - context: context, - ), - ); + if (mounted) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.success, + message: "$path saved!", + context: context, + ), + ); + } } } } else { @@ -144,7 +146,18 @@ class _GenerateUriQrCodeViewState extends State { final amountString = amountController.text; final noteString = noteController.text; - if (amountString.isNotEmpty && Decimal.tryParse(amountString) == null) { + // try "." + Decimal? amount = Decimal.tryParse(amountString); + if (amount == null) { + // try single instance of "," + final first = amountString.indexOf(","); + final last = amountString.lastIndexOf(","); + if (first == last) { + amount = Decimal.tryParse(amountString.replaceFirst(",", ".")); + } + } + + if (amountString.isNotEmpty && amount == null) { showFloatingFlushBar( type: FlushBarType.warning, message: "Invalid amount", @@ -156,7 +169,7 @@ class _GenerateUriQrCodeViewState extends State { final Map queryParams = {}; if (amountString.isNotEmpty) { - queryParams["amount"] = amountString; + queryParams["amount"] = amount.toString(); } if (noteString.isNotEmpty) { queryParams["message"] = noteString; @@ -300,7 +313,7 @@ class _GenerateUriQrCodeViewState extends State { FocusScope.of(context).unfocus(); await Future.delayed(const Duration(milliseconds: 70)); } - if (mounted) { + if (context.mounted) { Navigator.of(context).pop(); } }, diff --git a/lib/pages/receive_view/receive_view.dart b/lib/pages/receive_view/receive_view.dart index a40262cdc..636a05ab8 100644 --- a/lib/pages/receive_view/receive_view.dart +++ b/lib/pages/receive_view/receive_view.dart @@ -18,6 +18,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:isar/isar.dart'; import '../../models/isar/models/isar_models.dart'; +import '../../models/keys/view_only_wallet_data.dart'; import '../../notifications/show_flush_bar.dart'; import '../../providers/db/main_db_provider.dart'; import '../../providers/providers.dart'; @@ -36,6 +37,7 @@ import '../../wallets/wallet/intermediate/bip39_hd_wallet.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/bcash_interface.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/multi_address_interface.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/spark_interface.dart'; +import '../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../widgets/background.dart'; import '../../widgets/conditional_parent.dart'; import '../../widgets/custom_buttons/app_bar_icon_button.dart'; @@ -113,9 +115,15 @@ class _ReceiveViewState extends ConsumerState { address = await wallet.generateNextReceivingAddress( derivePathType: type, ); - await ref.read(mainDBProvider).isar.writeTxn(() async { - await ref.read(mainDBProvider).isar.addresses.put(address!); + final isar = ref.read(mainDBProvider).isar; + await isar.writeTxn(() async { + await isar.addresses.put(address!); }); + final info = ref.read(pWalletInfo(walletId)); + await info.updateReceivingAddress( + newAddress: address.value, + isar: isar, + ); } else { await wallet.generateNewReceivingAddress(); address = null; @@ -183,10 +191,15 @@ class _ReceiveViewState extends ConsumerState { clipboard = widget.clipboard; final wallet = ref.read(pWallets).getWallet(walletId); _supportsSpark = wallet is SparkInterface; - _showMultiType = _supportsSpark || - (wallet is! BCashInterface && - wallet is Bip39HDWallet && - wallet.supportedAddressTypes.length > 1); + + if (wallet is ViewOnlyOptionInterface && wallet.isViewOnly) { + _showMultiType = false; + } else { + _showMultiType = _supportsSpark || + (wallet is! BCashInterface && + wallet is Bip39HDWallet && + wallet.supportedAddressTypes.length > 1); + } _walletAddressTypes.add(wallet.info.mainAddressType); @@ -259,6 +272,18 @@ class _ReceiveViewState extends ConsumerState { address = ref.watch(pWalletReceivingAddress(walletId)); } + final wallet = + ref.watch(pWallets.select((value) => value.getWallet(walletId))); + + final bool canGen; + if (wallet is ViewOnlyOptionInterface && + wallet.isViewOnly && + wallet.viewOnlyType == ViewOnlyWalletType.addressOnly) { + canGen = false; + } else { + canGen = (wallet is MultiAddressInterface || _supportsSpark); + } + return Background( child: Scaffold( backgroundColor: Theme.of(context).extension()!.background, @@ -547,17 +572,11 @@ class _ReceiveViewState extends ConsumerState { ); }, ), - if (ref.watch( - pWallets.select((value) => value.getWallet(walletId)), - ) is MultiAddressInterface || - _supportsSpark) + if (canGen) const SizedBox( height: 12, ), - if (ref.watch( - pWallets.select((value) => value.getWallet(walletId)), - ) is MultiAddressInterface || - _supportsSpark) + if (canGen) SecondaryButton( label: "Generate new address", onPressed: _supportsSpark && diff --git a/lib/pages/send_view/frost_ms/recipient.dart b/lib/pages/send_view/frost_ms/recipient.dart index 6d9d9b7c4..ce38153e7 100644 --- a/lib/pages/send_view/frost_ms/recipient.dart +++ b/lib/pages/send_view/frost_ms/recipient.dart @@ -120,6 +120,69 @@ class _RecipientState extends ConsumerState { } } + void _onQrTapped() async { + try { + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future.delayed( + const Duration( + milliseconds: 75, + ), + ); + } + + final qrResult = await ref.read(pBarcodeScanner).scan(); + + Logging.instance.log( + "qrResult content: ${qrResult.rawContent}", + level: LogLevel.Info, + ); + + final paymentData = AddressUtils.parsePaymentUri( + qrResult.rawContent, + logging: Logging.instance, + ); + + Logging.instance.log( + "qrResult parsed: $paymentData", + level: LogLevel.Info, + ); + + if (paymentData != null && + paymentData.coin?.uriScheme == widget.coin.uriScheme) { + // auto fill address + + addressController.text = paymentData.address.trim(); + + // autofill amount field + if (paymentData.amount != null) { + final Amount amount = Decimal.parse(paymentData.amount!).toAmount( + fractionDigits: widget.coin.fractionDigits, + ); + amountController.text = + ref.read(pAmountFormatter(widget.coin)).format( + amount, + withUnitName: false, + ); + } + } else { + addressController.text = qrResult.rawContent.trim(); + } + + setState(() { + _addressIsEmpty = addressController.text.isEmpty; + }); + + _updateRecipientData(); + } on PlatformException catch (e, s) { + Logging.instance.log( + "Failed to get camera permissions while " + "trying to scan qr code in SendView: $e\n$s", + level: LogLevel.Warning, + ); + } + } + @override void initState() { addressController = TextEditingController(); @@ -289,76 +352,7 @@ class _RecipientState extends ConsumerState { key: const Key( "sendViewScanQrButtonKey", ), - onTap: () async { - try { - if (FocusScope.of(context).hasFocus) { - FocusScope.of(context).unfocus(); - await Future.delayed( - const Duration( - milliseconds: 75, - ), - ); - } - - final qrResult = - await ref.read(pBarcodeScanner).scan(); - - Logging.instance.log( - "qrResult content: ${qrResult.rawContent}", - level: LogLevel.Info, - ); - - /// TODO: deal with address utils - final results = - AddressUtils.parseUri(qrResult.rawContent); - - Logging.instance.log( - "qrResult parsed: $results", - level: LogLevel.Info, - ); - - if (results.isNotEmpty && - results["scheme"] == - widget.coin.uriScheme) { - // auto fill address - - addressController.text = - (results["address"] ?? "").trim(); - - // autofill amount field - if (results["amount"] != null) { - final Amount amount = - Decimal.parse(results["amount"]!) - .toAmount( - fractionDigits: - widget.coin.fractionDigits, - ); - amountController.text = ref - .read(pAmountFormatter(widget.coin)) - .format( - amount, - withUnitName: false, - ); - } - } else { - addressController.text = - qrResult.rawContent.trim(); - } - - setState(() { - _addressIsEmpty = - addressController.text.isEmpty; - }); - - _updateRecipientData(); - } on PlatformException catch (e, s) { - Logging.instance.log( - "Failed to get camera permissions while " - "trying to scan qr code in SendView: $e\n$s", - level: LogLevel.Warning, - ); - } - }, + onTap: _onQrTapped, child: const QrCodeIcon(), ), ], diff --git a/lib/pages/send_view/frost_ms/send_steps/frost_send_step_1b.dart b/lib/pages/send_view/frost_ms/send_steps/frost_send_step_1b.dart index 058b980c5..b7c95ea2c 100644 --- a/lib/pages/send_view/frost_ms/send_steps/frost_send_step_1b.dart +++ b/lib/pages/send_view/frost_ms/send_steps/frost_send_step_1b.dart @@ -67,6 +67,7 @@ class _FrostSendStep1bState extends ConsumerState { final data = Frost.extractDataFromSignConfig( signConfig: config, coin: wallet.cryptoCurrency, + serializedKeys: (await wallet.getSerializedKeys())!, ); final utxos = await ref diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index cd7d5f01a..1dd9b68ef 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -11,7 +11,7 @@ import 'dart:async'; import 'dart:io'; -import 'package:cw_core/monero_transaction_priority.dart'; +import 'package:cs_monero/cs_monero.dart' as lib_monero; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -163,9 +163,13 @@ class _SendViewState extends ConsumerState { level: LogLevel.Info, ); - final paymentData = AddressUtils.parsePaymentUri(qrResult.rawContent); + final paymentData = AddressUtils.parsePaymentUri( + qrResult.rawContent, + logging: Logging.instance, + ); - if (paymentData.coin.uriScheme == coin.uriScheme) { + if (paymentData != null && + paymentData.coin?.uriScheme == coin.uriScheme) { // auto fill address _address = paymentData.address.trim(); sendToController.text = _address!; @@ -195,12 +199,8 @@ class _SendViewState extends ConsumerState { }); // now check for non standard encoded basic address - } else if (ref - .read(pWallets) - .getWallet(walletId) - .cryptoCurrency - .validateAddress(qrResult.rawContent)) { - _address = qrResult.rawContent.trim(); + } else { + _address = qrResult.rawContent.split("\n").first.trim(); sendToController.text = _address ?? ""; _setValidAddressProviders(_address); @@ -470,22 +470,22 @@ class _SendViewState extends ConsumerState { Amount fee; if (coin is Monero) { - MoneroTransactionPriority specialMoneroId; + lib_monero.TransactionPriority specialMoneroId; switch (ref.read(feeRateTypeStateProvider.state).state) { case FeeRateType.fast: - specialMoneroId = MoneroTransactionPriority.fast; + specialMoneroId = lib_monero.TransactionPriority.high; break; case FeeRateType.average: - specialMoneroId = MoneroTransactionPriority.regular; + specialMoneroId = lib_monero.TransactionPriority.medium; break; case FeeRateType.slow: - specialMoneroId = MoneroTransactionPriority.slow; + specialMoneroId = lib_monero.TransactionPriority.normal; break; default: throw ArgumentError("custom fee not available for monero"); } - fee = await wallet.estimateFeeFor(amount, specialMoneroId.raw!); + fee = await wallet.estimateFeeFor(amount, specialMoneroId.value); cachedFees[amount] = ref.read(pAmountFormatter(coin)).format( fee, withUnitName: true, diff --git a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart index a70098c03..0ca0dba47 100644 --- a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart +++ b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart @@ -8,9 +8,10 @@ * */ -import 'package:cw_core/monero_transaction_priority.dart'; import 'package:flutter/material.dart'; +import 'package:cs_monero/cs_monero.dart' as lib_monero; import 'package:flutter_riverpod/flutter_riverpod.dart'; + import '../../../models/paymint/fee_object_model.dart'; import '../../../providers/providers.dart'; import '../../../providers/ui/fee_rate_type_state_provider.dart'; @@ -90,7 +91,7 @@ class _TransactionFeeSelectionSheetState if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.fast.raw!, + lib_monero.TransactionPriority.high.value, ); ref.read(feeSheetSessionCacheProvider).fast[amount] = fee; } else if (coin is Firo) { @@ -127,7 +128,7 @@ class _TransactionFeeSelectionSheetState if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.regular.raw!, + lib_monero.TransactionPriority.medium.value, ); ref.read(feeSheetSessionCacheProvider).average[amount] = fee; } else if (coin is Firo) { @@ -163,7 +164,7 @@ class _TransactionFeeSelectionSheetState if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.slow.raw!, + lib_monero.TransactionPriority.normal.value, ); ref.read(feeSheetSessionCacheProvider).slow[amount] = fee; } else if (coin is Firo) { diff --git a/lib/pages/send_view/token_send_view.dart b/lib/pages/send_view/token_send_view.dart index 7f82cc0e5..3ad00fe40 100644 --- a/lib/pages/send_view/token_send_view.dart +++ b/lib/pages/send_view/token_send_view.dart @@ -163,25 +163,30 @@ class _TokenSendViewState extends ConsumerState { level: LogLevel.Info, ); - final results = AddressUtils.parseUri(qrResult.rawContent); + final paymentData = AddressUtils.parsePaymentUri( + qrResult.rawContent, + logging: Logging.instance, + ); - Logging.instance.log("qrResult parsed: $results", level: LogLevel.Info); + Logging.instance + .log("qrResult parsed: $paymentData", level: LogLevel.Info); - if (results.isNotEmpty && results["scheme"] == coin.uriScheme) { + if (paymentData != null && + paymentData.coin?.uriScheme == coin.uriScheme) { // auto fill address - _address = (results["address"] ?? "").trim(); + _address = paymentData.address.trim(); sendToController.text = _address!; // autofill notes field - if (results["message"] != null) { - noteController.text = results["message"]!; - } else if (results["label"] != null) { - noteController.text = results["label"]!; + if (paymentData.message != null) { + noteController.text = paymentData.message!; + } else if (paymentData.label != null) { + noteController.text = paymentData.label!; } // autofill amount field - if (results["amount"] != null) { - final Amount amount = Decimal.parse(results["amount"]!).toAmount( + if (paymentData.amount != null) { + final Amount amount = Decimal.parse(paymentData.amount!).toAmount( fractionDigits: tokenContract.decimals, ); cryptoAmountController.text = ref.read(pAmountFormatter(coin)).format( @@ -198,12 +203,8 @@ class _TokenSendViewState extends ConsumerState { }); // now check for non standard encoded basic address - } else if (ref - .read(pWallets) - .getWallet(walletId) - .cryptoCurrency - .validateAddress(qrResult.rawContent)) { - _address = qrResult.rawContent.trim(); + } else { + _address = qrResult.rawContent.split("\n").first.trim(); sendToController.text = _address ?? ""; _updatePreviewButtonState(_address, _amountToSend); diff --git a/lib/pages/settings_views/global_settings_view/about_view.dart b/lib/pages/settings_views/global_settings_view/about_view.dart index f4c3eb7ec..b72c3222c 100644 --- a/lib/pages/settings_views/global_settings_view/about_view.dart +++ b/lib/pages/settings_views/global_settings_view/about_view.dart @@ -272,48 +272,48 @@ class AboutView extends ConsumerWidget { const SizedBox( height: 12, ), - if (AppConfig.coins.whereType().isNotEmpty) - FutureBuilder( - future: GitStatus.getMoneroCommitStatus(), - builder: ( - context, - AsyncSnapshot snapshot, - ) { - CommitStatus stateOfCommit = - CommitStatus.notLoaded; - - if (snapshot.connectionState == - ConnectionState.done && - snapshot.hasData) { - stateOfCommit = snapshot.data!; - } - return RoundedWhiteContainer( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.stretch, - children: [ - Text( - "Monero Build Commit", - style: STextStyles.titleBold12(context), - ), - const SizedBox( - height: 4, - ), - SelectableText( - GitStatus.moneroCommit, - style: GitStatus.styleForStatus( - stateOfCommit, - context, - ), - ), - ], - ), - ); - }, - ), - const SizedBox( - height: 12, - ), + // if (AppConfig.coins.whereType().isNotEmpty) + // FutureBuilder( + // future: GitStatus.getMoneroCommitStatus(), + // builder: ( + // context, + // AsyncSnapshot snapshot, + // ) { + // CommitStatus stateOfCommit = + // CommitStatus.notLoaded; + // + // if (snapshot.connectionState == + // ConnectionState.done && + // snapshot.hasData) { + // stateOfCommit = snapshot.data!; + // } + // return RoundedWhiteContainer( + // child: Column( + // crossAxisAlignment: + // CrossAxisAlignment.stretch, + // children: [ + // Text( + // "Monero Build Commit", + // style: STextStyles.titleBold12(context), + // ), + // const SizedBox( + // height: 4, + // ), + // SelectableText( + // GitStatus.moneroCommit, + // style: GitStatus.styleForStatus( + // stateOfCommit, + // context, + // ), + // ), + // ], + // ), + // ); + // }, + // ), + // const SizedBox( + // height: 12, + // ), RoundedWhiteContainer( child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/pages/settings_views/global_settings_view/advanced_views/debug_view.dart b/lib/pages/settings_views/global_settings_view/advanced_views/debug_view.dart index 81297430e..92e5cc256 100644 --- a/lib/pages/settings_views/global_settings_view/advanced_views/debug_view.dart +++ b/lib/pages/settings_views/global_settings_view/advanced_views/debug_view.dart @@ -18,7 +18,7 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_libepiccash/git_versions.dart' as EPIC_VERSIONS; -import 'package:flutter_libmonero/git_versions.dart' as MONERO_VERSIONS; +// import 'package:flutter_libmonero/git_versions.dart' as MONERO_VERSIONS; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:lelantus/git_versions.dart' as FIRO_VERSIONS; @@ -313,8 +313,8 @@ class _DebugViewState extends ConsumerState { FIRO_VERSIONS.getPluginVersion(); final String epicCashCommit = EPIC_VERSIONS.getPluginVersion(); - final String moneroCommit = - MONERO_VERSIONS.getPluginVersion(); + // final String moneroCommit = + // MONERO_VERSIONS.getPluginVersion(); final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin(); final deviceInfo = @@ -347,7 +347,7 @@ class _DebugViewState extends ConsumerState { "appName": appName, "firoCommit": firoCommit, "epicCashCommit": epicCashCommit, - "moneroCommit": moneroCommit, + // "moneroCommit": moneroCommit, "deviceInfoMap": deviceInfoMap, "errorLogs": errorLogs, }; diff --git a/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/manage_coin_units_view.dart b/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/manage_coin_units_view.dart index cd2f7d231..28ebe18a9 100644 --- a/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/manage_coin_units_view.dart +++ b/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/manage_coin_units_view.dart @@ -3,9 +3,9 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; -import 'edit_coin_units_view.dart'; -import '../../../../../providers/global/prefs_provider.dart'; + import '../../../../../app_config.dart'; +import '../../../../../providers/global/prefs_provider.dart'; import '../../../../../themes/coin_icon_provider.dart'; import '../../../../../themes/stack_colors.dart'; import '../../../../../utilities/assets.dart'; @@ -18,6 +18,7 @@ import '../../../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../../../widgets/desktop/desktop_dialog.dart'; import '../../../../../widgets/desktop/desktop_dialog_close_button.dart'; import '../../../../../widgets/rounded_white_container.dart'; +import 'edit_coin_units_view.dart'; class ManageCoinUnitsView extends ConsumerWidget { const ManageCoinUnitsView({super.key}); @@ -44,13 +45,9 @@ class ManageCoinUnitsView extends ConsumerWidget { prefsChangeNotifierProvider.select((value) => value.showTestNetCoins), ); - final _coins = AppConfig.coins - .where((e) => e is! Firo && e.network != CryptoCurrencyNetwork.test) - .toList(); - final coins = showTestNet - ? _coins - : _coins.where((e) => e.network != CryptoCurrencyNetwork.test).toList(); + ? AppConfig.coins + : AppConfig.coins.where((e) => !e.network.isTestNet).toList(); return ConditionalParent( condition: Util.isDesktop, diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart index 478440c99..7888635b7 100644 --- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart +++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart @@ -29,7 +29,7 @@ import '../../../../utilities/text_styles.dart'; import '../../../../utilities/util.dart'; import '../../../../wallets/crypto_currency/crypto_currency.dart'; import '../../../../wallets/crypto_currency/intermediate/cryptonote_currency.dart'; -import '../../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; +import '../../../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../../../widgets/background.dart'; import '../../../../widgets/conditional_parent.dart'; import '../../../../widgets/custom_buttons/app_bar_icon_button.dart'; @@ -222,7 +222,7 @@ class _AddEditNodeViewState extends ConsumerState { // strip unused path String address = formData.host!; - if (coin is CwBasedInterface) { + if (coin is LibMoneroWallet) { if (address.startsWith("http")) { final uri = Uri.parse(address); address = "${uri.scheme}://${uri.host}"; @@ -837,7 +837,7 @@ class _NodeFormState extends ConsumerState { } else { enableSSLCheckbox = true; } - } else if (widget.coin is CwBasedInterface) { + } else if (widget.coin is LibMoneroWallet) { if (newValue.startsWith("https://")) { _useSSL = true; } else if (newValue.startsWith("http://")) { @@ -1052,7 +1052,7 @@ class _NodeFormState extends ConsumerState { ), ], ), - if (widget.coin is CwBasedInterface) + if (widget.coin is LibMoneroWallet) Row( children: [ GestureDetector( diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart index e44d352f4..a7756f662 100644 --- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart +++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart @@ -62,7 +62,7 @@ class _ManageNodesViewState extends ConsumerState { final coins = showTestNet ? _coins - : _coins.where((e) => e.network != CryptoCurrencyNetwork.test).toList(); + : _coins.where((e) => !e.network.isTestNet).toList(); return Background( child: Scaffold( diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart index d0f964116..6d99938b3 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart @@ -18,7 +18,7 @@ import 'package:isar/isar.dart'; import 'package:stack_wallet_backup/stack_wallet_backup.dart'; import 'package:tuple/tuple.dart'; import 'package:uuid/uuid.dart'; -import 'package:wakelock/wakelock.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; import '../../../../../app_config.dart'; import '../../../../../db/hive/db.dart'; @@ -27,6 +27,7 @@ import '../../../../../models/exchange/change_now/exchange_transaction.dart'; import '../../../../../models/exchange/response_objects/trade.dart'; import '../../../../../models/isar/models/contact_entry.dart'; import '../../../../../models/isar/models/transaction_note.dart'; +import '../../../../../models/keys/view_only_wallet_data.dart'; import '../../../../../models/node_model.dart'; import '../../../../../models/stack_restoring_ui_state.dart'; import '../../../../../models/trade_wallet_lookup.dart'; @@ -54,10 +55,11 @@ import '../../../../../wallets/wallet/impl/bitcoin_frost_wallet.dart'; import '../../../../../wallets/wallet/impl/epiccash_wallet.dart'; import '../../../../../wallets/wallet/impl/monero_wallet.dart'; import '../../../../../wallets/wallet/impl/wownero_wallet.dart'; +import '../../../../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../../../../wallets/wallet/wallet.dart'; -import '../../../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/private_key_interface.dart'; +import '../../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; class PreRestoreState { final Set walletIds; @@ -312,7 +314,10 @@ abstract class SWB { backupWallet['isFavorite'] = wallet.info.isFavourite; backupWallet['otherDataJsonString'] = wallet.info.otherDataJsonString; - if (wallet is MnemonicInterface) { + if (wallet is ViewOnlyOptionInterface && wallet.isViewOnly) { + backupWallet['viewOnlyWalletDataKey'] = + (await wallet.getViewOnlyWalletData()).toJsonEncodedString(); + } else if (wallet is MnemonicInterface) { backupWallet['mnemonic'] = await wallet.getMnemonic(); backupWallet['mnemonicPassphrase'] = await wallet.getMnemonicPassphrase(); @@ -419,7 +424,16 @@ abstract class SWB { String? mnemonic, mnemonicPassphrase, privateKey; - if (walletbackup['mnemonic'] == null) { + ViewOnlyWalletData? viewOnlyData; + if (info.isViewOnly) { + final viewOnlyDataEncoded = + walletbackup['viewOnlyWalletDataKey'] as String; + + viewOnlyData = ViewOnlyWalletData.fromJsonEncodedString( + viewOnlyDataEncoded, + walletId: info.walletId, + ); + } else if (walletbackup['mnemonic'] == null) { // probably private key based if (walletbackup['privateKey'] != null) { privateKey = walletbackup['privateKey'] as String; @@ -486,6 +500,7 @@ abstract class SWB { mnemonic: mnemonic, mnemonicPassphrase: mnemonicPassphrase, privateKey: privateKey, + viewOnlyData: viewOnlyData, ); if (wallet is MoneroWallet /*|| wallet is WowneroWallet doesn't work.*/) { @@ -503,7 +518,7 @@ abstract class SWB { Future? restoringFuture; - if (!(wallet is CwBasedInterface || wallet is EpiccashWallet)) { + if (!(wallet is LibMoneroWallet || wallet is EpiccashWallet)) { if (wallet is BitcoinFrostWallet) { restoringFuture = wallet.recover( isRescan: false, @@ -700,7 +715,7 @@ abstract class SWB { StackRestoringUIState? uiState, SecureStorageInterface secureStorageInterface, ) async { - if (!Platform.isLinux) await Wakelock.enable(); + if (!Platform.isLinux) await WakelockPlus.enable(); Logging.instance.log( "SWB creating temp backup", @@ -914,7 +929,7 @@ abstract class SWB { await status; } - if (!Platform.isLinux) await Wakelock.disable(); + if (!Platform.isLinux) await WakelockPlus.disable(); // check if cancel was requested and restore previous state if (_checkShouldCancel( preRestoreState, diff --git a/lib/pages/settings_views/sub_widgets/view_only_wallet_data_widget.dart b/lib/pages/settings_views/sub_widgets/view_only_wallet_data_widget.dart new file mode 100644 index 000000000..265986087 --- /dev/null +++ b/lib/pages/settings_views/sub_widgets/view_only_wallet_data_widget.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; + +import '../../../models/keys/view_only_wallet_data.dart'; +import '../../../utilities/util.dart'; +import '../../../widgets/custom_buttons/simple_copy_button.dart'; +import '../../../widgets/detail_item.dart'; +import '../../wallet_view/transaction_views/transaction_details_view.dart'; + +class ViewOnlyWalletDataWidget extends StatelessWidget { + const ViewOnlyWalletDataWidget({ + super.key, + required this.data, + }); + + final ViewOnlyWalletData data; + + @override + Widget build(BuildContext context) { + return switch (data) { + final CryptonoteViewOnlyWalletData e => Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + DetailItem( + title: "Address", + detail: e.address, + button: Util.isDesktop + ? IconCopyButton( + data: e.address, + ) + : SimpleCopyButton( + data: e.address, + ), + ), + const SizedBox( + height: 16, + ), + DetailItem( + title: "Private view key", + detail: e.privateViewKey, + button: Util.isDesktop + ? IconCopyButton( + data: e.privateViewKey, + ) + : SimpleCopyButton( + data: e.privateViewKey, + ), + ), + ], + ), + final AddressViewOnlyWalletData e => Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + DetailItem( + title: "Address", + detail: e.address, + button: Util.isDesktop + ? IconCopyButton( + data: e.address, + ) + : SimpleCopyButton( + data: e.address, + ), + ), + ], + ), + final ExtendedKeysViewOnlyWalletData e => Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ...e.xPubs.map( + (xPub) => DetailItem( + title: xPub.path, + detail: xPub.encoded, + button: Util.isDesktop + ? IconCopyButton( + data: xPub.encoded, + ) + : SimpleCopyButton( + data: xPub.encoded, + ), + ), + ), + ], + ), + }; + } +} diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart index 95538ed10..75b8ca87b 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart @@ -17,6 +17,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../../app_config.dart'; import '../../../../models/keys/cw_key_data.dart'; import '../../../../models/keys/key_data_interface.dart'; +import '../../../../models/keys/view_only_wallet_data.dart'; import '../../../../models/keys/xpriv_data.dart'; import '../../../../notifications/show_flush_bar.dart'; import '../../../../themes/stack_colors.dart'; @@ -39,6 +40,7 @@ import '../../../../widgets/rounded_white_container.dart'; import '../../../../widgets/stack_dialog.dart'; import '../../../add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart'; import '../../../wallet_view/transaction_views/transaction_details_view.dart'; +import '../../sub_widgets/view_only_wallet_data_widget.dart'; import 'cn_wallet_keys.dart'; import 'wallet_xprivs.dart'; @@ -87,9 +89,10 @@ class WalletBackupView extends ConsumerWidget { Padding( padding: const EdgeInsets.all(10), child: CustomTextButton( - text: switch (keyData.runtimeType) { - const (XPrivData) => "xpriv(s)", - const (CWKeyData) => "keys", + text: switch (keyData) { + final XPrivData _ => "xpriv(s)", + final CWKeyData _ => "keys", + final ViewOnlyWalletData _ => "keys", _ => throw UnimplementedError( "Don't forget to add your KeyDataInterface here! ${keyData.runtimeType}", ), @@ -426,7 +429,7 @@ class _FrostKeys extends StatelessWidget { } } -class MobileKeyDataView extends StatelessWidget { +class MobileKeyDataView extends ConsumerWidget { const MobileKeyDataView({ super.key, required this.walletId, @@ -441,7 +444,7 @@ class MobileKeyDataView extends StatelessWidget { final KeyDataInterface keyData; @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { return Background( child: Scaffold( backgroundColor: Theme.of(context).extension()!.background, @@ -452,9 +455,10 @@ class MobileKeyDataView extends StatelessWidget { }, ), title: Text( - "Wallet ${switch (keyData.runtimeType) { - const (XPrivData) => "xpriv(s)", - const (CWKeyData) => "keys", + "Wallet ${switch (keyData) { + final XPrivData _ => "xpriv(s)", + final CWKeyData _ => "keys", + final ViewOnlyWalletData _ => "keys", _ => throw UnimplementedError( "Don't forget to add your KeyDataInterface here!", ), @@ -474,14 +478,18 @@ class MobileKeyDataView extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Expanded( - child: switch (keyData.runtimeType) { - const (XPrivData) => WalletXPrivs( + child: switch (keyData) { + final XPrivData e => WalletXPrivs( walletId: walletId, - xprivData: keyData as XPrivData, + xprivData: e, ), - const (CWKeyData) => CNWalletKeys( + final CWKeyData e => CNWalletKeys( walletId: walletId, - cwKeyData: keyData as CWKeyData, + cwKeyData: e, + ), + final ViewOnlyWalletData e => + ViewOnlyWalletDataWidget( + data: e, ), _ => throw UnimplementedError( "Don't forget to add your KeyDataInterface here!", diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_xprivs.dart b/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_xprivs.dart index 594db33a7..264032961 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_xprivs.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_xprivs.dart @@ -49,7 +49,7 @@ class WalletXPrivsState extends ConsumerState { late String _currentDropDownValue; String _current(String key) => - widget.xprivData.xprivs.firstWhere((e) => e.path == key).xpriv; + widget.xprivData.xprivs.firstWhere((e) => e.path == key).encoded; Future _copy() async { await widget.clipboardInterface.setData( diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart index e15fad011..1be577f1d 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart @@ -16,7 +16,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:tuple/tuple.dart'; -import 'package:wakelock/wakelock.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; import '../../../../providers/providers.dart'; import '../../../../route_generator.dart'; @@ -125,7 +125,7 @@ class _WalletNetworkSettingsViewState } Future _attemptRescan() async { - if (!Platform.isLinux) await Wakelock.enable(); + if (!Platform.isLinux) await WakelockPlus.enable(); try { if (mounted) { @@ -180,7 +180,7 @@ class _WalletNetworkSettingsViewState ); } } catch (e) { - if (!Platform.isLinux) await Wakelock.disable(); + if (!Platform.isLinux) await WakelockPlus.disable(); if (mounted) { // pop rescanning dialog @@ -212,7 +212,7 @@ class _WalletNetworkSettingsViewState } } } finally { - if (!Platform.isLinux) await Wakelock.disable(); + if (!Platform.isLinux) await WakelockPlus.disable(); } } 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 6985bb00c..4948876bd 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 @@ -19,6 +19,7 @@ import '../../../db/hive/db.dart'; import '../../../db/sqlite/firo_cache.dart'; import '../../../models/epicbox_config_model.dart'; import '../../../models/keys/key_data_interface.dart'; +import '../../../models/keys/view_only_wallet_data.dart'; import '../../../notifications/show_flush_bar.dart'; import '../../../providers/global/wallets_provider.dart'; import '../../../providers/ui/transaction_filter_provider.dart'; @@ -36,9 +37,10 @@ import '../../../wallets/crypto_currency/intermediate/frost_currency.dart'; import '../../../wallets/crypto_currency/intermediate/nano_currency.dart'; import '../../../wallets/wallet/impl/bitcoin_frost_wallet.dart'; import '../../../wallets/wallet/impl/epiccash_wallet.dart'; -import '../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; +import '../../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart'; import '../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; +import '../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../widgets/background.dart'; import '../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../widgets/desktop/secondary_button.dart'; @@ -98,8 +100,13 @@ class _WalletSettingsViewState extends ConsumerState { void initState() { walletId = widget.walletId; coin = widget.coin; - xPubEnabled = - ref.read(pWallets).getWallet(walletId) is ExtendedKeysInterface; + + final wallet = ref.read(pWallets).getWallet(walletId); + if (wallet is ViewOnlyOptionInterface && wallet.isViewOnly) { + xPubEnabled = false; + } else { + xPubEnabled = wallet is ExtendedKeysInterface; + } xpub = ""; @@ -165,6 +172,15 @@ class _WalletSettingsViewState extends ConsumerState { @override Widget build(BuildContext context) { debugPrint("BUILD: $runtimeType"); + final wallet = ref.read(pWallets).getWallet(widget.walletId); + + bool canBackup = true; + if (wallet is ViewOnlyOptionInterface && + wallet.isViewOnly && + wallet.viewOnlyType == ViewOnlyWalletType.addressOnly) { + canBackup = false; + } + return Background( child: Scaffold( backgroundColor: Theme.of(context).extension()!.background, @@ -247,106 +263,155 @@ class _WalletSettingsViewState extends ConsumerState { ); }, ), - const SizedBox( - height: 8, - ), - Consumer( - builder: (_, ref, __) { - return SettingsListButton( - iconAssetName: Assets.svg.lock, - iconSize: 16, - title: "Wallet backup", - onPressed: () async { - final wallet = ref - .read(pWallets) - .getWallet(widget.walletId); + if (canBackup) + const SizedBox( + height: 8, + ), + if (canBackup) + Consumer( + builder: (_, ref, __) { + return SettingsListButton( + iconAssetName: Assets.svg.lock, + iconSize: 16, + title: "Wallet backup", + onPressed: () async { + // TODO: [prio=med] take wallets that don't have a mnemonic into account - // TODO: [prio=med] take wallets that don't have a mnemonic into account - - List? mnemonic; - ({ - String myName, - String config, - String keys, + List? mnemonic; ({ + String myName, String config, - String keys - })? prevGen, - })? frostWalletData; - if (wallet is BitcoinFrostWallet) { - final futures = [ - wallet.getSerializedKeys(), - wallet.getMultisigConfig(), - wallet.getSerializedKeysPrevGen(), - wallet.getMultisigConfigPrevGen(), - ]; + String keys, + ({ + String config, + String keys + })? prevGen, + })? frostWalletData; + if (wallet is BitcoinFrostWallet) { + final futures = [ + wallet.getSerializedKeys(), + wallet.getMultisigConfig(), + wallet.getSerializedKeysPrevGen(), + wallet.getMultisigConfigPrevGen(), + ]; - final results = - await Future.wait(futures); + final results = + await Future.wait(futures); - if (results.length == 4) { - frostWalletData = ( - myName: wallet.frostInfo.myName, - config: results[1]!, - keys: results[0]!, - prevGen: results[2] == null || - results[3] == null - ? null - : ( - config: results[3]!, - keys: results[2]!, - ), - ); + if (results.length == 4) { + frostWalletData = ( + myName: wallet.frostInfo.myName, + config: results[1]!, + keys: results[0]!, + prevGen: results[2] == null || + results[3] == null + ? null + : ( + config: results[3]!, + keys: results[2]!, + ), + ); + } + } else { + if (wallet is MnemonicInterface) { + if (wallet + is ViewOnlyOptionInterface && + !(wallet + as ViewOnlyOptionInterface) + .isViewOnly) { + mnemonic = await wallet + .getMnemonicAsWords(); + } + } } - } else if (wallet - is MnemonicInterface) { - mnemonic = - await wallet.getMnemonicAsWords(); - } - KeyDataInterface? keyData; - if (wallet is ExtendedKeysInterface) { - keyData = await wallet.getXPrivs(); - } else if (wallet is CwBasedInterface) { - keyData = await wallet.getKeys(); - } + KeyDataInterface? keyData; + if (wallet + is ViewOnlyOptionInterface && + wallet.isViewOnly) { + keyData = await wallet + .getViewOnlyWalletData(); + } else if (wallet + is ExtendedKeysInterface) { + keyData = await wallet.getXPrivs(); + } else if (wallet + is LibMoneroWallet) { + keyData = await wallet.getKeys(); + } - if (context.mounted) { - await Navigator.push( - context, - RouteGenerator.getRoute( - shouldUseMaterialRoute: - RouteGenerator - .useMaterialPageRoute, - builder: (_) => LockscreenView( - routeOnSuccessArguments: ( - walletId: walletId, - mnemonic: mnemonic ?? [], - frostWalletData: - frostWalletData, - keyData: keyData, + if (context.mounted) { + if (keyData != null && + wallet + is ViewOnlyOptionInterface && + wallet.isViewOnly) { + await Navigator.push( + context, + RouteGenerator.getRoute( + shouldUseMaterialRoute: + RouteGenerator + .useMaterialPageRoute, + builder: (_) => + LockscreenView( + routeOnSuccessArguments: ( + walletId: walletId, + keyData: keyData, + ), + showBackButton: true, + routeOnSuccess: + MobileKeyDataView + .routeName, + biometricsCancelButtonString: + "CANCEL", + biometricsLocalizedReason: + "Authenticate to view recovery data", + biometricsAuthenticationTitle: + "View recovery data", + ), + settings: const RouteSettings( + name: + "/viewRecoveryDataLockscreen", + ), ), - showBackButton: true, - routeOnSuccess: - WalletBackupView.routeName, - biometricsCancelButtonString: - "CANCEL", - biometricsLocalizedReason: - "Authenticate to view recovery phrase", - biometricsAuthenticationTitle: - "View recovery phrase", - ), - settings: const RouteSettings( - name: - "/viewRecoverPhraseLockscreen", - ), - ), - ); - } - }, - ); - }, - ), + ); + } else { + await Navigator.push( + context, + RouteGenerator.getRoute( + shouldUseMaterialRoute: + RouteGenerator + .useMaterialPageRoute, + builder: (_) => + LockscreenView( + routeOnSuccessArguments: ( + walletId: walletId, + mnemonic: mnemonic ?? [], + frostWalletData: + frostWalletData, + keyData: keyData, + ), + showBackButton: true, + routeOnSuccess: + WalletBackupView + .routeName, + biometricsCancelButtonString: + "CANCEL", + biometricsLocalizedReason: + "Authenticate to view recovery phrase", + biometricsAuthenticationTitle: + "View recovery phrase", + ), + settings: const RouteSettings( + name: + "/viewRecoverPhraseLockscreen", + ), + ), + ); + } + } + }, + ); + }, + ), const SizedBox( height: 8, ), diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_view_only_wallet_keys_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_view_only_wallet_keys_view.dart new file mode 100644 index 000000000..d2d2bef2a --- /dev/null +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_view_only_wallet_keys_view.dart @@ -0,0 +1,177 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import '../../../../app_config.dart'; +import '../../../../models/keys/view_only_wallet_data.dart'; +import '../../../../pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart'; +import '../../../../providers/global/secure_store_provider.dart'; +import '../../../../providers/global/wallets_provider.dart'; +import '../../../../route_generator.dart'; +import '../../../../themes/stack_colors.dart'; +import '../../../../utilities/text_styles.dart'; +import '../../../../utilities/util.dart'; +import '../../../../wallets/isar/providers/wallet_info_provider.dart'; +import '../../../../widgets/conditional_parent.dart'; +import '../../../../widgets/custom_buttons/app_bar_icon_button.dart'; +import '../../../../widgets/desktop/primary_button.dart'; +import '../../../../widgets/rounded_white_container.dart'; +import '../../../../widgets/stack_dialog.dart'; +import '../../../home_view/home_view.dart'; +import '../../sub_widgets/view_only_wallet_data_widget.dart'; + +class DeleteViewOnlyWalletKeysView extends ConsumerStatefulWidget { + const DeleteViewOnlyWalletKeysView({ + super.key, + required this.walletId, + required this.data, + }); + + static const routeName = "/deleteWalletViewOnlyData"; + + final String walletId; + final ViewOnlyWalletData data; + + @override + ConsumerState createState() => + _DeleteViewOnlyWalletKeysViewState(); +} + +class _DeleteViewOnlyWalletKeysViewState + extends ConsumerState { + bool _lock = false; + void _continuePressed() async { + if (_lock) { + return; + } + _lock = true; + try { + if (Util.isDesktop) { + await Navigator.of(context).push( + RouteGenerator.getRoute( + builder: (context) { + return ConfirmDelete( + walletId: widget.walletId, + ); + }, + settings: const RouteSettings( + name: "/desktopConfirmDelete", + ), + ), + ); + } else { + await showDialog( + barrierDismissible: true, + context: context, + builder: (_) => StackDialog( + title: "Thanks! Your wallet will be deleted.", + leftButton: TextButton( + style: Theme.of(context) + .extension()! + .getSecondaryEnabledButtonStyle(context), + onPressed: () { + Navigator.pop(context); + }, + child: Text( + "Cancel", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension()! + .accentColorDark, + ), + ), + ), + rightButton: TextButton( + style: Theme.of(context) + .extension()! + .getPrimaryEnabledButtonStyle(context), + onPressed: () async { + await ref.read(pWallets).deleteWallet( + ref.read(pWalletInfo(widget.walletId)), + ref.read(secureStoreProvider), + ); + + if (mounted) { + Navigator.of(context).popUntil( + ModalRoute.withName(HomeView.routeName), + ); + } + }, + child: Text( + "Ok", + style: STextStyles.button(context), + ), + ), + ), + ); + } + } finally { + _lock = false; + } + } + + @override + Widget build(BuildContext context) { + return ConditionalParent( + condition: !Util.isDesktop, + builder: (child) => Scaffold( + backgroundColor: Theme.of(context).extension()!.background, + appBar: AppBar( + leading: AppBarBackButton( + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ), + body: SafeArea( + child: LayoutBuilder( + builder: (context, cons) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints(minHeight: cons.maxHeight), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(16), + child: child, + ), + ), + ), + ); + }, + ), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + RoundedWhiteContainer( + child: Text( + "Please write down your backup data. Keep it safe and " + "never share it with anyone. " + "Your backup data is the only way you can access your " + "wallet if you forget your PIN, lose your phone, etc." + "\n\n" + "${AppConfig.appName} does not keep nor is able to restore " + "your backup data. " + "Only you have access to your wallet.", + style: STextStyles.label(context), + ), + ), + const SizedBox( + height: 24, + ), + ViewOnlyWalletDataWidget( + data: widget.data, + ), + if (!Util.isDesktop) const Spacer(), + const SizedBox( + height: 16, + ), + PrimaryButton( + label: "Continue", + onPressed: _continuePressed, + ), + ], + ), + ); + } +} diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart index f418ed230..16c48cbb6 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart @@ -14,11 +14,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; + import '../../../../app_config.dart'; import '../../../../notifications/show_flush_bar.dart'; -import '../../../add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart'; -import '../../../home_view/home_view.dart'; -import '../../../wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart'; import '../../../../providers/global/secure_store_provider.dart'; import '../../../../providers/global/wallets_provider.dart'; import '../../../../themes/stack_colors.dart'; @@ -35,6 +33,9 @@ import '../../../../widgets/desktop/primary_button.dart'; import '../../../../widgets/detail_item.dart'; import '../../../../widgets/rounded_white_container.dart'; import '../../../../widgets/stack_dialog.dart'; +import '../../../add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart'; +import '../../../home_view/home_view.dart'; +import '../../../wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart'; class DeleteWalletRecoveryPhraseView extends ConsumerStatefulWidget { const DeleteWalletRecoveryPhraseView({ @@ -69,7 +70,6 @@ class _DeleteWalletRecoveryPhraseViewState late ClipboardInterface _clipboardInterface; bool _lock = false; - void _continuePressed() { if (_lock) { return; diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart index afb5137b4..39a723d66 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart @@ -12,14 +12,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../../app_config.dart'; +import '../../../../models/keys/view_only_wallet_data.dart'; import '../../../../providers/providers.dart'; import '../../../../themes/stack_colors.dart'; import '../../../../utilities/text_styles.dart'; import '../../../../wallets/wallet/impl/bitcoin_frost_wallet.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; +import '../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../../widgets/background.dart'; import '../../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../../widgets/rounded_container.dart'; +import 'delete_view_only_wallet_keys_view.dart'; import 'delete_wallet_recovery_phrase_view.dart'; class DeleteWalletWarningView extends ConsumerWidget { @@ -118,6 +121,7 @@ class DeleteWalletWarningView extends ConsumerWidget { String keys, ({String config, String keys})? prevGen, })? frostWalletData; + ViewOnlyWalletData? viewOnlyData; if (wallet is BitcoinFrostWallet) { final futures = [ @@ -142,18 +146,33 @@ class DeleteWalletWarningView extends ConsumerWidget { ), ); } - } else if (wallet is MnemonicInterface) { - mnemonic = await wallet.getMnemonicAsWords(); + } else { + if (wallet is ViewOnlyOptionInterface && + wallet.isViewOnly) { + viewOnlyData = await wallet.getViewOnlyWalletData(); + } else if (wallet is MnemonicInterface) { + mnemonic = await wallet.getMnemonicAsWords(); + } } if (context.mounted) { - await Navigator.of(context).pushNamed( - DeleteWalletRecoveryPhraseView.routeName, - arguments: ( - walletId: walletId, - mnemonicWords: mnemonic ?? [], - frostWalletData: frostWalletData, - ), - ); + if (viewOnlyData != null) { + await Navigator.of(context).pushNamed( + DeleteViewOnlyWalletKeysView.routeName, + arguments: ( + walletId: walletId, + data: viewOnlyData, + ), + ); + } else { + await Navigator.of(context).pushNamed( + DeleteWalletRecoveryPhraseView.routeName, + arguments: ( + walletId: walletId, + mnemonicWords: mnemonic ?? [], + frostWalletData: frostWalletData, + ), + ); + } } }, child: Text( diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart index e8dc5138e..bf41d6261 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart @@ -11,6 +11,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../../../models/keys/view_only_wallet_data.dart'; import '../../../../providers/db/main_db_provider.dart'; import '../../../../providers/providers.dart'; import '../../../../route_generator.dart'; @@ -23,6 +24,7 @@ import '../../../../wallets/wallet/wallet_mixin_interfaces/lelantus_interface.da import '../../../../wallets/wallet/wallet_mixin_interfaces/multi_address_interface.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/rbf_interface.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/spark_interface.dart'; +import '../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../../widgets/background.dart'; import '../../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../../widgets/custom_buttons/draggable_switch_button.dart'; @@ -133,6 +135,12 @@ class _WalletSettingsWalletSettingsViewState @override Widget build(BuildContext context) { + final wallet = ref.watch(pWallets).getWallet(widget.walletId); + + final isViewOnlyNoAddressGen = wallet is ViewOnlyOptionInterface && + wallet.isViewOnly && + wallet.viewOnlyType == ViewOnlyWalletType.addressOnly; + return Background( child: Scaffold( backgroundColor: Theme.of(context).extension()!.background, @@ -189,13 +197,11 @@ class _WalletSettingsWalletSettingsViewState ), ), ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is RbfInterface) + if (wallet is RbfInterface) const SizedBox( height: 8, ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is RbfInterface) + if (wallet is RbfInterface) RoundedWhiteContainer( padding: const EdgeInsets.all(0), child: RawMaterialButton( @@ -227,13 +233,11 @@ class _WalletSettingsWalletSettingsViewState ), ), ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is MultiAddressInterface) + if (wallet is MultiAddressInterface && !isViewOnlyNoAddressGen) const SizedBox( height: 8, ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is MultiAddressInterface) + if (wallet is MultiAddressInterface && !isViewOnlyNoAddressGen) RoundedWhiteContainer( padding: const EdgeInsets.all(0), child: RawMaterialButton( @@ -278,13 +282,11 @@ class _WalletSettingsWalletSettingsViewState ), ), ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is LelantusInterface) + if (wallet is LelantusInterface && !wallet.isViewOnly) const SizedBox( height: 8, ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is LelantusInterface) + if (wallet is LelantusInterface && !wallet.isViewOnly) RoundedWhiteContainer( padding: const EdgeInsets.all(0), child: RawMaterialButton( @@ -316,13 +318,11 @@ class _WalletSettingsWalletSettingsViewState ), ), ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is SparkInterface) + if (wallet is SparkInterface && !wallet.isViewOnly) const SizedBox( height: 8, ), - if (ref.watch(pWallets).getWallet(widget.walletId) - is SparkInterface) + if (wallet is SparkInterface && !wallet.isViewOnly) RoundedWhiteContainer( padding: const EdgeInsets.all(0), child: RawMaterialButton( @@ -369,7 +369,7 @@ class _WalletSettingsWalletSettingsViewState materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, padding: const EdgeInsets.all(0), onPressed: () { - showDialog( + showDialog( barrierDismissible: true, context: context, builder: (_) => StackDialog( diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart index 09200fb1b..2eddd3078 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/xpub_view.dart @@ -57,7 +57,7 @@ class XPubViewState extends ConsumerState { late String _currentDropDownValue; String _current(String key) => - widget.xpubData.xpubs.firstWhere((e) => e.path == key).xpub; + widget.xpubData.xpubs.firstWhere((e) => e.path == key).encoded; Future _copy() async { await widget.clipboardInterface.setData( diff --git a/lib/pages/special/firo_rescan_recovery_error_dialog.dart b/lib/pages/special/firo_rescan_recovery_error_dialog.dart index 92d226d4b..fa59d841a 100644 --- a/lib/pages/special/firo_rescan_recovery_error_dialog.dart +++ b/lib/pages/special/firo_rescan_recovery_error_dialog.dart @@ -12,7 +12,7 @@ import '../../utilities/assets.dart'; import '../../utilities/text_styles.dart'; import '../../utilities/util.dart'; import '../../wallets/isar/providers/wallet_info_provider.dart'; -import '../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; +import '../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; import '../../widgets/background.dart'; @@ -270,7 +270,7 @@ class _FiroRescanRecoveryErrorViewState KeyDataInterface? keyData; if (wallet is ExtendedKeysInterface) { keyData = await wallet.getXPrivs(); - } else if (wallet is CwBasedInterface) { + } else if (wallet is LibMoneroWallet) { keyData = await wallet.getKeys(); } diff --git a/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart b/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart index c9b973f5d..08d9152b8 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart @@ -186,6 +186,21 @@ class WalletSummaryInfo extends ConsumerWidget { ), ), const Spacer(), + if (ref.watch(pWalletInfo(walletId)).isViewOnly) + FittedBox( + fit: BoxFit.scaleDown, + child: SelectableText( + "(View only)", + style: STextStyles.pageTitleH1(context).copyWith( + fontSize: 18, + color: Theme.of(context) + .extension()! + .textFavoriteCard + .withOpacity(0.7), + ), + ), + ), + const Spacer(), FittedBox( fit: BoxFit.scaleDown, child: SelectableText( diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart index e4ad804dc..346a4b730 100644 --- a/lib/pages/wallet_view/wallet_view.dart +++ b/lib/pages/wallet_view/wallet_view.dart @@ -50,11 +50,13 @@ import '../../wallets/crypto_currency/intermediate/frost_currency.dart'; import '../../wallets/isar/providers/wallet_info_provider.dart'; import '../../wallets/wallet/impl/bitcoin_frost_wallet.dart'; import '../../wallets/wallet/impl/firo_wallet.dart'; +import '../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/spark_interface.dart'; +import '../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../widgets/background.dart'; import '../../widgets/conditional_parent.dart'; import '../../widgets/custom_buttons/app_bar_icon_button.dart'; @@ -66,6 +68,7 @@ import '../../widgets/loading_indicator.dart'; import '../../widgets/small_tor_icon.dart'; import '../../widgets/stack_dialog.dart'; import '../../widgets/wallet_navigation_bar/components/icons/buy_nav_icon.dart'; +import '../../widgets/wallet_navigation_bar/components/icons/churn_nav_icon.dart'; import '../../widgets/wallet_navigation_bar/components/icons/coin_control_nav_icon.dart'; import '../../widgets/wallet_navigation_bar/components/icons/exchange_nav_icon.dart'; import '../../widgets/wallet_navigation_bar/components/icons/frost_sign_nav_icon.dart'; @@ -78,6 +81,7 @@ import '../../widgets/wallet_navigation_bar/components/wallet_navigation_bar_ite import '../../widgets/wallet_navigation_bar/wallet_navigation_bar.dart'; import '../buy_view/buy_in_wallet_view.dart'; import '../cashfusion/cashfusion_view.dart'; +import '../churning/churning_view.dart'; import '../coin_control/coin_control_view.dart'; import '../exchange_view/wallet_initiated_exchange_view.dart'; import '../monkey/monkey_view.dart'; @@ -521,6 +525,10 @@ class _WalletViewState extends ConsumerState { final prefs = ref.watch(prefsChangeNotifierProvider); final showExchange = prefs.enableExchange; + final wallet = ref.watch(pWallets).getWallet(walletId); + + final viewOnly = wallet is ViewOnlyOptionInterface && wallet.isViewOnly; + return ConditionalParent( condition: _rescanningOnOpen, builder: (child) { @@ -1023,38 +1031,39 @@ class _WalletViewState extends ConsumerState { icon: const FrostSignNavIcon(), onTap: () => _onFrostSignPressed(context), ), - WalletNavigationBarItemData( - label: "Send", - icon: const SendNavIcon(), - onTap: () { - // not sure what this is supposed to accomplish? - // switch (ref - // .read(walletBalanceToggleStateProvider.state) - // .state) { - // case WalletBalanceToggleState.full: - // ref - // .read(publicPrivateBalanceStateProvider.state) - // .state = "Public"; - // break; - // case WalletBalanceToggleState.available: - // ref - // .read(publicPrivateBalanceStateProvider.state) - // .state = "Private"; - // break; - // } - Navigator.of(context).pushNamed( - ref.read(pWallets).getWallet(walletId) - is BitcoinFrostWallet - ? FrostSendView.routeName - : SendView.routeName, - arguments: ( - walletId: walletId, - coin: coin, - ), - ); - }, - ), - if (Constants.enableExchange && + if (!viewOnly) + WalletNavigationBarItemData( + label: "Send", + icon: const SendNavIcon(), + onTap: () { + // not sure what this is supposed to accomplish? + // switch (ref + // .read(walletBalanceToggleStateProvider.state) + // .state) { + // case WalletBalanceToggleState.full: + // ref + // .read(publicPrivateBalanceStateProvider.state) + // .state = "Public"; + // break; + // case WalletBalanceToggleState.available: + // ref + // .read(publicPrivateBalanceStateProvider.state) + // .state = "Private"; + // break; + // } + Navigator.of(context).pushNamed( + wallet is BitcoinFrostWallet + ? FrostSendView.routeName + : SendView.routeName, + arguments: ( + walletId: walletId, + coin: coin, + ), + ); + }, + ), + if (!viewOnly && + Constants.enableExchange && ref.watch(pWalletCoin(walletId)) is! FrostCurrency && AppConfig.hasFeature(AppFeature.swap) && showExchange) @@ -1110,12 +1119,7 @@ class _WalletViewState extends ConsumerState { ); }, ), - if (ref.watch( - pWallets.select( - (value) => value.getWallet(widget.walletId) - is CoinControlInterface, - ), - ) && + if (wallet is CoinControlInterface && ref.watch( prefsChangeNotifierProvider.select( (value) => value.enableCoinControl, @@ -1134,12 +1138,7 @@ class _WalletViewState extends ConsumerState { ); }, ), - if (ref.watch( - pWallets.select( - (value) => - value.getWallet(widget.walletId) is PaynymInterface, - ), - )) + if (!viewOnly && wallet is PaynymInterface) WalletNavigationBarItemData( label: "PayNym", icon: const PaynymNavIcon(), @@ -1210,12 +1209,7 @@ class _WalletViewState extends ConsumerState { ); }, ), - if (ref.watch( - pWallets.select( - (value) => value.getWallet(widget.walletId) - is CashFusionInterface, - ), - )) + if (wallet is CashFusionInterface && !viewOnly) WalletNavigationBarItemData( label: "Fusion", icon: const FusionNavIcon(), @@ -1226,6 +1220,17 @@ class _WalletViewState extends ConsumerState { ); }, ), + if (wallet is LibMoneroWallet && !viewOnly) + WalletNavigationBarItemData( + label: "Churn", + icon: const ChurnNavIcon(), + onTap: () { + Navigator.of(context).pushNamed( + ChurningView.routeName, + arguments: walletId, + ); + }, + ), ], ), ], diff --git a/lib/pages/wallets_view/sub_widgets/favorite_card.dart b/lib/pages/wallets_view/sub_widgets/favorite_card.dart index ab91cc759..48d0d1257 100644 --- a/lib/pages/wallets_view/sub_widgets/favorite_card.dart +++ b/lib/pages/wallets_view/sub_widgets/favorite_card.dart @@ -13,7 +13,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import '../../wallet_view/wallet_view.dart'; + import '../../../pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart'; import '../../../providers/providers.dart'; import '../../../themes/coin_icon_provider.dart'; @@ -26,9 +26,10 @@ import '../../../utilities/text_styles.dart'; import '../../../utilities/util.dart'; import '../../../wallets/crypto_currency/coins/firo.dart'; import '../../../wallets/isar/providers/wallet_info_provider.dart'; -import '../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; +import '../../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../../widgets/coin_card.dart'; import '../../../widgets/conditional_parent.dart'; +import '../../wallet_view/wallet_view.dart'; class FavoriteCard extends ConsumerStatefulWidget { const FavoriteCard({ @@ -117,7 +118,7 @@ class _FavoriteCardState extends ConsumerState { final wallet = ref.read(pWallets).getWallet(walletId); final Future loadFuture; - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { loadFuture = wallet.init().then((value) async => await (wallet).open()); } else { diff --git a/lib/pages/wallets_view/sub_widgets/wallet_list_item.dart b/lib/pages/wallets_view/sub_widgets/wallet_list_item.dart index 5602d2419..3ac87eb2e 100644 --- a/lib/pages/wallets_view/sub_widgets/wallet_list_item.dart +++ b/lib/pages/wallets_view/sub_widgets/wallet_list_item.dart @@ -24,7 +24,7 @@ import '../../../utilities/show_loading.dart'; import '../../../utilities/text_styles.dart'; import '../../../utilities/util.dart'; import '../../../wallets/crypto_currency/crypto_currency.dart'; -import '../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; +import '../../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../../widgets/dialogs/tor_warning_dialog.dart'; import '../../../widgets/rounded_white_container.dart'; import '../../wallet_view/wallet_view.dart'; @@ -84,7 +84,7 @@ class WalletListItem extends ConsumerWidget { .wallets .firstWhere((e) => e.info.coin == coin); final Future loadFuture; - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { loadFuture = wallet.init().then((value) async => await (wallet).open()); } else { diff --git a/lib/pages_desktop_specific/addresses/sub_widgets/desktop_address_list.dart b/lib/pages_desktop_specific/addresses/sub_widgets/desktop_address_list.dart index 9ac4fab33..a0a183afe 100644 --- a/lib/pages_desktop_specific/addresses/sub_widgets/desktop_address_list.dart +++ b/lib/pages_desktop_specific/addresses/sub_widgets/desktop_address_list.dart @@ -69,6 +69,19 @@ class _DesktopAddressListState extends ConsumerState { .and() .not() .typeEqualTo(AddressType.nonWallet) + .and() + .group( + (q) => q + .group( + (q2) => q2 + .typeEqualTo(AddressType.frostMS) + .and() + .zSafeFrostEqualTo(true), + ) + .or() + .not() + .typeEqualTo(AddressType.frostMS), + ) .sortByDerivationIndex() .idProperty() .findAllSync(); @@ -118,6 +131,19 @@ class _DesktopAddressListState extends ConsumerState { .and() .not() .typeEqualTo(AddressType.nonWallet) + .and() + .group( + (q) => q + .group( + (q2) => q2 + .typeEqualTo(AddressType.frostMS) + .and() + .zSafeFrostEqualTo(true), + ) + .or() + .not() + .typeEqualTo(AddressType.frostMS), + ) .sortByDerivationIndex() .idProperty() .findAllSync(); diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 09bce3a3b..8eb43d648 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:wakelock/wakelock.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; import '../../../providers/cash_fusion/fusion_progress_ui_state_provider.dart'; import '../../../providers/global/prefs_provider.dart'; @@ -139,7 +139,7 @@ class _FusionDialogViewState extends ConsumerState { message: "Stopping fusion", ); - await Wakelock.disable(); + await WakelockPlus.disable(); return true; } else { @@ -156,7 +156,7 @@ class _FusionDialogViewState extends ConsumerState { @override dispose() { - Wakelock.disable(); + WakelockPlus.disable(); super.dispose(); } @@ -173,7 +173,7 @@ class _FusionDialogViewState extends ConsumerState { .fusionRoundsCompleted; if (!Platform.isLinux) { - Wakelock.enable(); + WakelockPlus.enable(); } return DesktopDialog( diff --git a/lib/pages_desktop_specific/churning/desktop_churning_view.dart b/lib/pages_desktop_specific/churning/desktop_churning_view.dart new file mode 100644 index 000000000..e3a7b0736 --- /dev/null +++ b/lib/pages_desktop_specific/churning/desktop_churning_view.dart @@ -0,0 +1,424 @@ +import 'dart:async'; + +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/svg.dart'; + +import '../../pages/churning/churning_rounds_selection_sheet.dart'; +import '../../providers/churning/churning_service_provider.dart'; +import '../../themes/stack_colors.dart'; +import '../../utilities/assets.dart'; +import '../../utilities/constants.dart'; +import '../../utilities/extensions/extensions.dart'; +import '../../utilities/text_styles.dart'; +import '../../widgets/custom_buttons/app_bar_icon_button.dart'; +import '../../widgets/custom_buttons/checkbox_text_button.dart'; +import '../../widgets/desktop/desktop_app_bar.dart'; +import '../../widgets/desktop/desktop_dialog.dart'; +import '../../widgets/desktop/desktop_dialog_close_button.dart'; +import '../../widgets/desktop/desktop_scaffold.dart'; +import '../../widgets/desktop/primary_button.dart'; +import '../../widgets/rounded_white_container.dart'; +import '../../widgets/stack_text_field.dart'; +import 'sub_widgets/churning_dialog.dart'; + +class DesktopChurningView extends ConsumerStatefulWidget { + const DesktopChurningView({ + super.key, + required this.walletId, + }); + + static const String routeName = "/desktopChurningView"; + + final String walletId; + + @override + ConsumerState createState() => _DesktopChurning(); +} + +class _DesktopChurning extends ConsumerState { + late final TextEditingController churningRoundController; + late final FocusNode churningRoundFocusNode; + + bool _enableStartButton = false; + + ChurnOption _option = ChurnOption.continuous; + + Future _startChurn() async { + final churningService = ref.read(pChurningService(widget.walletId)); + + final int rounds = _option == ChurnOption.continuous + ? 0 + : int.parse(churningRoundController.text); + + churningService.rounds = rounds; + + await showDialog( + context: context, + barrierDismissible: false, + builder: (context) { + return ChurnDialogView( + walletId: widget.walletId, + ); + }, + ); + } + + @override + void initState() { + churningRoundController = TextEditingController(); + + churningRoundFocusNode = FocusNode(); + + final rounds = ref.read(pChurningService(widget.walletId)).rounds; + + _option = rounds == 0 ? ChurnOption.continuous : ChurnOption.custom; + churningRoundController.text = rounds.toString(); + + _enableStartButton = churningRoundController.text.isNotEmpty; + + super.initState(); + } + + @override + void dispose() { + churningRoundController.dispose(); + churningRoundFocusNode.dispose(); + + super.dispose(); + } + + @override + Widget build(BuildContext context) { + debugPrint("BUILD: $runtimeType"); + + return DesktopScaffold( + appBar: DesktopAppBar( + background: Theme.of(context).extension()!.popupBG, + isCompactHeight: true, + useSpacers: false, + leading: Expanded( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + // const SizedBox( + // width: 32, + // ), + AppBarIconButton( + size: 32, + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + shadows: const [], + icon: SvgPicture.asset( + Assets.svg.arrowLeft, + width: 18, + height: 18, + color: Theme.of(context) + .extension()! + .topNavIconPrimary, + ), + onPressed: Navigator.of(context).pop, + ), + const SizedBox( + width: 15, + ), + SvgPicture.asset( + Assets.svg.churn, + width: 32, + height: 32, + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + const SizedBox( + width: 12, + ), + Text( + "Churning", + style: STextStyles.desktopH3(context), + ), + ], + ), + MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () {}, + child: Row( + children: [ + SvgPicture.asset( + Assets.svg.circleQuestion, + color: Theme.of(context) + .extension()! + .radioButtonIconBorder, + ), + const SizedBox( + width: 8, + ), + RichText( + text: TextSpan( + text: "What is churning?", + style: STextStyles.richLink(context).copyWith( + fontSize: 16, + ), + recognizer: TapGestureRecognizer() + ..onTap = () { + showDialog( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return DesktopDialog( + maxWidth: 580, + maxHeight: double.infinity, + child: Padding( + padding: const EdgeInsets.only( + top: 10, + left: 20, + bottom: 20, + right: 10, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text( + "What is churning?", + style: STextStyles.desktopH2( + context, + ), + ), + DesktopDialogCloseButton( + onPressedOverride: () => + Navigator.of(context) + .pop(true), + ), + ], + ), + const SizedBox( + height: 16, + ), + Text( + "Churning in a Monero wallet involves" + " sending Monero to oneself in multiple" + " transactions, which can enhance privacy" + " by making it harder for observers to " + "link your transactions. This process" + " re-mixes the funds within the network," + " helping obscure transaction history. " + "Churning is optional and mainly beneficial" + " in scenarios where maximum privacy is" + " desired or if you received the Monero from" + " a source from which you'd like to disassociate.", + style: + STextStyles.desktopTextMedium( + context, + ).copyWith( + color: Theme.of(context) + .extension()! + .textDark3, + ), + ), + ], + ), + ), + ); + }, + ); + }, + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ), + body: Row( + children: [ + Padding( + padding: const EdgeInsets.all(24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 460, + child: RoundedWhiteContainer( + child: Row( + children: [ + Text( + "Churning helps anonymize your coins by mixing them.", + style: + STextStyles.desktopTextExtraExtraSmall(context), + ), + ], + ), + ), + ), + const SizedBox( + height: 24, + ), + SizedBox( + width: 460, + child: RoundedWhiteContainer( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Configuration", + style: + STextStyles.desktopTextExtraExtraSmall(context), + ), + const SizedBox( + height: 10, + ), + DropdownButtonHideUnderline( + child: DropdownButton2( + value: _option, + items: [ + ...ChurnOption.values.map( + (e) => DropdownMenuItem( + value: e, + child: Text( + e.name.capitalize(), + style: STextStyles.smallMed14(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ), + ), + ), + ), + ], + onChanged: (value) { + if (value is ChurnOption) { + setState(() { + _option = value; + }); + } + }, + isExpanded: true, + iconStyleData: IconStyleData( + icon: SvgPicture.asset( + Assets.svg.chevronDown, + width: 12, + height: 6, + color: Theme.of(context) + .extension()! + .textFieldActiveSearchIconRight, + ), + ), + dropdownStyleData: DropdownStyleData( + offset: const Offset(0, -10), + elevation: 0, + decoration: BoxDecoration( + color: Theme.of(context) + .extension()! + .textFieldActiveBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + ), + menuItemStyleData: const MenuItemStyleData( + padding: EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + ), + ), + ), + if (_option == ChurnOption.custom) + const SizedBox( + height: 10, + ), + if (_option == ChurnOption.custom) + SizedBox( + width: 460, + child: RoundedWhiteContainer( + padding: EdgeInsets.zero, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: false, + enableSuggestions: false, + controller: churningRoundController, + focusNode: churningRoundFocusNode, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + onChanged: (value) { + setState(() { + _enableStartButton = value.isNotEmpty; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Number of churns", + churningRoundFocusNode, + context, + desktopMed: true, + ).copyWith( + labelText: "Enter number of churns..", + ), + ), + ), + ], + ), + ), + ), + const SizedBox( + height: 20, + ), + CheckboxTextButton( + label: "Pause on errors", + initialValue: !ref + .read(pChurningService(widget.walletId)) + .ignoreErrors, + onChanged: (value) { + ref + .read(pChurningService(widget.walletId)) + .ignoreErrors = !value; + }, + ), + const SizedBox( + height: 20, + ), + PrimaryButton( + label: "Start", + enabled: _enableStartButton, + buttonHeight: ButtonHeight.l, + onPressed: _startChurn, + ), + ], + ), + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages_desktop_specific/churning/sub_widgets/churning_dialog.dart b/lib/pages_desktop_specific/churning/sub_widgets/churning_dialog.dart new file mode 100644 index 000000000..44615e244 --- /dev/null +++ b/lib/pages_desktop_specific/churning/sub_widgets/churning_dialog.dart @@ -0,0 +1,323 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; + +import '../../../pages/churning/churn_error_dialog.dart'; +import '../../../providers/churning/churning_service_provider.dart'; +import '../../../themes/stack_colors.dart'; +import '../../../utilities/assets.dart'; +import '../../../utilities/text_styles.dart'; +import '../../../widgets/churning/churn_progress_item.dart'; +import '../../../widgets/desktop/desktop_dialog.dart'; +import '../../../widgets/desktop/desktop_dialog_close_button.dart'; +import '../../../widgets/desktop/primary_button.dart'; +import '../../../widgets/desktop/secondary_button.dart'; +import '../../../widgets/rounded_container.dart'; +import '../../../widgets/rounded_white_container.dart'; + +class ChurnDialogView extends ConsumerStatefulWidget { + const ChurnDialogView({ + super.key, + required this.walletId, + }); + + final String walletId; + + @override + ConsumerState createState() => _ChurnDialogViewState(); +} + +class _ChurnDialogViewState extends ConsumerState { + Future _requestAndProcessCancel() async { + final bool? shouldCancel = await showDialog( + context: context, + barrierDismissible: false, + builder: (_) => DesktopDialog( + maxWidth: 580, + maxHeight: double.infinity, + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 0, + top: 0, + bottom: 32, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Cancel churning?", + style: STextStyles.desktopH3(context), + ), + DesktopDialogCloseButton( + onPressedOverride: () => Navigator.of(context).pop(false), + ), + ], + ), + Padding( + padding: const EdgeInsets.only( + left: 0, + right: 32, + top: 0, + bottom: 0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Do you really want to cancel the churning process?", + style: STextStyles.smallMed14(context), + textAlign: TextAlign.left, + ), + const SizedBox(height: 40), + Row( + children: [ + Expanded( + child: SecondaryButton( + label: "No", + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + ), + const SizedBox(width: 16), + Expanded( + child: PrimaryButton( + label: "Yes", + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + ); + + if (shouldCancel == true && mounted) { + ref.read(pChurningService(widget.walletId)).stopChurning(); + + await WakelockPlus.disable(); + + return true; + } else { + return false; + } + } + + @override + void initState() { + super.initState(); + + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) ref.read(pChurningService(widget.walletId)).churn(); + }); + } + + @override + dispose() { + WakelockPlus.disable(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final bool _succeeded = ref.watch( + pChurningService(widget.walletId).select((s) => s.done), + ); + + final int _roundsCompleted = ref.watch( + pChurningService(widget.walletId).select((s) => s.roundsCompleted), + ); + + if (!Platform.isLinux) { + WakelockPlus.enable(); + } + + ref.listen( + pChurningService(widget.walletId).select((s) => s.lastSeenError), + (p, n) { + if (!ref.read(pChurningService(widget.walletId)).ignoreErrors && + n != null) { + if (context.mounted) { + showDialog( + context: context, + builder: (context) => ChurnErrorDialog( + error: n.toString(), + walletId: widget.walletId, + ), + ); + } + } + }, + ); + + return DesktopDialog( + maxHeight: 600, + child: SingleChildScrollView( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 32), + child: Text( + "Churn progress", + style: STextStyles.desktopH2(context), + ), + ), + DesktopDialogCloseButton( + onPressedOverride: () async { + if (_succeeded) { + Navigator.of(context).pop(); + } else { + if (await _requestAndProcessCancel()) { + if (context.mounted) { + Navigator.of(context).pop(); + } + } + } + }, + ), + ], + ), + Padding( + padding: const EdgeInsets.only( + top: 20, + left: 32, + right: 32, + bottom: 32, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _roundsCompleted > 0 + ? RoundedWhiteContainer( + child: Text( + "Churn rounds completed: $_roundsCompleted", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + textAlign: TextAlign.center, + ), + ) + : RoundedContainer( + color: Theme.of(context) + .extension()! + .snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension()! + .snackBarTextError, + ), + textAlign: TextAlign.center, + ), + ), + const SizedBox( + height: 20, + ), + ProgressItem( + iconAsset: Assets.svg.alertCircle, + label: "Waiting for balance to unlock ${ref.watch( + pChurningService(widget.walletId) + .select((s) => s.confirmsInfo), + ) ?? ""}", + status: ref.watch( + pChurningService(widget.walletId) + .select((s) => s.waitingForUnlockedBalance), + ), + ), + const SizedBox( + height: 12, + ), + ProgressItem( + iconAsset: Assets.svg.churn, + label: "Creating churn transaction", + status: ref.watch( + pChurningService(widget.walletId) + .select((s) => s.makingChurnTransaction), + ), + ), + const SizedBox( + height: 12, + ), + ProgressItem( + iconAsset: Assets.svg.checkCircle, + label: "Complete", + status: ref.watch( + pChurningService(widget.walletId) + .select((s) => s.completedStatus), + ), + ), + const SizedBox( + height: 12, + ), + Row( + children: [ + if (_succeeded) + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Churn again", + onPressed: ref + .read(pChurningService(widget.walletId)) + .churn, + ), + ), + if (_succeeded) + const SizedBox( + width: 16, + ), + if (!_succeeded) const Spacer(), + if (!_succeeded) + const SizedBox( + width: 16, + ), + Expanded( + child: SecondaryButton( + buttonHeight: ButtonHeight.m, + enabled: true, + label: _succeeded ? "Done" : "Cancel", + onPressed: () async { + if (_succeeded) { + Navigator.of(context).pop(); + } else { + if (await _requestAndProcessCancel()) { + if (context.mounted) { + Navigator.of(context).pop(); + } + } + } + }, + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages_desktop_specific/my_stack_view/coin_wallets_table.dart b/lib/pages_desktop_specific/my_stack_view/coin_wallets_table.dart index e440af8fe..7771c33f5 100644 --- a/lib/pages_desktop_specific/my_stack_view/coin_wallets_table.dart +++ b/lib/pages_desktop_specific/my_stack_view/coin_wallets_table.dart @@ -10,7 +10,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'wallet_view/desktop_wallet_view.dart'; + import '../../providers/global/active_wallet_provider.dart'; import '../../providers/global/wallets_provider.dart'; import '../../themes/stack_colors.dart'; @@ -18,9 +18,10 @@ import '../../utilities/constants.dart'; import '../../utilities/show_loading.dart'; import '../../utilities/util.dart'; import '../../wallets/crypto_currency/crypto_currency.dart'; -import '../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; +import '../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../widgets/rounded_container.dart'; import '../../widgets/wallet_info_row/wallet_info_row.dart'; +import 'wallet_view/desktop_wallet_view.dart'; class CoinWalletsTable extends ConsumerWidget { const CoinWalletsTable({ @@ -81,7 +82,7 @@ class CoinWalletsTable extends ConsumerWidget { final wallet = ref.read(pWallets).getWallet(walletIds[i]); final Future loadFuture; - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { loadFuture = wallet .init() .then((value) async => await (wallet).open()); diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart index 983f01a42..b30ffb17a 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart @@ -19,15 +19,19 @@ import '../../providers/providers.dart'; import '../../themes/coin_icon_provider.dart'; import '../../themes/stack_colors.dart'; import '../../utilities/amount/amount.dart'; +import '../../utilities/show_loading.dart'; import '../../utilities/text_styles.dart'; +import '../../utilities/util.dart'; import '../../wallets/crypto_currency/crypto_currency.dart'; import '../../wallets/isar/providers/all_wallets_info_provider.dart'; +import '../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../widgets/breathing.dart'; import '../../widgets/conditional_parent.dart'; import '../../widgets/desktop/desktop_dialog.dart'; import '../../widgets/desktop/desktop_dialog_close_button.dart'; import '../../widgets/dialogs/tor_warning_dialog.dart'; import '../../widgets/rounded_white_container.dart'; +import 'wallet_view/desktop_wallet_view.dart'; class WalletSummaryTable extends ConsumerStatefulWidget { const WalletSummaryTable({super.key}); @@ -86,10 +90,7 @@ class DesktopWalletSummaryRow extends ConsumerStatefulWidget { class _DesktopWalletSummaryRowState extends ConsumerState { - bool _hovering = false; - - void _onPressed() async { - // Check if Tor is enabled... + Future _checkTor() async { if (ref.read(prefsChangeNotifierProvider).useTor) { // ... and if the coin supports Tor. if (!widget.coin.torSupport) { @@ -106,44 +107,97 @@ class _DesktopWalletSummaryRowState } } } + } - showDialog( - context: context, - builder: (_) => DesktopDialog( - maxHeight: 600, - maxWidth: 700, - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + bool get goStraightIntoWallet => + Util.isDesktop && widget.walletCount == 1 && !widget.coin.hasTokenSupport; + + bool _buttonLock = false; + Future _onPressedSingleWalletDesktop() async { + if (_buttonLock) return; + _buttonLock = true; + try { + await _checkTor(); + + if (mounted) { + final wallet = ref.read(pWallets).wallets.firstWhere( + (e) => e.cryptoCurrency.identifier == widget.coin.identifier); + + final Future loadFuture; + if (wallet is LibMoneroWallet) { + loadFuture = + wallet.init().then((value) async => await (wallet).open()); + } else { + loadFuture = wallet.init(); + } + await showLoading( + whileFuture: loadFuture, + context: context, + message: 'Opening ${wallet.info.name}', + rootNavigator: Util.isDesktop, + ); + + if (mounted) { + await Navigator.of(context).pushNamed( + DesktopWalletView.routeName, + arguments: wallet.walletId, + ); + } + } + } finally { + _buttonLock = false; + } + } + + void _onPressed() async { + if (_buttonLock) return; + _buttonLock = true; + try { + // Check if Tor is enabled... + await _checkTor(); + + if (mounted) { + await showDialog( + context: context, + builder: (_) => DesktopDialog( + maxHeight: 600, + maxWidth: 700, + child: Column( children: [ - Padding( - padding: const EdgeInsets.only(left: 32), - child: Text( - "${widget.coin.prettyName} (${widget.coin.ticker}) wallets", - style: STextStyles.desktopH3(context), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 32), + child: Text( + "${widget.coin.prettyName} (${widget.coin.ticker}) wallets", + style: STextStyles.desktopH3(context), + ), + ), + const DesktopDialogCloseButton(), + ], + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + bottom: 32, + ), + child: WalletsOverview( + coin: widget.coin, + navigatorState: Navigator.of(context), + ), ), ), - const DesktopDialogCloseButton(), ], ), - Expanded( - child: Padding( - padding: const EdgeInsets.only( - left: 32, - right: 32, - bottom: 32, - ), - child: WalletsOverview( - coin: widget.coin, - navigatorState: Navigator.of(context), - ), - ), - ), - ], - ), - ), - ); + ), + ); + } + } finally { + _buttonLock = false; + } } @override @@ -152,7 +206,8 @@ class _DesktopWalletSummaryRowState child: RoundedWhiteContainer( padding: const EdgeInsets.all(20), hoverColor: Colors.transparent, - onPressed: _onPressed, + onPressed: + goStraightIntoWallet ? _onPressedSingleWalletDesktop : _onPressed, child: Row( children: [ Expanded( diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index 0105c0006..9893a6cae 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -21,6 +21,7 @@ import 'package:isar/isar.dart'; import '../../../db/sqlite/firo_cache.dart'; import '../../../models/isar/models/blockchain_data/v2/transaction_v2.dart'; import '../../../models/isar/models/isar_models.dart'; +import '../../../models/keys/view_only_wallet_data.dart'; import '../../../pages/add_wallet_views/add_token_view/edit_wallet_tokens_view.dart'; import '../../../pages/token_view/my_tokens_view.dart'; import '../../../pages/wallet_view/sub_widgets/transactions_list.dart'; @@ -44,6 +45,7 @@ import '../../../utilities/wallet_tools.dart'; import '../../../wallets/isar/providers/wallet_info_provider.dart'; import '../../../wallets/wallet/impl/banano_wallet.dart'; import '../../../wallets/wallet/impl/firo_wallet.dart'; +import '../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../widgets/custom_buttons/blue_text_button.dart'; import '../../../widgets/desktop/desktop_app_bar.dart'; @@ -168,6 +170,11 @@ class _DesktopWalletViewState extends ConsumerState { final monke = wallet is BananoWallet ? wallet.getMonkeyImageBytes() : null; + // if the view only wallet watches a single address there are no keys of any kind + final showKeysButton = !(wallet is ViewOnlyOptionInterface && + wallet.isViewOnly && + wallet.viewOnlyType == ViewOnlyWalletType.addressOnly); + return DesktopScaffold( appBar: DesktopAppBar( background: Theme.of(context).extension()!.popupBG, @@ -216,6 +223,19 @@ class _DesktopWalletViewState extends ConsumerState { ), ), ), + if (ref.watch(pWalletInfo(widget.walletId)).isViewOnly) + const SizedBox( + width: 20, + ), + if (ref.watch(pWalletInfo(widget.walletId)).isViewOnly) + Text( + "(View only)", + style: STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context) + .extension()! + .textFieldActiveSearchIconLeft, + ), + ), if (kDebugMode) const Spacer(), if (kDebugMode) Column( @@ -312,12 +332,14 @@ class _DesktopWalletViewState extends ConsumerState { walletId: widget.walletId, eventBus: eventBus, ), - const SizedBox( - width: 2, - ), - WalletKeysButton( - walletId: widget.walletId, - ), + if (showKeysButton) + const SizedBox( + width: 2, + ), + if (showKeysButton) + WalletKeysButton( + walletId: widget.walletId, + ), const SizedBox( width: 2, ), diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart index 21d4bfbf5..16032b36b 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart @@ -10,18 +10,21 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:tuple/tuple.dart'; + import '../../../../app_config.dart'; -import 'delete_wallet_keys_popup.dart'; +import '../../../../pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_view_only_wallet_keys_view.dart'; import '../../../../providers/global/wallets_provider.dart'; import '../../../../themes/stack_colors.dart'; import '../../../../utilities/text_styles.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; +import '../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../../widgets/desktop/desktop_dialog.dart'; import '../../../../widgets/desktop/desktop_dialog_close_button.dart'; import '../../../../widgets/desktop/primary_button.dart'; import '../../../../widgets/desktop/secondary_button.dart'; import '../../../../widgets/rounded_container.dart'; -import 'package:tuple/tuple.dart'; +import 'delete_wallet_keys_popup.dart'; class DesktopAttentionDeleteWallet extends ConsumerStatefulWidget { const DesktopAttentionDeleteWallet({ @@ -114,6 +117,58 @@ class _DesktopAttentionDeleteWallet onPressed: () async { final wallet = ref.read(pWallets).getWallet(widget.walletId); + + if (wallet is ViewOnlyOptionInterface && + wallet.isViewOnly) { + final data = await wallet.getViewOnlyWalletData(); + if (context.mounted) { + await Navigator.of(context).push( + MaterialPageRoute( + builder: (builder) => DesktopDialog( + maxWidth: 614, + maxHeight: double.infinity, + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 32, + ), + child: Text( + "Wallet keys", + style: STextStyles.desktopH3( + context, + ), + ), + ), + DesktopDialogCloseButton( + onPressedOverride: () { + Navigator.of( + context, + rootNavigator: true, + ).pop(); + }, + ), + ], + ), + Padding( + padding: const EdgeInsets.all(32), + child: DeleteViewOnlyWalletKeysView( + walletId: widget.walletId, + data: data, + ), + ), + ], + ), + ), + ), + ); + } + } else + // TODO: [prio=med] handle other types wallet deletion // All wallets currently are mnemonic based if (wallet is MnemonicInterface) { diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart index 3b25f0dad..6326a6474 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart @@ -8,9 +8,9 @@ * */ -import 'package:cw_core/monero_transaction_priority.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; +import 'package:cs_monero/cs_monero.dart' as lib_monero; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; @@ -86,7 +86,7 @@ class _DesktopFeeDropDownState extends ConsumerState { if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.fast.raw!, + lib_monero.TransactionPriority.high.value, ); ref.read(feeSheetSessionCacheProvider).fast[amount] = fee; } else if (coin is Firo) { @@ -136,7 +136,7 @@ class _DesktopFeeDropDownState extends ConsumerState { if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.regular.raw!, + lib_monero.TransactionPriority.medium.value, ); ref.read(feeSheetSessionCacheProvider).average[amount] = fee; } else if (coin is Firo) { @@ -186,7 +186,7 @@ class _DesktopFeeDropDownState extends ConsumerState { if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.slow.raw!, + lib_monero.TransactionPriority.normal.value, ); ref.read(feeSheetSessionCacheProvider).slow[amount] = fee; } else if (coin is Firo) { diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart index a96a01b8f..87f62a6f4 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart @@ -19,6 +19,7 @@ import 'package:isar/isar.dart'; import 'package:tuple/tuple.dart'; import '../../../../models/isar/models/isar_models.dart'; +import '../../../../models/keys/view_only_wallet_data.dart'; import '../../../../notifications/show_flush_bar.dart'; import '../../../../pages/receive_view/generate_receiving_uri_qr_code_view.dart'; import '../../../../providers/db/main_db_provider.dart'; @@ -40,6 +41,7 @@ import '../../../../wallets/wallet/intermediate/bip39_hd_wallet.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/bcash_interface.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/multi_address_interface.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/spark_interface.dart'; +import '../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../../widgets/conditional_parent.dart'; import '../../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../../widgets/custom_loading_overlay.dart'; @@ -110,9 +112,15 @@ class _DesktopReceiveState extends ConsumerState { address = await wallet.generateNextReceivingAddress( derivePathType: type, ); - await ref.read(mainDBProvider).isar.writeTxn(() async { - await ref.read(mainDBProvider).isar.addresses.put(address!); + final isar = ref.read(mainDBProvider).isar; + await isar.writeTxn(() async { + await isar.addresses.put(address!); }); + final info = ref.read(pWalletInfo(walletId)); + await info.updateReceivingAddress( + newAddress: address.value, + isar: isar, + ); } else { await wallet.generateNewReceivingAddress(); address = null; @@ -172,8 +180,6 @@ class _DesktopReceiveState extends ConsumerState { } } - StreamSubscription? _streamSub; - @override void initState() { walletId = widget.walletId; @@ -181,10 +187,15 @@ class _DesktopReceiveState extends ConsumerState { clipboard = widget.clipboard; final wallet = ref.read(pWallets).getWallet(walletId); supportsSpark = ref.read(pWallets).getWallet(walletId) is SparkInterface; - showMultiType = supportsSpark || - (wallet is! BCashInterface && - wallet is Bip39HDWallet && - wallet.supportedAddressTypes.length > 1); + + if (wallet is ViewOnlyOptionInterface && wallet.isViewOnly) { + showMultiType = false; + } else { + showMultiType = supportsSpark || + (wallet is! BCashInterface && + wallet is Bip39HDWallet && + wallet.supportedAddressTypes.length > 1); + } _walletAddressTypes.add(wallet.info.mainAddressType); @@ -238,7 +249,9 @@ class _DesktopReceiveState extends ConsumerState { @override void dispose() { - _streamSub?.cancel(); + for (final subscription in _addressSubMap.values) { + subscription.cancel(); + } super.dispose(); } @@ -253,6 +266,18 @@ class _DesktopReceiveState extends ConsumerState { address = ref.watch(pWalletReceivingAddress(walletId)); } + final wallet = + ref.watch(pWallets.select((value) => value.getWallet(walletId))); + + final bool canGen; + if (wallet is ViewOnlyOptionInterface && + wallet.isViewOnly && + wallet.viewOnlyType == ViewOnlyWalletType.addressOnly) { + canGen = false; + } else { + canGen = (wallet is MultiAddressInterface || supportsSpark); + } + return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ @@ -424,16 +449,12 @@ class _DesktopReceiveState extends ConsumerState { ), ), - if (ref.watch(pWallets.select((value) => value.getWallet(walletId))) - is MultiAddressInterface || - supportsSpark) + if (canGen) const SizedBox( height: 20, ), - if (ref.watch(pWallets.select((value) => value.getWallet(walletId))) - is MultiAddressInterface || - supportsSpark) + if (canGen) SecondaryButton( buttonHeight: ButtonHeight.l, onPressed: supportsSpark && diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart index ce3ab2b1f..7fb764cfa 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart @@ -10,7 +10,7 @@ import 'dart:async'; -import 'package:cw_core/monero_transaction_priority.dart'; +import 'package:cs_monero/cs_monero.dart' as lib_monero; import 'package:decimal/decimal.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; @@ -145,7 +145,7 @@ class _DesktopSendState extends ConsumerState { Future scanWebcam() async { try { - await showDialog( + await showDialog( context: context, builder: (context) { return QrCodeScannerDialog( @@ -153,16 +153,20 @@ class _DesktopSendState extends ConsumerState { try { _processQrCodeData(qrCodeData); } catch (e, s) { - Logging.instance.log("Error processing QR code data: $e\n$s", - level: LogLevel.Error); + Logging.instance.log( + "Error processing QR code data: $e\n$s", + level: LogLevel.Error, + ); } }, ); }, ); } catch (e, s) { - Logging.instance.log("Error opening QR code scanner dialog: $e\n$s", - level: LogLevel.Error); + Logging.instance.log( + "Error opening QR code scanner dialog: $e\n$s", + level: LogLevel.Error, + ); } } @@ -655,84 +659,15 @@ class _DesktopSendState extends ConsumerState { // return null; // } - Future scanQr() async { - try { - if (FocusScope.of(context).hasFocus) { - FocusScope.of(context).unfocus(); - await Future.delayed(const Duration(milliseconds: 75)); - } - - final qrResult = await scanner.scan(); - - Logging.instance.log( - "qrResult content: ${qrResult.rawContent}", - level: LogLevel.Info, - ); - - final results = AddressUtils.parseUri(qrResult.rawContent); - - Logging.instance.log("qrResult parsed: $results", level: LogLevel.Info); - - if (results.isNotEmpty && results["scheme"] == coin.uriScheme) { - // auto fill address - _address = results["address"] ?? ""; - sendToController.text = _address!; - - // autofill notes field - if (results["message"] != null) { - _note = results["message"]!; - } else if (results["label"] != null) { - _note = results["label"]!; - } - - // autofill amount field - if (results["amount"] != null) { - final amount = Decimal.parse(results["amount"]!).toAmount( - fractionDigits: coin.fractionDigits, - ); - cryptoAmountController.text = ref - .read(pAmountFormatter(coin)) - .format(amount, withUnitName: false); - ref.read(pSendAmount.notifier).state = amount; - } - - setState(() { - _addressToggleFlag = sendToController.text.isNotEmpty; - }); - - // now check for non standard encoded basic address - } else if (ref - .read(pWallets) - .getWallet(walletId) - .cryptoCurrency - .validateAddress(qrResult.rawContent)) { - _address = qrResult.rawContent; - sendToController.text = _address ?? ""; - - _setValidAddressProviders(_address); - setState(() { - _addressToggleFlag = sendToController.text.isNotEmpty; - }); - } - } on PlatformException catch (e, s) { - // here we ignore the exception caused by not giving permission - // to use the camera to scan a qr code - Logging.instance.log( - "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", - level: LogLevel.Warning, - ); - } catch (e, s) { - Logging.instance.log( - "Failed to scan qr code in SendView: $e\n$s", - level: LogLevel.Warning, - ); - } - } - void _processQrCodeData(String qrCodeData) { try { - final paymentData = AddressUtils.parsePaymentUri(qrCodeData); - if (paymentData.coin.uriScheme == coin.uriScheme) { + final paymentData = AddressUtils.parsePaymentUri( + qrCodeData, + logging: Logging.instance, + ); + + if (paymentData != null && + paymentData.coin?.uriScheme == coin.uriScheme) { // Auto fill address. _address = paymentData.address.trim(); sendToController.text = _address!; @@ -756,6 +691,14 @@ class _DesktopSendState extends ConsumerState { _note = paymentData.label; } + _setValidAddressProviders(_address); + setState(() { + _addressToggleFlag = sendToController.text.isNotEmpty; + }); + } else { + _address = qrCodeData.split("\n").first.trim(); + sendToController.text = _address ?? ""; + _setValidAddressProviders(_address); setState(() { _addressToggleFlag = sendToController.text.isNotEmpty; @@ -807,8 +750,12 @@ class _DesktopSendState extends ConsumerState { } try { - final paymentData = AddressUtils.parsePaymentUri(content); - if (paymentData.coin.uriScheme == coin.uriScheme) { + final paymentData = AddressUtils.parsePaymentUri( + content, + logging: Logging.instance, + ); + if (paymentData != null && + paymentData.coin?.uriScheme == coin.uriScheme) { // auto fill address _address = paymentData.address; sendToController.text = _address!; @@ -837,6 +784,7 @@ class _DesktopSendState extends ConsumerState { _addressToggleFlag = sendToController.text.isNotEmpty; }); } else { + content = content.split("\n").first.trim(); if (coin is Epiccash) { content = AddressUtils().formatAddress(content); } @@ -1860,7 +1808,7 @@ class _DesktopSendState extends ConsumerState { if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.regular.raw!, + lib_monero.TransactionPriority.medium.value, ); ref .read(feeSheetSessionCacheProvider) diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart index 490465490..e05a9f46a 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart @@ -14,14 +14,12 @@ import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; + import '../../../../models/isar/models/contact_entry.dart'; import '../../../../models/paynym/paynym_account_lite.dart'; import '../../../../models/send_view_auto_fill_data.dart'; import '../../../../pages/send_view/confirm_transaction_view.dart'; import '../../../../pages/send_view/sub_widgets/building_transaction_dialog.dart'; -import '../../../desktop_home_view.dart'; -import 'address_book_address_chooser/address_book_address_chooser.dart'; -import 'desktop_fee_dropdown.dart'; import '../../../../providers/providers.dart'; import '../../../../providers/ui/fee_rate_type_state_provider.dart'; import '../../../../providers/ui/preview_tx_button_state_provider.dart'; @@ -51,6 +49,9 @@ import '../../../../widgets/icon_widgets/clipboard_icon.dart'; import '../../../../widgets/icon_widgets/x_icon.dart'; import '../../../../widgets/stack_text_field.dart'; import '../../../../widgets/textfield_icon_button.dart'; +import '../../../desktop_home_view.dart'; +import 'address_book_address_chooser/address_book_address_chooser.dart'; +import 'desktop_fee_dropdown.dart'; // const _kCryptoAmountRegex = r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$'; @@ -480,25 +481,30 @@ class _DesktopTokenSendState extends ConsumerState { level: LogLevel.Info, ); - final results = AddressUtils.parseUri(qrResult.rawContent); + final paymentData = AddressUtils.parsePaymentUri( + qrResult.rawContent, + logging: Logging.instance, + ); - Logging.instance.log("qrResult parsed: $results", level: LogLevel.Info); + Logging.instance + .log("qrResult parsed: $paymentData", level: LogLevel.Info); - if (results.isNotEmpty && results["scheme"] == coin.uriScheme) { + if (paymentData != null && + paymentData.coin?.uriScheme == coin.uriScheme) { // auto fill address - _address = results["address"] ?? ""; + _address = paymentData.address.trim(); sendToController.text = _address!; // autofill notes field - if (results["message"] != null) { - _note = results["message"]!; - } else if (results["label"] != null) { - _note = results["label"]!; + if (paymentData.message != null) { + _note = paymentData.message!; + } else if (paymentData.label != null) { + _note = paymentData.label!; } // autofill amount field - if (results["amount"] != null) { - final amount = Decimal.parse(results["amount"]!).toAmount( + if (paymentData.amount != null) { + final Amount amount = Decimal.parse(paymentData.amount!).toAmount( fractionDigits: ref.read(pCurrentTokenWallet)!.tokenContract.decimals, ); @@ -516,12 +522,8 @@ class _DesktopTokenSendState extends ConsumerState { }); // now check for non standard encoded basic address - } else if (ref - .read(pWallets) - .getWallet(walletId) - .cryptoCurrency - .validateAddress(qrResult.rawContent)) { - _address = qrResult.rawContent; + } else { + _address = qrResult.rawContent.split("\n").first.trim(); sendToController.text = _address ?? ""; _updatePreviewButtonState(_address, _amountToSend); diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart index 4d9eaf026..9ad37d2a7 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart @@ -39,12 +39,14 @@ import '../../../../wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface import '../../../../wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart'; +import '../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../../widgets/custom_loading_overlay.dart'; import '../../../../widgets/desktop/desktop_dialog.dart'; import '../../../../widgets/desktop/primary_button.dart'; import '../../../../widgets/desktop/secondary_button.dart'; import '../../../../widgets/loading_indicator.dart'; import '../../../cashfusion/desktop_cashfusion_view.dart'; +import '../../../churning/desktop_churning_view.dart'; import '../../../coin_control/desktop_coin_control_view.dart'; import '../../../desktop_menu.dart'; import '../../../ordinals/desktop_ordinals_view.dart'; @@ -92,6 +94,7 @@ class _DesktopWalletFeaturesState extends ConsumerState { onOrdinalsPressed: _onOrdinalsPressed, onMonkeyPressed: _onMonkeyPressed, onFusionPressed: _onFusionPressed, + onChurnPressed: _onChurnPressed, ), ); } @@ -204,7 +207,7 @@ class _DesktopWalletFeaturesState extends ConsumerState { // await firoWallet.anonymizeAllLelantus(); await firoWallet.anonymizeAllSpark(); shouldPop = true; - if (context.mounted) { + if (mounted) { Navigator.of(context, rootNavigator: true).pop(); Navigator.of(context).popUntil( ModalRoute.withName(DesktopWalletView.routeName), @@ -219,7 +222,7 @@ class _DesktopWalletFeaturesState extends ConsumerState { } } catch (e) { shouldPop = true; - if (context.mounted) { + if (mounted) { Navigator.of(context, rootNavigator: true).pop(); Navigator.of(context).popUntil( ModalRoute.withName(DesktopWalletView.routeName), @@ -348,6 +351,15 @@ class _DesktopWalletFeaturesState extends ConsumerState { ); } + void _onChurnPressed() { + Navigator.of(context, rootNavigator: true).pop(); + + Navigator.of(context).pushNamed( + DesktopChurningView.routeName, + arguments: widget.walletId, + ); + } + @override Widget build(BuildContext context) { final wallet = ref.watch(pWallets).getWallet(widget.walletId); @@ -369,9 +381,12 @@ class _DesktopWalletFeaturesState extends ConsumerState { wallet is OrdinalsInterface || wallet is CashFusionInterface; + final isViewOnly = wallet is ViewOnlyOptionInterface && wallet.isViewOnly; + return Row( children: [ - if (Constants.enableExchange && + if (!isViewOnly && + Constants.enableExchange && AppConfig.hasFeature(AppFeature.swap) && showExchange) SecondaryButton( diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart index f849b7b09..e3a8f0dba 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart @@ -14,6 +14,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import '../../../../../app_config.dart'; import '../../../../../db/sqlite/firo_cache.dart'; +import '../../../../../models/keys/view_only_wallet_data.dart'; import '../../../../../providers/db/main_db_provider.dart'; import '../../../../../providers/global/prefs_provider.dart'; import '../../../../../providers/global/wallets_provider.dart'; @@ -23,6 +24,7 @@ import '../../../../../utilities/text_styles.dart'; import '../../../../../wallets/crypto_currency/crypto_currency.dart'; import '../../../../../wallets/isar/models/wallet_info.dart'; import '../../../../../wallets/isar/providers/wallet_info_provider.dart'; +import '../../../../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/lelantus_interface.dart'; @@ -30,6 +32,7 @@ import '../../../../../wallets/wallet/wallet_mixin_interfaces/ordinals_interface import '../../../../../wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/rbf_interface.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/spark_interface.dart'; +import '../../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../../../widgets/custom_buttons/draggable_switch_button.dart'; import '../../../../../widgets/desktop/desktop_dialog.dart'; import '../../../../../widgets/desktop/desktop_dialog_close_button.dart'; @@ -48,6 +51,7 @@ class MoreFeaturesDialog extends ConsumerStatefulWidget { required this.onOrdinalsPressed, required this.onMonkeyPressed, required this.onFusionPressed, + required this.onChurnPressed, }); final String walletId; @@ -58,6 +62,7 @@ class MoreFeaturesDialog extends ConsumerStatefulWidget { final VoidCallback? onOrdinalsPressed; final VoidCallback? onMonkeyPressed; final VoidCallback? onFusionPressed; + final VoidCallback? onChurnPressed; @override ConsumerState createState() => _MoreFeaturesDialogState(); @@ -235,6 +240,11 @@ class _MoreFeaturesDialogState extends ConsumerState { ), ); + final isViewOnly = wallet is ViewOnlyOptionInterface && wallet.isViewOnly; + final isViewOnlyNoAddressGen = wallet is ViewOnlyOptionInterface && + wallet.isViewOnly && + wallet.viewOnlyType == ViewOnlyWalletType.addressOnly; + return DesktopDialog( child: Column( mainAxisSize: MainAxisSize.min, @@ -254,7 +264,7 @@ class _MoreFeaturesDialogState extends ConsumerState { const DesktopDialogCloseButton(), ], ), - if (wallet.info.coin is Firo) + if (!isViewOnly && wallet.info.coin is Firo) _MoreFeaturesItem( label: "Anonymize funds", detail: "Anonymize funds", @@ -276,7 +286,7 @@ class _MoreFeaturesDialogState extends ConsumerState { iconAsset: Assets.svg.coinControl.gamePad, onPressed: () async => widget.onCoinControlPressed?.call(), ), - if (wallet is PaynymInterface) + if (!isViewOnly && wallet is PaynymInterface) _MoreFeaturesItem( label: "PayNym", detail: "Increased address privacy using BIP47", @@ -297,18 +307,25 @@ class _MoreFeaturesDialogState extends ConsumerState { iconAsset: Assets.svg.monkey, onPressed: () async => widget.onMonkeyPressed?.call(), ), - if (wallet is CashFusionInterface) + if (!isViewOnly && wallet is CashFusionInterface) _MoreFeaturesItem( label: "Fusion", detail: "Decentralized mixing protocol", iconAsset: Assets.svg.cashFusion, onPressed: () async => widget.onFusionPressed?.call(), ), - if (wallet is SparkInterface) + if (!isViewOnly && wallet is LibMoneroWallet) + _MoreFeaturesItem( + label: "Churn", + detail: "Churning", + iconAsset: Assets.svg.churn, + onPressed: () async => widget.onChurnPressed?.call(), + ), + if (wallet is SparkInterface && !isViewOnly) _MoreFeaturesClearSparkCacheItem( cryptoCurrency: wallet.cryptoCurrency, ), - if (wallet is LelantusInterface) + if (wallet is LelantusInterface && !isViewOnly) _MoreFeaturesItemBase( child: Row( children: [ @@ -373,40 +390,41 @@ class _MoreFeaturesDialogState extends ConsumerState { ), ), // reuseAddress preference. - _MoreFeaturesItemBase( - onPressed: _switchReuseAddressToggled, - child: Row( - children: [ - const SizedBox(width: 3), - SizedBox( - height: 20, - width: 40, - child: IgnorePointer( - child: DraggableSwitchButton( - isOn: ref.watch( - pWalletInfo(widget.walletId) - .select((value) => value.otherData), - )[WalletInfoKeys.reuseAddress] as bool? ?? - false, - controller: _switchController, + if (!isViewOnlyNoAddressGen) + _MoreFeaturesItemBase( + onPressed: _switchReuseAddressToggled, + child: Row( + children: [ + const SizedBox(width: 3), + SizedBox( + height: 20, + width: 40, + child: IgnorePointer( + child: DraggableSwitchButton( + isOn: ref.watch( + pWalletInfo(widget.walletId) + .select((value) => value.otherData), + )[WalletInfoKeys.reuseAddress] as bool? ?? + false, + controller: _switchController, + ), ), ), - ), - const SizedBox( - width: 16, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Reuse receiving address", - style: STextStyles.w600_20(context), - ), - ], - ), - ], + const SizedBox( + width: 16, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Reuse receiving address", + style: STextStyles.w600_20(context), + ), + ], + ), + ], + ), ), - ), const SizedBox( height: 28, ), diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/my_wallet.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/my_wallet.dart index 092f9884f..622630c4a 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/my_wallet.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/my_wallet.dart @@ -10,20 +10,22 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; + import '../../../../frost_route_generator.dart'; import '../../../../pages/send_view/frost_ms/frost_send_view.dart'; import '../../../../pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart'; -import '../../my_stack_view.dart'; -import 'desktop_receive.dart'; -import 'desktop_send.dart'; -import 'desktop_token_send.dart'; import '../../../../providers/global/wallets_provider.dart'; import '../../../../wallets/crypto_currency/crypto_currency.dart'; import '../../../../wallets/wallet/impl/bitcoin_frost_wallet.dart'; +import '../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../../widgets/custom_tab_view.dart'; import '../../../../widgets/desktop/secondary_button.dart'; import '../../../../widgets/frost_scaffold.dart'; import '../../../../widgets/rounded_white_container.dart'; +import '../../my_stack_view.dart'; +import 'desktop_receive.dart'; +import 'desktop_send.dart'; +import 'desktop_token_send.dart'; class MyWallet extends ConsumerStatefulWidget { const MyWallet({ @@ -48,6 +50,7 @@ class _MyWalletState extends ConsumerState { late final bool isEth; late final CryptoCurrency coin; late final bool isFrost; + late final bool isViewOnly; @override void initState() { @@ -60,11 +63,34 @@ class _MyWalletState extends ConsumerState { titles.add("Transactions"); } + isViewOnly = wallet is ViewOnlyOptionInterface && wallet.isViewOnly; + if (isViewOnly) { + titles.remove("Receive"); + } + super.initState(); } @override Widget build(BuildContext context) { + if (isViewOnly) { + return ListView( + primary: false, + children: [ + RoundedWhiteContainer( + padding: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.all(20), + child: DesktopReceive( + walletId: widget.walletId, + contractAddress: widget.contractAddress, + ), + ), + ), + ], + ); + } + return ListView( primary: false, children: [ diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart index e332c4543..f2357448c 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart @@ -23,9 +23,10 @@ import '../../../../utilities/assets.dart'; import '../../../../utilities/constants.dart'; import '../../../../utilities/text_styles.dart'; import '../../../../wallets/wallet/impl/bitcoin_frost_wallet.dart'; -import '../../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; +import '../../../../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; +import '../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../../widgets/desktop/desktop_dialog.dart'; import '../../../../widgets/desktop/desktop_dialog_close_button.dart'; import '../../../../widgets/desktop/primary_button.dart'; @@ -82,7 +83,9 @@ class _UnlockWalletKeysDesktopState .verifyPassphrase(passwordController.text); if (verified) { - Navigator.of(context, rootNavigator: true).pop(); + if (mounted) { + Navigator.of(context, rootNavigator: true).pop(); + } final wallet = ref.read(pWallets).getWallet(widget.walletId); ({String keys, String config})? frostData; @@ -100,13 +103,20 @@ class _UnlockWalletKeysDesktopState throw Exception("FIXME ~= see todo in code"); } } else { - words = await wallet.getMnemonicAsWords(); + if (wallet is ViewOnlyOptionInterface && + (wallet as ViewOnlyOptionInterface).isViewOnly) { + // TODO: is something needed here? + } else { + words = await wallet.getMnemonicAsWords(); + } } KeyDataInterface? keyData; - if (wallet is ExtendedKeysInterface) { + if (wallet is ViewOnlyOptionInterface && wallet.isViewOnly) { + keyData = await wallet.getViewOnlyWalletData(); + } else if (wallet is ExtendedKeysInterface) { keyData = await wallet.getXPrivs(); - } else if (wallet is CwBasedInterface) { + } else if (wallet is LibMoneroWallet) { keyData = await wallet.getKeys(); } @@ -122,17 +132,20 @@ class _UnlockWalletKeysDesktopState ); } } else { - Navigator.of(context, rootNavigator: true).pop(); + if (mounted) { + Navigator.of(context, rootNavigator: true).pop(); + } await Future.delayed(const Duration(milliseconds: 300)); - - unawaited( - showFloatingFlushBar( - type: FlushBarType.warning, - message: "Invalid passphrase!", - context: context, - ), - ); + if (mounted) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.warning, + message: "Invalid passphrase!", + context: context, + ), + ); + } } } @@ -327,7 +340,10 @@ class _UnlockWalletKeysDesktopState .verifyPassphrase(passwordController.text); if (verified) { - Navigator.of(context, rootNavigator: true).pop(); + if (context.mounted) { + Navigator.of(context, rootNavigator: true) + .pop(); + } ({String keys, String config})? frostData; List? words; @@ -347,13 +363,22 @@ class _UnlockWalletKeysDesktopState throw Exception("FIXME ~= see todo in code"); } } else { - words = await wallet.getMnemonicAsWords(); + if (wallet is ViewOnlyOptionInterface && + (wallet as ViewOnlyOptionInterface) + .isViewOnly) { + // TODO: is something needed here? + } else { + words = await wallet.getMnemonicAsWords(); + } } KeyDataInterface? keyData; - if (wallet is ExtendedKeysInterface) { + if (wallet is ViewOnlyOptionInterface && + wallet.isViewOnly) { + keyData = await wallet.getViewOnlyWalletData(); + } else if (wallet is ExtendedKeysInterface) { keyData = await wallet.getXPrivs(); - } else if (wallet is CwBasedInterface) { + } else if (wallet is LibMoneroWallet) { keyData = await wallet.getKeys(); } @@ -370,19 +395,23 @@ class _UnlockWalletKeysDesktopState ); } } else { - Navigator.of(context, rootNavigator: true).pop(); + if (context.mounted) { + Navigator.of(context, rootNavigator: true) + .pop(); + } await Future.delayed( const Duration(milliseconds: 300), ); - - unawaited( - showFloatingFlushBar( - type: FlushBarType.warning, - message: "Invalid passphrase!", - context: context, - ), - ); + if (context.mounted) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.warning, + message: "Invalid passphrase!", + context: context, + ), + ); + } } } : null, diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart index f1bc2d9f6..bb8ba8089 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart @@ -16,9 +16,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../../models/keys/cw_key_data.dart'; import '../../../../models/keys/key_data_interface.dart'; +import '../../../../models/keys/view_only_wallet_data.dart'; import '../../../../models/keys/xpriv_data.dart'; import '../../../../notifications/show_flush_bar.dart'; import '../../../../pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart'; +import '../../../../pages/settings_views/sub_widgets/view_only_wallet_data_widget.dart'; import '../../../../pages/settings_views/wallet_settings_view/wallet_backup_views/cn_wallet_keys.dart'; import '../../../../pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_xprivs.dart'; import '../../../../pages/wallet_view/transaction_views/transaction_details_view.dart'; @@ -180,31 +182,39 @@ class WalletKeysDesktopPopup extends ConsumerWidget { ], ) : keyData != null - ? CustomTabView( - titles: [ - "Mnemonic", - if (keyData is XPrivData) "XPriv(s)", - if (keyData is CWKeyData) "Keys", - ], - children: [ - Padding( - padding: const EdgeInsets.only(top: 16), - child: _Mnemonic( - words: words, + ? keyData is ViewOnlyWalletData + ? Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: ViewOnlyWalletDataWidget( + data: keyData as ViewOnlyWalletData, ), - ), - if (keyData is XPrivData) - WalletXPrivs( - xprivData: keyData as XPrivData, - walletId: walletId, - ), - if (keyData is CWKeyData) - CNWalletKeys( - cwKeyData: keyData as CWKeyData, - walletId: walletId, - ), - ], - ) + ) + : CustomTabView( + titles: [ + if (words.isNotEmpty) "Mnemonic", + if (keyData is XPrivData) "XPriv(s)", + if (keyData is CWKeyData) "Keys", + ], + children: [ + if (words.isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: 16), + child: _Mnemonic( + words: words, + ), + ), + if (keyData is XPrivData) + WalletXPrivs( + xprivData: keyData as XPrivData, + walletId: walletId, + ), + if (keyData is CWKeyData) + CNWalletKeys( + cwKeyData: keyData as CWKeyData, + walletId: walletId, + ), + ], + ) : _Mnemonic( words: words, ), 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 4f955c00f..e0da6d5e9 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 @@ -31,6 +31,7 @@ import '../../../../wallets/crypto_currency/intermediate/frost_currency.dart'; import '../../../../wallets/crypto_currency/intermediate/nano_currency.dart'; import '../../../../wallets/isar/providers/wallet_info_provider.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart'; +import '../../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../addresses/desktop_wallet_addresses_view.dart'; import '../../../lelantus_coins/lelantus_coins_view.dart'; import '../../../spark_coins/spark_coins_view.dart'; @@ -293,10 +294,15 @@ class WalletOptionsPopupMenu extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final coin = ref.watch(pWalletCoin(walletId)); - final firoDebug = kDebugMode && (coin is Firo); + bool firoDebug = kDebugMode && (coin is Firo); - final bool xpubEnabled = - ref.watch(pWallets).getWallet(walletId) is ExtendedKeysInterface; + final wallet = ref.watch(pWallets).getWallet(walletId); + bool xpubEnabled = wallet is ExtendedKeysInterface; + + if (wallet is ViewOnlyOptionInterface && wallet.isViewOnly) { + xpubEnabled = false; + firoDebug = false; + } final bool canChangeRep = coin is NanoCurrency; diff --git a/lib/pages_desktop_specific/settings/settings_menu/desktop_about_view.dart b/lib/pages_desktop_specific/settings/settings_menu/desktop_about_view.dart index 34c8a8dba..98a7dec34 100644 --- a/lib/pages_desktop_specific/settings/settings_menu/desktop_about_view.dart +++ b/lib/pages_desktop_specific/settings/settings_menu/desktop_about_view.dart @@ -434,63 +434,63 @@ class DesktopAboutView extends ConsumerWidget { ); }, ), - if (AppConfig.coins - .whereType() - .isNotEmpty) - FutureBuilder( - future: GitStatus - .getMoneroCommitStatus(), - builder: ( - context, - AsyncSnapshot - snapshot, - ) { - CommitStatus stateOfCommit = - CommitStatus.notLoaded; - - if (snapshot.connectionState == - ConnectionState - .done && - snapshot.hasData) { - stateOfCommit = - snapshot.data!; - } - return Column( - mainAxisSize: - MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Text( - "Monero Build Commit", - style: STextStyles - .desktopTextExtraExtraSmall( - context, - ).copyWith( - color: Theme.of( - context, - ) - .extension< - StackColors>()! - .textDark, - ), - ), - const SizedBox( - height: 2, - ), - SelectableText( - GitStatus.moneroCommit, - style: GitStatus - .styleForStatus( - stateOfCommit, - context, - ), - ), - ], - ); - }, - ), + // if (AppConfig.coins + // .whereType() + // .isNotEmpty) + // FutureBuilder( + // future: GitStatus + // .getMoneroCommitStatus(), + // builder: ( + // context, + // AsyncSnapshot + // snapshot, + // ) { + // CommitStatus stateOfCommit = + // CommitStatus.notLoaded; + // + // if (snapshot.connectionState == + // ConnectionState + // .done && + // snapshot.hasData) { + // stateOfCommit = + // snapshot.data!; + // } + // return Column( + // mainAxisSize: + // MainAxisSize.min, + // crossAxisAlignment: + // CrossAxisAlignment + // .start, + // children: [ + // Text( + // "Monero Build Commit", + // style: STextStyles + // .desktopTextExtraExtraSmall( + // context, + // ).copyWith( + // color: Theme.of( + // context, + // ) + // .extension< + // StackColors>()! + // .textDark, + // ), + // ), + // const SizedBox( + // height: 2, + // ), + // SelectableText( + // GitStatus.moneroCommit, + // style: GitStatus + // .styleForStatus( + // stateOfCommit, + // context, + // ), + // ), + // ], + // ); + // }, + // ), ], ), const SizedBox(height: 35), diff --git a/lib/providers/churning/churning_service_provider.dart b/lib/providers/churning/churning_service_provider.dart new file mode 100644 index 000000000..642d1103f --- /dev/null +++ b/lib/providers/churning/churning_service_provider.dart @@ -0,0 +1,12 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import '../../services/churning_service.dart'; +import '../../wallets/wallet/intermediate/lib_monero_wallet.dart'; +import '../global/wallets_provider.dart'; + +final pChurningService = ChangeNotifierProvider.family( + (ref, walletId) { + final wallet = ref.watch(pWallets.select((s) => s.getWallet(walletId))); + return ChurningService(wallet: wallet as LibMoneroWallet); + }, +); diff --git a/lib/route_generator.dart b/lib/route_generator.dart index b449525b6..52454fb29 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -23,6 +23,7 @@ import 'models/isar/models/contact_entry.dart'; import 'models/isar/models/isar_models.dart'; import 'models/isar/ordinal.dart'; import 'models/keys/key_data_interface.dart'; +import 'models/keys/view_only_wallet_data.dart'; import 'models/paynym/paynym_account_lite.dart'; import 'models/send_view_auto_fill_data.dart'; import 'pages/add_wallet_views/add_token_view/add_custom_token_view.dart'; @@ -37,6 +38,7 @@ import 'pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart'; import 'pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart'; import 'pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart'; import 'pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart'; +import 'pages/add_wallet_views/restore_wallet_view/restore_view_only_wallet_view.dart'; import 'pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart'; import 'pages/add_wallet_views/select_wallet_for_token_view.dart'; import 'pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart'; @@ -52,6 +54,8 @@ import 'pages/buy_view/buy_quote_preview.dart'; import 'pages/buy_view/buy_view.dart'; import 'pages/cashfusion/cashfusion_view.dart'; import 'pages/cashfusion/fusion_progress_view.dart'; +import 'pages/churning/churning_progress_view.dart'; +import 'pages/churning/churning_view.dart'; import 'pages/coin_control/coin_control_view.dart'; import 'pages/coin_control/utxo_details_view.dart'; import 'pages/exchange_view/choose_from_stack_view.dart'; @@ -128,6 +132,7 @@ import 'pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_bac import 'pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart'; import 'pages/settings_views/wallet_settings_view/wallet_settings_view.dart'; import 'pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/change_representative_view.dart'; +import 'pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_view_only_wallet_keys_view.dart'; import 'pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart'; import 'pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart'; import 'pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/lelantus_settings_view.dart'; @@ -155,6 +160,7 @@ import 'pages/wallets_view/wallets_view.dart'; import 'pages_desktop_specific/address_book_view/desktop_address_book.dart'; import 'pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart'; import 'pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart'; +import 'pages_desktop_specific/churning/desktop_churning_view.dart'; import 'pages_desktop_specific/coin_control/desktop_coin_control_view.dart'; // import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_all_buys_view.dart'; import 'pages_desktop_specific/desktop_buy/desktop_buy_view.dart'; @@ -779,6 +785,34 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case ChurningView.routeName: + if (args is String) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => ChurningView( + walletId: args, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + + case ChurningProgressView.routeName: + if (args is String) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => ChurningProgressView( + walletId: args, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case DesktopCashFusionView.routeName: if (args is String) { return getRoute( @@ -793,6 +827,20 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case DesktopChurningView.routeName: + if (args is String) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => DesktopChurningView( + walletId: args, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case GlobalSettingsView.routeName: return getRoute( shouldUseMaterialRoute: useMaterialPageRoute, @@ -1456,7 +1504,7 @@ class RouteGenerator { case RestoreWalletView.routeName: if (args - is Tuple6) { + is Tuple6) { return getRoute( shouldUseMaterialRoute: useMaterialPageRoute, builder: (_) => RestoreWalletView( @@ -1474,6 +1522,28 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case RestoreViewOnlyWalletView.routeName: + if (args is ({ + String walletName, + CryptoCurrency coin, + DateTime? restoreFromDate, + bool enableLelantusScanning, + })) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => RestoreViewOnlyWalletView( + walletName: args.walletName, + coin: args.coin, + restoreFromDate: args.restoreFromDate, + enableLelantusScanning: args.enableLelantusScanning, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case NewWalletRecoveryPhraseView.routeName: if (args is Tuple2>) { return getRoute( @@ -1882,6 +1952,21 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case DeleteViewOnlyWalletKeysView.routeName: + if (args is ({String walletId, ViewOnlyWalletData data})) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => DeleteViewOnlyWalletKeysView( + data: args.data, + walletId: args.walletId, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + // exchange steps case Step1View.routeName: diff --git a/lib/services/churning_service.dart b/lib/services/churning_service.dart new file mode 100644 index 000000000..0aecefe08 --- /dev/null +++ b/lib/services/churning_service.dart @@ -0,0 +1,207 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:cs_monero/cs_monero.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:mutex/mutex.dart'; + +import '../wallets/wallet/intermediate/lib_monero_wallet.dart'; + +enum ChurnStatus { + waiting, + running, + failed, + success; +} + +class ChurningService extends ChangeNotifier { + // stack only uses account 0 at this point in time + static const kAccount = 0; + + ChurningService({required this.wallet}); + + final LibMoneroWallet wallet; + Wallet get csWallet => wallet.libMoneroWallet!; + + int rounds = 1; // default + bool ignoreErrors = false; // default + + bool _running = false; + + ChurnStatus waitingForUnlockedBalance = ChurnStatus.waiting; + ChurnStatus makingChurnTransaction = ChurnStatus.waiting; + ChurnStatus completedStatus = ChurnStatus.waiting; + int roundsCompleted = 0; + bool done = false; + Object? lastSeenError; + + bool _canChurn() { + if (csWallet.getUnlockedBalance(accountIndex: kAccount) > BigInt.zero) { + return true; + } else { + return false; + } + } + + String? confirmsInfo; + Future _updateConfirmsInfo() async { + final currentHeight = wallet.currentKnownChainHeight; + if (currentHeight < 1) { + return; + } + + final outputs = await csWallet.getOutputs(refresh: true); + final required = wallet.cryptoCurrency.minConfirms; + + int lowestNumberOfConfirms = required; + + for (final output in outputs.where((e) => !e.isFrozen && !e.spent)) { + final confirms = currentHeight - output.height; + + lowestNumberOfConfirms = min(lowestNumberOfConfirms, confirms); + } + + final bool shouldNotify; + if (lowestNumberOfConfirms == required) { + shouldNotify = confirmsInfo != null; + confirmsInfo = null; + } else { + final prev = confirmsInfo; + confirmsInfo = "($lowestNumberOfConfirms/$required)"; + shouldNotify = confirmsInfo != prev; + } + + if (_running && _timerRunning && shouldNotify) { + notifyListeners(); + } + } + + Timer? _confirmsTimer; + bool _timerRunning = false; + void _stopConfirmsTimer() { + _timerRunning = false; + _confirmsTimer?.cancel(); + confirmsInfo = null; + _confirmsTimer = null; + } + + void _startConfirmsTimer() { + _confirmsTimer?.cancel(); + _confirmsTimer = Timer.periodic( + const Duration(seconds: 5), + (_) => _updateConfirmsInfo(), + ); + } + + final _pause = Mutex(); + bool get isPaused => _pause.isLocked; + void unpause() { + if (_pause.isLocked) _pause.release(); + } + + Future churn() async { + if (rounds < 0 || _running) { + // TODO: error? + return; + } + + _running = true; + waitingForUnlockedBalance = ChurnStatus.running; + makingChurnTransaction = ChurnStatus.waiting; + completedStatus = ChurnStatus.waiting; + roundsCompleted = 0; + done = false; + lastSeenError = null; + notifyListeners(); + + final roundsToDo = rounds; + final continuous = rounds == 0; + + bool complete() => !continuous && roundsCompleted >= roundsToDo; + + while (!complete() && _running) { + if (_canChurn()) { + waitingForUnlockedBalance = ChurnStatus.success; + makingChurnTransaction = ChurnStatus.running; + notifyListeners(); + + try { + _stopConfirmsTimer(); + Logging.log?.i("Doing churn #${roundsCompleted + 1}"); + await _churnTxSimple(); + waitingForUnlockedBalance = ChurnStatus.success; + makingChurnTransaction = ChurnStatus.success; + roundsCompleted++; + notifyListeners(); + } catch (e, s) { + Logging.log?.e( + "Churning round #${roundsCompleted + 1} failed", + error: e, + stackTrace: s, + ); + lastSeenError = e; + makingChurnTransaction = ChurnStatus.failed; + notifyListeners(); + if (!ignoreErrors) { + await _pause.acquire(); + await _pause.protect(() async {}); + + if (!_running) { + completedStatus = ChurnStatus.failed; + // exit if stop option chosen on error + return; + } + } + } + } else { + Logging.log?.i("Can't churn yet, waiting..."); + } + + if (!complete() && _running) { + _startConfirmsTimer(); + waitingForUnlockedBalance = ChurnStatus.running; + makingChurnTransaction = ChurnStatus.waiting; + completedStatus = ChurnStatus.waiting; + notifyListeners(); + // sleep + await Future.delayed(const Duration(seconds: 30)); + } + } + + waitingForUnlockedBalance = ChurnStatus.success; + makingChurnTransaction = ChurnStatus.success; + completedStatus = ChurnStatus.success; + done = true; + _running = false; + notifyListeners(); + Logging.log?.i("Churning complete"); + } + + void stopChurning() { + done = true; + _running = false; + notifyListeners(); + unpause(); + } + + Future _churnTxSimple({ + final TransactionPriority priority = TransactionPriority.normal, + }) async { + final address = csWallet.getAddress( + accountIndex: kAccount, + addressIndex: 0, + ); + + final pending = await csWallet.createTx( + output: Recipient( + address: address.value, + amount: BigInt.zero, // Doesn't matter if `sweep` is true + ), + priority: priority, + accountIndex: kAccount, + sweep: true, + ); + + await csWallet.commitTx(pending); + } +} diff --git a/lib/services/ethereum/ethereum_api.dart b/lib/services/ethereum/ethereum_api.dart index a74bca89e..6f5f2313e 100644 --- a/lib/services/ethereum/ethereum_api.dart +++ b/lib/services/ethereum/ethereum_api.dart @@ -612,9 +612,21 @@ abstract class EthereumAPI { ); } + static Future _addContractInfoToServer(String contractAddress) async { + await client.get( + url: Uri.parse( + "$stackBaseServer/names?terms=$contractAddress&autoname=$contractAddress&all", + ), + proxyInfo: Prefs.instance.useTor + ? TorService.sharedInstance.getProxyInfo() + : null, + ); + } + static Future> getTokenContractInfoByAddress( - String contractAddress, - ) async { + String contractAddress, { + bool autoNameOnEmpty = true, + }) async { try { final response = await client.get( url: Uri.parse( @@ -630,7 +642,28 @@ abstract class EthereumAPI { final json = jsonDecode(response.body) as Map; if (json["data"] is List) { if ((json["data"] as List).isEmpty) { - throw EthApiException("Unknown token"); + if (autoNameOnEmpty) { + Logging.instance.log( + "getTokenByContractAddress(): Adding token data to server", + level: LogLevel.Debug, + ); + // this will add the missing data to server + await _addContractInfoToServer(contractAddress); + + Logging.instance.log( + "getTokenByContractAddress(): Adding to server threw so now" + "we try a normal fetch again", + level: LogLevel.Debug, + ); + + // now try again + return await getTokenContractInfoByAddress( + contractAddress, + autoNameOnEmpty: false, // prevent possible infinite loop + ); + } else { + throw EthApiException("Unknown token"); + } } final map = Map.from(json["data"].first as Map); @@ -653,7 +686,7 @@ abstract class EthereumAPI { ); } else { throw EthApiException( - "Unsupported token type found: ${map["type"]}", + "Unsupported token type found: ${map["type"]} in $map", ); } diff --git a/lib/services/event_bus/events/global/updated_in_background_event.dart b/lib/services/event_bus/events/global/updated_in_background_event.dart index 582978357..36a23360f 100644 --- a/lib/services/event_bus/events/global/updated_in_background_event.dart +++ b/lib/services/event_bus/events/global/updated_in_background_event.dart @@ -8,6 +8,8 @@ * */ +import 'package:flutter/foundation.dart'; + import '../../../../utilities/logger.dart'; class UpdatedInBackgroundEvent { @@ -15,9 +17,11 @@ class UpdatedInBackgroundEvent { String walletId; UpdatedInBackgroundEvent(this.message, this.walletId) { - Logging.instance.log( - "UpdatedInBackgroundEvent fired with message: $message", - level: LogLevel.Info, - ); + if (kDebugMode) { + Logging.instance.log( + "UpdatedInBackgroundEvent fired with message: $message", + level: LogLevel.Info, + ); + } } } diff --git a/lib/services/exchange/exchange_data_loading_service.dart b/lib/services/exchange/exchange_data_loading_service.dart index cfb01e150..811949d6e 100644 --- a/lib/services/exchange/exchange_data_loading_service.dart +++ b/lib/services/exchange/exchange_data_loading_service.dart @@ -12,6 +12,7 @@ import 'package:flutter/foundation.dart'; import 'package:isar/isar.dart'; import 'package:tuple/tuple.dart'; +import '../../app_config.dart'; import '../../db/hive/db.dart'; import '../../models/exchange/active_pair.dart'; import '../../models/exchange/aggregate_currency.dart'; @@ -79,7 +80,7 @@ class ExchangeDataLoadingService { if (await isar.currencies.count() > 0) { pair?.setSend( await getAggregateCurrency( - "BTC", + AppConfig.swapDefaults.from, rateType, null, ), @@ -88,7 +89,7 @@ class ExchangeDataLoadingService { pair?.setReceive( await getAggregateCurrency( - "XMR", + AppConfig.swapDefaults.to, rateType, null, ), diff --git a/lib/services/frost.dart b/lib/services/frost.dart index 06eb674f6..a3e2e030f 100644 --- a/lib/services/frost.dart +++ b/lib/services/frost.dart @@ -80,6 +80,7 @@ abstract class Frost { int feePerWeight, List inputs, }) extractDataFromSignConfig({ + required String serializedKeys, required String signConfig, required CryptoCurrency coin, }) { @@ -89,6 +90,7 @@ abstract class Frost { final signConfigPointer = decodedSignConfig( encodedConfig: signConfig, network: network, + serializedKeys: serializedKeys, ); // get various data from config @@ -126,6 +128,7 @@ abstract class Frost { final List outputs = []; for (int i = 0; i < count; i++) { final output = signInput( + thresholdKeysWrapperPointer: deserializeKeys(keys: serializedKeys), signConfig: signConfig, index: i, network: network, @@ -283,6 +286,7 @@ abstract class Frost { //=================== transaction creation =================================== static String createSignConfig({ + required String serializedKeys, required int network, required List< ({ @@ -297,6 +301,7 @@ abstract class Frost { }) { try { final signConfig = newSignConfig( + thresholdKeysWrapperPointer: deserializeKeys(keys: serializedKeys), network: network, outputs: inputs .map( @@ -402,12 +407,16 @@ abstract class Frost { } static Pointer decodedSignConfig({ + required String serializedKeys, required String encodedConfig, required int network, }) { try { - final configPtr = - decodeSignConfig(encodedSignConfig: encodedConfig, network: network); + final configPtr = decodeSignConfig( + thresholdKeysWrapperPointer: deserializeKeys(keys: serializedKeys), + encodedSignConfig: encodedConfig, + network: network, + ); return configPtr; } catch (e, s) { Logging.instance.log( diff --git a/lib/services/price.dart b/lib/services/price.dart index dc4f3d8d8..5a97e43cb 100644 --- a/lib/services/price.dart +++ b/lib/services/price.dart @@ -30,6 +30,7 @@ class PriceAPI { BitcoinFrost: "bitcoin", Litecoin: "litecoin", Bitcoincash: "bitcoin-cash", + Cardano: "cardano", Dash: "dash", Dogecoin: "dogecoin", Epiccash: "epic-cash", diff --git a/lib/services/wallets.dart b/lib/services/wallets.dart index c4e75bde8..c606a75cf 100644 --- a/lib/services/wallets.dart +++ b/lib/services/wallets.dart @@ -10,8 +10,7 @@ import 'dart:async'; -import 'package:flutter_libmonero/monero/monero.dart' as monero; -import 'package:flutter_libmonero/wownero/wownero.dart' as wownero; +import 'package:compat/compat.dart' as lib_monero_compat; import 'package:isar/isar.dart'; import '../app_config.dart'; @@ -21,11 +20,12 @@ import '../utilities/enums/sync_type_enum.dart'; import '../utilities/flutter_secure_storage_interface.dart'; import '../utilities/logger.dart'; import '../utilities/prefs.dart'; +import '../utilities/stack_file_system.dart'; import '../wallets/crypto_currency/crypto_currency.dart'; import '../wallets/isar/models/wallet_info.dart'; import '../wallets/wallet/impl/epiccash_wallet.dart'; +import '../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../wallets/wallet/wallet.dart'; -import '../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; import 'event_bus/events/wallet_added_event.dart'; import 'event_bus/global_event_bus.dart'; import 'node_service.dart'; @@ -84,17 +84,24 @@ class Wallets { key: Wallet.mnemonicPassphraseKey(walletId: walletId), ); await secureStorage.delete(key: Wallet.privateKeyKey(walletId: walletId)); + await secureStorage.delete( + key: Wallet.getViewOnlyWalletDataSecStoreKey(walletId: walletId), + ); if (info.coin is Wownero) { - final wowService = wownero.wownero - .createWowneroWalletService(DB.instance.moneroWalletInfoBox); - await wowService.remove(walletId); + await lib_monero_compat.deleteWalletFiles( + name: walletId, + type: lib_monero_compat.WalletType.wownero, + appRoot: await StackFileSystem.applicationRootDirectory(), + ); Logging.instance .log("monero wallet: $walletId deleted", level: LogLevel.Info); } else if (info.coin is Monero) { - final xmrService = monero.monero - .createMoneroWalletService(DB.instance.moneroWalletInfoBox); - await xmrService.remove(walletId); + await lib_monero_compat.deleteWalletFiles( + name: walletId, + type: lib_monero_compat.WalletType.monero, + appRoot: await StackFileSystem.applicationRootDirectory(), + ); Logging.instance .log("monero wallet: $walletId deleted", level: LogLevel.Info); } else if (info.coin is Epiccash) { @@ -220,7 +227,7 @@ class Wallets { final shouldSetAutoSync = shouldAutoSyncAll || walletIdsToEnableAutoSync.contains(walletInfo.walletId); - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { // walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync)); } else { walletInitFutures.add( @@ -327,7 +334,7 @@ class Wallets { nodeService: nodeService, prefs: prefs, ).then((wallet) { - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { // walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync)); walletIdCompleter.complete("dummy_ignore"); @@ -457,7 +464,7 @@ class Wallets { nodeService: nodeService, prefs: prefs, ).then((wallet) { - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { // walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync)); walletIdCompleter.complete("dummy_ignore"); @@ -577,7 +584,7 @@ class Wallets { walletIdsToEnableAutoSync.contains(wallet.walletId); if (isDesktop) { - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { // walletsToInitLinearly.add(Tuple2(manager, shouldSetAutoSync)); } else { walletInitFutures.add( diff --git a/lib/utilities/address_utils.dart b/lib/utilities/address_utils.dart index 869aa5895..2e6b241b8 100644 --- a/lib/utilities/address_utils.dart +++ b/lib/utilities/address_utils.dart @@ -12,6 +12,7 @@ import 'dart:convert'; import '../app_config.dart'; import '../wallets/crypto_currency/crypto_currency.dart'; +import 'logger.dart'; class AddressUtils { static final Set recognizedParams = { @@ -29,166 +30,16 @@ class AddressUtils { return '${address.substring(0, 5)}...${address.substring(address.length - 5)}'; } - // static bool validateAddress(String address, Coin coin) { - // //This calls the validate address for each crypto coin, validateAddress is - // //only used in 2 places, so I just replaced the old functionality here - // switch (coin) { - // case Coin.bitcoin: - // return Bitcoin(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.bitcoinFrost: - // return BitcoinFrost(CryptoCurrencyNetwork.main) - // .validateAddress(address); - // case Coin.litecoin: - // return Litecoin(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.bitcoincash: - // return Bitcoincash(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.dogecoin: - // return Dogecoin(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.epicCash: - // return Epiccash(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.ethereum: - // return Ethereum(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.firo: - // return Firo(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.eCash: - // return Ecash(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.monero: - // return Monero(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.wownero: - // return Wownero(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.namecoin: - // return Namecoin(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.particl: - // return Particl(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.peercoin: - // return Peercoin(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.solana: - // return Solana(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.stellar: - // return Stellar(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.nano: - // return Nano(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.banano: - // return Banano(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.tezos: - // return Tezos(CryptoCurrencyNetwork.main).validateAddress(address); - // case Coin.bitcoinTestNet: - // return Bitcoin(CryptoCurrencyNetwork.test).validateAddress(address); - // case Coin.bitcoinFrostTestNet: - // return BitcoinFrost(CryptoCurrencyNetwork.test) - // .validateAddress(address); - // case Coin.litecoinTestNet: - // return Litecoin(CryptoCurrencyNetwork.test).validateAddress(address); - // case Coin.bitcoincashTestnet: - // return Bitcoincash(CryptoCurrencyNetwork.test).validateAddress(address); - // case Coin.firoTestNet: - // return Firo(CryptoCurrencyNetwork.test).validateAddress(address); - // case Coin.dogecoinTestNet: - // return Dogecoin(CryptoCurrencyNetwork.test).validateAddress(address); - // case Coin.peercoinTestNet: - // return Peercoin(CryptoCurrencyNetwork.test).validateAddress(address); - // case Coin.stellarTestnet: - // return Stellar(CryptoCurrencyNetwork.test).validateAddress(address); - // } - // // throw Exception("moved"); - // // switch (coin) { - // // case Coin.bitcoin: - // // return Address.validateAddress(address, bitcoin); - // // case Coin.litecoin: - // // return Address.validateAddress(address, litecoin); - // // case Coin.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: - // // return validateSendAddress(address) == "1"; - // // case Coin.ethereum: - // // return true; //TODO - validate ETH address - // // case Coin.firo: - // // return Address.validateAddress(address, firoNetwork); - // // case Coin.eCash: - // // return Address.validateAddress(address, eCashNetwork); - // // case Coin.monero: - // // return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) || - // // RegExp("[a-zA-Z0-9]{106}").hasMatch(address); - // // case Coin.wownero: - // // return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) || - // // RegExp("[a-zA-Z0-9]{106}").hasMatch(address); - // // case Coin.namecoin: - // // return Address.validateAddress(address, namecoin, namecoin.bech32!); - // // case Coin.particl: - // // return Address.validateAddress(address, particl); - // // case Coin.stellar: - // // return RegExp(r"^[G][A-Z0-9]{55}$").hasMatch(address); - // // case Coin.nano: - // // return NanoAccounts.isValid(NanoAccountType.NANO, address); - // // case Coin.banano: - // // return NanoAccounts.isValid(NanoAccountType.BANANO, address); - // // case Coin.tezos: - // // return RegExp(r"^tz[1-9A-HJ-NP-Za-km-z]{34}$").hasMatch(address); - // // case Coin.bitcoinTestNet: - // // return Address.validateAddress(address, testnet); - // // case Coin.litecoinTestNet: - // // return Address.validateAddress(address, litecointestnet); - // // case Coin.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: - // // return Address.validateAddress(address, dogecointestnet); - // // case Coin.stellarTestnet: - // // return RegExp(r"^[G][A-Z0-9]{55}$").hasMatch(address); - // // } - // } - /// Return only recognized parameters. - static Map filterParams(Map params) { - return Map.fromEntries(params.entries - .where((entry) => recognizedParams.contains(entry.key.toLowerCase()))); + static Map _filterParams(Map params) { + return Map.fromEntries( + params.entries + .where((entry) => recognizedParams.contains(entry.key.toLowerCase())), + ); } /// Parses a URI string and returns a map with parsed components. - static Map parseUri(String uri) { + static Map _parseUri(String uri) { final Map result = {}; try { final u = Uri.parse(uri); @@ -273,28 +124,36 @@ class AddressUtils { } /// Centralized method to handle various cryptocurrency URIs and return a common object. - static PaymentUriData parsePaymentUri(String uri) { - final Map parsedData = parseUri(uri); + /// + /// Returns null on failure to parse + static PaymentUriData? parsePaymentUri( + String uri, { + Logging? logging, + }) { + try { + final Map parsedData = _parseUri(uri); - // Normalize the URI scheme. - final String scheme = parsedData['scheme'] ?? ''; - parsedData.remove('scheme'); + // Normalize the URI scheme. + final String scheme = parsedData['scheme'] ?? ''; + parsedData.remove('scheme'); - // Determine the coin type based on the URI scheme. - final CryptoCurrency coin = _getCryptoCurrencyByScheme(scheme); + // Filter out unrecognized parameters. + final filteredParams = _filterParams(parsedData); - // Filter out unrecognized parameters. - final filteredParams = filterParams(parsedData); - - return PaymentUriData( - coin: coin, - address: parsedData['address'] ?? '', - amount: filteredParams['amount'] ?? filteredParams['tx_amount'], - label: filteredParams['label'] ?? filteredParams['recipient_name'], - message: filteredParams['message'] ?? filteredParams['tx_description'], - paymentId: filteredParams['tx_payment_id'], // Specific to Monero - additionalParams: filteredParams, - ); + return PaymentUriData( + scheme: scheme, + address: parsedData['address']!.trim(), + amount: filteredParams['amount'] ?? filteredParams['tx_amount'], + label: filteredParams['label'] ?? filteredParams['recipient_name'], + message: filteredParams['message'] ?? filteredParams['tx_description'], + paymentId: filteredParams['tx_payment_id'], + // Specific to Monero + additionalParams: filteredParams, + ); + } catch (e, s) { + logging?.log("$e\n$s", level: LogLevel.Error); + return null; + } } /// Builds a uri string with the given address and query parameters (if any) @@ -304,7 +163,7 @@ class AddressUtils { Map params, ) { // Filter unrecognized parameters. - final filteredParams = filterParams(params); + final filteredParams = _filterParams(params); String uriString = "$scheme:$address"; if (scheme.toLowerCase() == "monero") { @@ -345,11 +204,12 @@ class AddressUtils { } /// Method to get CryptoCurrency based on URI scheme. - static CryptoCurrency _getCryptoCurrencyByScheme(String scheme) { + static CryptoCurrency? _getCryptoCurrencyByScheme(String scheme) { if (AppConfig.coins.map((e) => e.uriScheme).toSet().contains(scheme)) { return AppConfig.coins.firstWhere((e) => e.uriScheme == scheme); } else { - throw UnsupportedError('Unsupported URI scheme: $scheme'); + return null; + // throw UnsupportedError('Unsupported URI scheme: $scheme'); } } @@ -375,21 +235,37 @@ class AddressUtils { } class PaymentUriData { - final CryptoCurrency coin; final String address; + final String? scheme; final String? amount; final String? label; final String? message; final String? paymentId; // Specific to Monero. final Map additionalParams; + CryptoCurrency? get coin => AddressUtils._getCryptoCurrencyByScheme( + scheme ?? "", // empty will just return null + ); + PaymentUriData({ - required this.coin, required this.address, + this.scheme, this.amount, this.label, this.message, this.paymentId, required this.additionalParams, }); + + @override + String toString() => "PaymentUriData { " + "coin: $coin, " + "address: $address, " + "amount: $amount, " + "scheme: $scheme, " + "label: $label, " + "message: $message, " + "paymentId: $paymentId, " + "additionalParams: $additionalParams" + " }"; } diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart index c8bfaf1fb..e0245131a 100644 --- a/lib/utilities/assets.dart +++ b/lib/utilities/assets.dart @@ -205,6 +205,7 @@ class _SVG { String get robotHead => "assets/svg/robot-head.svg"; String get whirlPool => "assets/svg/whirlpool.svg"; String get cashFusion => "assets/svg/cashfusion-icon.svg"; + String get churn => "assets/svg/churn.svg"; String get fingerprint => "assets/svg/fingerprint.svg"; String get faceId => "assets/svg/faceid.svg"; String get tokens => "assets/svg/tokens.svg"; diff --git a/lib/utilities/biometrics.dart b/lib/utilities/biometrics.dart index 18e27cbfb..cf9d8c27d 100644 --- a/lib/utilities/biometrics.dart +++ b/lib/utilities/biometrics.dart @@ -10,8 +10,8 @@ import 'dart:io'; -import 'package:local_auth/auth_strings.dart'; import 'package:local_auth/local_auth.dart'; +import 'package:local_auth_android/local_auth_android.dart'; import 'logger.dart'; @@ -46,80 +46,43 @@ class Biometrics { final canCheckBiometrics = await localAuth.canCheckBiometrics; final isDeviceSupported = await localAuth.isDeviceSupported(); - //todo: check if print needed // debugPrint("canCheckBiometrics: $canCheckBiometrics"); // debugPrint("isDeviceSupported: $isDeviceSupported"); if (canCheckBiometrics && isDeviceSupported) { - final List availableSystems = + List availableSystems = await localAuth.getAvailableBiometrics(); - //todo: check if print needed - // debugPrint("availableSystems: $availableSystems"); + Logging.instance.log( + "Bio availableSystems: $availableSystems", + level: LogLevel.Info, + ); //TODO properly handle caught exceptions - if (Platform.isIOS) { - if (availableSystems.contains(BiometricType.face)) { - try { - final bool didAuthenticate = await localAuth.authenticate( - biometricOnly: true, - localizedReason: localizedReason, - stickyAuth: true, - iOSAuthStrings: const IOSAuthMessages(), - ); + try { + final bool didAuthenticate = await localAuth.authenticate( + localizedReason: localizedReason, + options: const AuthenticationOptions( + stickyAuth: true, + biometricOnly: true, + ), + authMessages: [ + AndroidAuthMessages( + biometricHint: "", + cancelButton: cancelButtonText, + signInTitle: title, + ), + ], + ); - if (didAuthenticate) { - return true; - } - } catch (e) { - Logging.instance.log( - "local_auth exception caught in Biometrics.authenticate(), e: $e", - level: LogLevel.Error, - ); - } - } else if (availableSystems.contains(BiometricType.fingerprint)) { - try { - final bool didAuthenticate = await localAuth.authenticate( - biometricOnly: true, - localizedReason: localizedReason, - stickyAuth: true, - iOSAuthStrings: const IOSAuthMessages(), - ); - - if (didAuthenticate) { - return true; - } - } catch (e) { - Logging.instance.log( - "local_auth exception caught in Biometrics.authenticate(), e: $e", - level: LogLevel.Error, - ); - } - } - } else if (Platform.isAndroid) { - if (availableSystems.contains(BiometricType.fingerprint)) { - try { - final bool didAuthenticate = await localAuth.authenticate( - biometricOnly: true, - localizedReason: localizedReason, - stickyAuth: true, - androidAuthStrings: AndroidAuthMessages( - biometricHint: "", - cancelButton: cancelButtonText, - signInTitle: title, - ), - ); - - if (didAuthenticate) { - return true; - } - } catch (e) { - Logging.instance.log( - "local_auth exception caught in Biometrics.authenticate(), e: $e", - level: LogLevel.Error, - ); - } + if (didAuthenticate) { + return true; } + } catch (e) { + Logging.instance.log( + "local_auth exception caught in Biometrics.authenticate(), e: $e", + level: LogLevel.Error, + ); } } diff --git a/lib/utilities/enums/derive_path_type_enum.dart b/lib/utilities/enums/derive_path_type_enum.dart index 8981cf1c3..3d64fb45a 100644 --- a/lib/utilities/enums/derive_path_type_enum.dart +++ b/lib/utilities/enums/derive_path_type_enum.dart @@ -18,7 +18,8 @@ enum DerivePathType { eth, eCash44, solana, - bip86; + bip86, + cardanoShelley; AddressType getAddressType() { switch (this) { @@ -41,6 +42,9 @@ enum DerivePathType { case DerivePathType.bip86: return AddressType.p2tr; + + case DerivePathType.cardanoShelley: + return AddressType.cardanoShelley; } } } diff --git a/lib/utilities/git_status.dart b/lib/utilities/git_status.dart index 818660427..093bc39af 100644 --- a/lib/utilities/git_status.dart +++ b/lib/utilities/git_status.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_libepiccash/git_versions.dart' as epic_versions; -import 'package:flutter_libmonero/git_versions.dart' as monero_versions; +// import 'package:flutter_libmonero/git_versions.dart' as monero_versions; import 'package:http/http.dart'; import 'package:lelantus/git_versions.dart' as firo_versions; @@ -20,7 +20,7 @@ enum CommitStatus { isHead, isOldCommit, notACommit, notLoaded } abstract class GitStatus { static String get firoCommit => firo_versions.getPluginVersion(); static String get epicCashCommit => epic_versions.getPluginVersion(); - static String get moneroCommit => monero_versions.getPluginVersion(); + // static String get moneroCommit => monero_versions.getPluginVersion(); static String get appCommitHash => AppConfig.commitHash; @@ -78,31 +78,31 @@ abstract class GitStatus { return _cachedEpicStatus!; } - - static CommitStatus? _cachedMoneroStatus; - static Future getMoneroCommitStatus() async { - if (_cachedMoneroStatus != null) { - return _cachedMoneroStatus!; - } - - final List results = await Future.wait([ - _doesCommitExist("cypherstack", "flutter_libmonero", moneroCommit), - _isHeadCommit("cypherstack", "flutter_libmonero", "main", moneroCommit), - ]); - - final commitExists = results[0]; - final commitIsHead = results[1]; - - if (commitExists && commitIsHead) { - _cachedMoneroStatus = CommitStatus.isHead; - } else if (commitExists) { - _cachedMoneroStatus = CommitStatus.isOldCommit; - } else { - _cachedMoneroStatus = CommitStatus.notACommit; - } - - return _cachedMoneroStatus!; - } + // + // static CommitStatus? _cachedMoneroStatus; + // static Future getMoneroCommitStatus() async { + // if (_cachedMoneroStatus != null) { + // return _cachedMoneroStatus!; + // } + // + // final List results = await Future.wait([ + // _doesCommitExist("cypherstack", "flutter_libmonero", moneroCommit), + // _isHeadCommit("cypherstack", "flutter_libmonero", "main", moneroCommit), + // ]); + // + // final commitExists = results[0]; + // final commitIsHead = results[1]; + // + // if (commitExists && commitIsHead) { + // _cachedMoneroStatus = CommitStatus.isHead; + // } else if (commitExists) { + // _cachedMoneroStatus = CommitStatus.isOldCommit; + // } else { + // _cachedMoneroStatus = CommitStatus.notACommit; + // } + // + // return _cachedMoneroStatus!; + // } static TextStyle styleForStatus(CommitStatus status, BuildContext context) { final Color color; diff --git a/lib/utilities/paynym_is_api.dart b/lib/utilities/paynym_is_api.dart index 8b42e6143..f81fc855a 100644 --- a/lib/utilities/paynym_is_api.dart +++ b/lib/utilities/paynym_is_api.dart @@ -25,7 +25,7 @@ import 'prefs.dart'; // todo: better error message parsing (from response itself?) class PaynymIsApi { - static const String baseURL = "https://paynym.is/api"; + static const String baseURL = "https://paynym.rs"; static const String version = "/v1"; HTTP client = HTTP(); @@ -35,9 +35,8 @@ class PaynymIsApi { Map body, [ Map additionalHeaders = const {}, ]) async { - final String url = baseURL + - version + - (endpoint.startsWith("/") ? endpoint : "/$endpoint"); + final String url = + "$baseURL/api$version${endpoint.startsWith("/") ? endpoint : "/$endpoint"}"; final uri = Uri.parse(url); // Calculate the body length. diff --git a/lib/utilities/test_node_connection.dart b/lib/utilities/test_node_connection.dart index e3365eda8..458e04e4d 100644 --- a/lib/utilities/test_node_connection.dart +++ b/lib/utilities/test_node_connection.dart @@ -4,11 +4,15 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:on_chain/ada/ada.dart'; +import 'package:on_chain/ada/src/provider/provider/provider.dart'; +import 'package:socks5_proxy/socks.dart'; import '../networking/http.dart'; import '../pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart'; import '../providers/global/prefs_provider.dart'; import '../services/tor_service.dart'; +import '../wallets/api/cardano/blockfrost_http_provider.dart'; import '../wallets/api/tezos/tezos_rpc_api.dart'; import '../wallets/crypto_currency/crypto_currency.dart'; import '../wallets/crypto_currency/interfaces/electrumx_currency_interface.dart'; @@ -107,7 +111,9 @@ Future testNodeConnection({ case CryptonoteCurrency(): try { - final proxyInfo = ref.read(prefsChangeNotifierProvider).useTor + final proxyInfo = ref + .read(prefsChangeNotifierProvider) + .useTor ? ref.read(pTorService).getProxyInfo() : null; @@ -180,7 +186,7 @@ Future testNodeConnection({ case Stellar(): try { testPassed = - await testStellarNodeConnection(formData.host!, formData.port!); + await testStellarNodeConnection(formData.host!, formData.port!); } catch (_) {} break; @@ -196,7 +202,9 @@ Future testNodeConnection({ "action": "version", }, ), - proxyInfo: ref.read(prefsChangeNotifierProvider).useTor + proxyInfo: ref + .read(prefsChangeNotifierProvider) + .useTor ? ref.read(pTorService).getProxyInfo() : null, ); @@ -233,6 +241,41 @@ Future testNodeConnection({ testPassed = false; } break; + + case Cardano(): + try { + final client = HttpClient(); + if (ref + .read(prefsChangeNotifierProvider) + .useTor) { + final proxyInfo = TorService.sharedInstance.getProxyInfo(); + final proxySettings = ProxySettings( + proxyInfo.host, + proxyInfo.port, + ); + SocksTCPClient.assignToHttpClient(client, [proxySettings]); + } + final blockfrostProvider = BlockforestProvider( + BlockfrostHttpProvider( + url: "${formData.host!}:${formData.port!}/api/v0", + client: client, + ), + ); + + final health = await blockfrostProvider.request( + BlockfrostRequestBackendHealthStatus(), + ); + + Logging.instance.log( + "Cardano testNodeConnection \"health=$health\"", + level: LogLevel.Info, + ); + + return health; + } catch (_) { + testPassed = false; + } + break; } return testPassed; diff --git a/lib/wallets/api/cardano/blockfrost_http_provider.dart b/lib/wallets/api/cardano/blockfrost_http_provider.dart new file mode 100644 index 000000000..bf00691a9 --- /dev/null +++ b/lib/wallets/api/cardano/blockfrost_http_provider.dart @@ -0,0 +1,53 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:cbor/simple.dart'; +import 'package:on_chain/ada/src/provider/blockfrost/core/core.dart'; +import 'package:on_chain/ada/src/provider/service/service.dart'; + +import '../../../utilities/logger.dart'; + +class BlockfrostHttpProvider implements BlockfrostServiceProvider { + BlockfrostHttpProvider({ + required this.url, + this.version = "v0", + this.projectId, + HttpClient? client, + this.defaultRequestTimeout = const Duration(seconds: 30), + }) : client = client ?? HttpClient(); + @override + final String url; + final String version; + final String? projectId; + final HttpClient client; + final Duration defaultRequestTimeout; + + @override + Future get(BlockforestRequestDetails params, + [Duration? timeout,]) async { + final response = await client.getUrl(Uri.parse(params.url(url, "api/$version"))).timeout(timeout ?? defaultRequestTimeout); + response.headers.add("Content-Type", "application/json"); + response.headers.add("Accept", "application/json"); + if (projectId != null) { + response.headers.add("project_id", projectId!); + } + final responseStream = await response.close(); + final data = json.decode(await responseStream.transform(utf8.decoder).join()); + return data; + } + + @override + Future post(BlockforestRequestDetails params, + [Duration? timeout,]) async { + final request = await client.postUrl(Uri.parse(params.url(url, "api/$version"))).timeout(timeout ?? defaultRequestTimeout); + // Need to change this for other operations than submitting transactions + request.headers.add("Content-Type", "application/cbor"); + request.headers.add("Accept", "application/json"); + if (projectId != null) { + request.headers.add("project_id", projectId!); + } + request.add(params.body as List); + final response = await request.close(); + final data = json.decode(await response.transform(utf8.decoder).join()); + return data; + } +} diff --git a/lib/wallets/crypto_currency/coins/cardano.dart b/lib/wallets/crypto_currency/coins/cardano.dart new file mode 100644 index 000000000..e9cf17c65 --- /dev/null +++ b/lib/wallets/crypto_currency/coins/cardano.dart @@ -0,0 +1,126 @@ +import '../../../models/isar/models/blockchain_data/address.dart'; +import '../../../models/node_model.dart'; +import '../../../utilities/default_nodes.dart'; +import '../../../utilities/enums/derive_path_type_enum.dart'; +import '../crypto_currency.dart'; +import '../intermediate/bip39_currency.dart'; + +class Cardano extends Bip39Currency { + Cardano(super.network) { + _idMain = "cardano"; + _uriScheme = "cardano"; + switch (network) { + case CryptoCurrencyNetwork.main: + _id = _idMain; + _name = "Cardano"; + _ticker = "ADA"; + default: + throw Exception("Unsupported network: $network"); + } + } + + late final String _id; + + @override + String get identifier => _id; + + late final String _idMain; + + @override + String get mainNetId => _idMain; + + late final String _name; + + @override + String get prettyName => _name; + + late final String _uriScheme; + + @override + String get uriScheme => _uriScheme; + + late final String _ticker; + + @override + String get ticker => _ticker; + + @override + AddressType get defaultAddressType => AddressType.cardanoShelley; + + @override + Uri defaultBlockExplorer(String txid) { + switch (network) { + case CryptoCurrencyNetwork.main: + return Uri.parse( + "https://explorer.cardano.org/en/transaction?id=$txid"); + default: + throw Exception( + "Unsupported network for defaultBlockExplorer(): $network", + ); + } + } + + @override + DerivePathType get defaultDerivePathType => DerivePathType.cardanoShelley; + + @override + NodeModel get defaultNode { + switch (network) { + case CryptoCurrencyNetwork.main: + return NodeModel( + host: "https://cardano.stackwallet.com", + port: 443, + name: DefaultNodes.defaultName, + id: DefaultNodes.buildId(this), + useSSL: true, + enabled: true, + coinName: identifier, + isFailover: true, + isDown: false, + ); + + default: + throw Exception("Unsupported network: $network"); + } + } + + @override + int get defaultSeedPhraseLength => 15; + + @override + int get fractionDigits => 6; + + @override + String get genesisHash => "f0f7892b5c333cffc4b3c4344de48af4cc63f55e44936196f365a9ef2244134f"; + + @override + bool get hasBuySupport => false; + + @override + bool get hasMnemonicPassphraseSupport => false; + + @override + int get minConfirms => 2; + + @override + List get possibleMnemonicLengths => [defaultSeedPhraseLength]; + + @override + BigInt get satsPerCoin => BigInt.from(1000000); + + @override + int get targetBlockTimeSeconds => 20; + + @override + bool get torSupport => true; + + @override + bool validateAddress(String address) { + switch (network) { + case CryptoCurrencyNetwork.main: + return RegExp(r"^addr1[0-9a-zA-Z]{98}$").hasMatch(address); + default: + throw Exception("Unsupported network: $network"); + } + } +} diff --git a/lib/wallets/crypto_currency/coins/monero.dart b/lib/wallets/crypto_currency/coins/monero.dart index edd389ec3..fba0e1701 100644 --- a/lib/wallets/crypto_currency/coins/monero.dart +++ b/lib/wallets/crypto_currency/coins/monero.dart @@ -1,4 +1,5 @@ -import 'package:monero/monero.dart' as monero; +import 'package:cs_monero/src/ffi_bindings/monero_wallet_bindings.dart' + as xmr_wallet_ffi; import '../../../models/node_model.dart'; import '../../../utilities/default_nodes.dart'; @@ -50,7 +51,7 @@ class Monero extends CryptonoteCurrency { bool validateAddress(String address) { switch (network) { case CryptoCurrencyNetwork.main: - return monero.Wallet_addressValid(address, 0); + return xmr_wallet_ffi.validateAddress(address, 0); default: throw Exception("Unsupported network: $network"); } diff --git a/lib/wallets/crypto_currency/coins/wownero.dart b/lib/wallets/crypto_currency/coins/wownero.dart index 8624ecb75..ed3f18c3d 100644 --- a/lib/wallets/crypto_currency/coins/wownero.dart +++ b/lib/wallets/crypto_currency/coins/wownero.dart @@ -1,4 +1,5 @@ -import 'package:cw_wownero/api/wallet.dart' as wownero_wallet; +import 'package:cs_monero/src/ffi_bindings/wownero_wallet_bindings.dart' + as wow_wallet_ffi; import '../../../models/node_model.dart'; import '../../../utilities/default_nodes.dart'; @@ -48,7 +49,12 @@ class Wownero extends CryptonoteCurrency { @override bool validateAddress(String address) { - return wownero_wallet.addressValid(address); + switch (network) { + case CryptoCurrencyNetwork.main: + return wow_wallet_ffi.validateAddress(address, 0); + default: + throw Exception("Unsupported network: $network"); + } } @override @@ -86,7 +92,7 @@ class Wownero extends CryptonoteCurrency { bool get hasMnemonicPassphraseSupport => false; @override - List get possibleMnemonicLengths => [defaultSeedPhraseLength, 25]; + List get possibleMnemonicLengths => [defaultSeedPhraseLength, 16, 25]; @override BigInt get satsPerCoin => BigInt.from(100000000000); diff --git a/lib/wallets/crypto_currency/crypto_currency.dart b/lib/wallets/crypto_currency/crypto_currency.dart index 788c87b4f..074536be6 100644 --- a/lib/wallets/crypto_currency/crypto_currency.dart +++ b/lib/wallets/crypto_currency/crypto_currency.dart @@ -6,6 +6,7 @@ export 'coins/banano.dart'; export 'coins/bitcoin.dart'; export 'coins/bitcoin_frost.dart'; export 'coins/bitcoincash.dart'; +export 'coins/cardano.dart'; export 'coins/dash.dart'; export 'coins/dogecoin.dart'; export 'coins/ecash.dart'; diff --git a/lib/wallets/crypto_currency/interfaces/view_only_option_currency_interface.dart b/lib/wallets/crypto_currency/interfaces/view_only_option_currency_interface.dart new file mode 100644 index 000000000..dec5c016b --- /dev/null +++ b/lib/wallets/crypto_currency/interfaces/view_only_option_currency_interface.dart @@ -0,0 +1,5 @@ +import '../crypto_currency.dart'; + +mixin ViewOnlyOptionCurrencyInterface on CryptoCurrency { + // +} diff --git a/lib/wallets/crypto_currency/intermediate/bip39_hd_currency.dart b/lib/wallets/crypto_currency/intermediate/bip39_hd_currency.dart index bb97b6754..44b2f79e2 100644 --- a/lib/wallets/crypto_currency/intermediate/bip39_hd_currency.dart +++ b/lib/wallets/crypto_currency/intermediate/bip39_hd_currency.dart @@ -5,9 +5,11 @@ import 'package:flutter/foundation.dart'; import '../../../models/isar/models/blockchain_data/address.dart'; import '../../../utilities/amount/amount.dart'; import '../../../utilities/enums/derive_path_type_enum.dart'; +import '../interfaces/view_only_option_currency_interface.dart'; import 'bip39_currency.dart'; -abstract class Bip39HDCurrency extends Bip39Currency { +abstract class Bip39HDCurrency extends Bip39Currency + implements ViewOnlyOptionCurrencyInterface { Bip39HDCurrency(super.network); coinlib.Network get networkParams; @@ -39,6 +41,25 @@ abstract class Bip39HDCurrency extends Bip39Currency { } } + List get supportedHardenedDerivationPaths { + final paths = supportedDerivationPathTypes.map( + (e) => ( + path: e, + addressType: e.getAddressType(), + ), + ); + + return paths.map((e) { + final path = constructDerivePath( + derivePathType: e.path, + chain: 0, + index: 0, + ); + // trim unhardened + return path.substring(0, path.lastIndexOf("'") + 1); + }).toList(); + } + static String convertBytesToScriptHash(Uint8List bytes) { final hash = sha256.convert(bytes.toList(growable: false)).toString(); diff --git a/lib/wallets/crypto_currency/intermediate/cryptonote_currency.dart b/lib/wallets/crypto_currency/intermediate/cryptonote_currency.dart index 496336235..319a501ac 100644 --- a/lib/wallets/crypto_currency/intermediate/cryptonote_currency.dart +++ b/lib/wallets/crypto_currency/intermediate/cryptonote_currency.dart @@ -1,7 +1,9 @@ import '../../../models/isar/models/blockchain_data/address.dart'; import '../crypto_currency.dart'; +import '../interfaces/view_only_option_currency_interface.dart'; -abstract class CryptonoteCurrency extends CryptoCurrency { +abstract class CryptonoteCurrency extends CryptoCurrency + with ViewOnlyOptionCurrencyInterface { CryptonoteCurrency(super.network); @override diff --git a/lib/wallets/isar/models/frost_wallet_info.g.dart b/lib/wallets/isar/models/frost_wallet_info.g.dart index 6c80125e2..a2c7534d0 100644 --- a/lib/wallets/isar/models/frost_wallet_info.g.dart +++ b/lib/wallets/isar/models/frost_wallet_info.g.dart @@ -7,7 +7,7 @@ part of 'frost_wallet_info.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetFrostWalletInfoCollection on Isar { IsarCollection get frostWalletInfo => this.collection(); @@ -68,7 +68,7 @@ const FrostWalletInfoSchema = CollectionSchema( getId: _frostWalletInfoGetId, getLinks: _frostWalletInfoGetLinks, attach: _frostWalletInfoAttach, - version: '3.0.5', + version: '3.1.8', ); int _frostWalletInfoEstimateSize( diff --git a/lib/wallets/isar/models/spark_coin.g.dart b/lib/wallets/isar/models/spark_coin.g.dart index 75cd92b62..717d1a2c6 100644 --- a/lib/wallets/isar/models/spark_coin.g.dart +++ b/lib/wallets/isar/models/spark_coin.g.dart @@ -7,7 +7,7 @@ part of 'spark_coin.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetSparkCoinCollection on Isar { IsarCollection get sparkCoins => this.collection(); @@ -139,7 +139,7 @@ const SparkCoinSchema = CollectionSchema( getId: _sparkCoinGetId, getLinks: _sparkCoinGetLinks, attach: _sparkCoinAttach, - version: '3.0.5', + version: '3.1.8', ); int _sparkCoinEstimateSize( diff --git a/lib/wallets/isar/models/token_wallet_info.g.dart b/lib/wallets/isar/models/token_wallet_info.g.dart index bdf6a060a..f5d8555ab 100644 --- a/lib/wallets/isar/models/token_wallet_info.g.dart +++ b/lib/wallets/isar/models/token_wallet_info.g.dart @@ -7,7 +7,7 @@ part of 'token_wallet_info.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetTokenWalletInfoCollection on Isar { IsarCollection get tokenWalletInfo => this.collection(); @@ -68,7 +68,7 @@ const TokenWalletInfoSchema = CollectionSchema( getId: _tokenWalletInfoGetId, getLinks: _tokenWalletInfoGetLinks, attach: _tokenWalletInfoAttach, - version: '3.0.5', + version: '3.1.8', ); int _tokenWalletInfoEstimateSize( diff --git a/lib/wallets/isar/models/wallet_info.dart b/lib/wallets/isar/models/wallet_info.dart index 6a7a9b54c..eb6a4e9ea 100644 --- a/lib/wallets/isar/models/wallet_info.dart +++ b/lib/wallets/isar/models/wallet_info.dart @@ -6,6 +6,7 @@ import 'package:uuid/uuid.dart'; import '../../../app_config.dart'; import '../../../models/balance.dart'; import '../../../models/isar/models/blockchain_data/address.dart'; +import '../../../models/keys/view_only_wallet_data.dart'; import '../../crypto_currency/crypto_currency.dart'; import '../isar_id_interface.dart'; import 'wallet_info_meta.dart'; @@ -117,6 +118,17 @@ class WalletInfo implements IsarId { ? {} : Map.from(jsonDecode(otherDataJsonString!) as Map); + @ignore + bool get isViewOnly => + otherData[WalletInfoKeys.isViewOnlyKey] as bool? ?? false; + + @ignore + ViewOnlyWalletType? get viewOnlyWalletType { + final index = otherData[WalletInfoKeys.viewOnlyTypeIndexKey] as int?; + if (index == null) return null; + return ViewOnlyWalletType.values[index]; + } + Future isMnemonicVerified(Isar isar) async => (await isar.walletInfoMeta.where().walletIdEqualTo(walletId).findFirst()) ?.isMnemonicVerified == @@ -512,4 +524,6 @@ abstract class WalletInfoKeys { "firoSparkCacheSetTimestampCacheKey"; static const String enableOptInRbf = "enableOptInRbfKey"; static const String reuseAddress = "reuseAddressKey"; + static const String isViewOnlyKey = "isViewOnlyKey"; + static const String viewOnlyTypeIndexKey = "viewOnlyTypeIndexKey"; } diff --git a/lib/wallets/isar/models/wallet_info.g.dart b/lib/wallets/isar/models/wallet_info.g.dart index bc0a5828e..89c5511fa 100644 --- a/lib/wallets/isar/models/wallet_info.g.dart +++ b/lib/wallets/isar/models/wallet_info.g.dart @@ -7,7 +7,7 @@ part of 'wallet_info.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetWalletInfoCollection on Isar { IsarCollection get walletInfo => this.collection(); @@ -114,7 +114,7 @@ const WalletInfoSchema = CollectionSchema( getId: _walletInfoGetId, getLinks: _walletInfoGetLinks, attach: _walletInfoAttach, - version: '3.0.5', + version: '3.1.8', ); int _walletInfoEstimateSize( diff --git a/lib/wallets/isar/models/wallet_info_meta.dart b/lib/wallets/isar/models/wallet_info_meta.dart index 62d37b7d4..ce0820a1a 100644 --- a/lib/wallets/isar/models/wallet_info_meta.dart +++ b/lib/wallets/isar/models/wallet_info_meta.dart @@ -1,4 +1,5 @@ import 'package:isar/isar.dart'; + import '../isar_id_interface.dart'; part 'wallet_info_meta.g.dart'; diff --git a/lib/wallets/isar/models/wallet_info_meta.g.dart b/lib/wallets/isar/models/wallet_info_meta.g.dart index 619bc1ac5..d8f578929 100644 --- a/lib/wallets/isar/models/wallet_info_meta.g.dart +++ b/lib/wallets/isar/models/wallet_info_meta.g.dart @@ -7,7 +7,7 @@ part of 'wallet_info_meta.dart'; // ************************************************************************** // 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 +// 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, always_specify_types extension GetWalletInfoMetaCollection on Isar { IsarCollection get walletInfoMeta => this.collection(); @@ -53,7 +53,7 @@ const WalletInfoMetaSchema = CollectionSchema( getId: _walletInfoMetaGetId, getLinks: _walletInfoMetaGetLinks, attach: _walletInfoMetaAttach, - version: '3.0.5', + version: '3.1.8', ); int _walletInfoMetaEstimateSize( diff --git a/lib/wallets/models/tx_data.dart b/lib/wallets/models/tx_data.dart index 99a28a138..652a5605f 100644 --- a/lib/wallets/models/tx_data.dart +++ b/lib/wallets/models/tx_data.dart @@ -1,5 +1,4 @@ -import 'package:cw_monero/pending_monero_transaction.dart'; -import 'package:cw_wownero/pending_wownero_transaction.dart'; +import 'package:cs_monero/cs_monero.dart' as lib_monero; import 'package:tezart/tezart.dart' as tezart; import 'package:web3dart/web3dart.dart' as web3dart; @@ -49,11 +48,8 @@ class TxData { final BigInt? chainId; final BigInt? feeInWei; - // wownero specific - final PendingWowneroTransaction? pendingWowneroTransaction; - - // monero specific - final PendingMoneroTransaction? pendingMoneroTransaction; + // wownero and monero specific + final lib_monero.PendingTransaction? pendingTransaction; // firo lelantus specific final int? jMintValue; @@ -104,8 +100,7 @@ class TxData { this.nonce, this.chainId, this.feeInWei, - this.pendingWowneroTransaction, - this.pendingMoneroTransaction, + this.pendingTransaction, this.jMintValue, this.spendCoinIndexes, this.height, @@ -120,11 +115,27 @@ class TxData { this.ignoreCachedBalanceChecks = false, }); - Amount? get amount => recipients != null && recipients!.isNotEmpty - ? recipients! + Amount? get amount { + if (recipients != null && recipients!.isNotEmpty) { + final sum = recipients! .map((e) => e.amount) - .reduce((total, amount) => total += amount) - : null; + .reduce((total, amount) => total += amount); + + // special xmr/wow check + if (pendingTransaction?.amount != null && fee != null) { + if (pendingTransaction!.amount + fee!.raw == sum.raw) { + return Amount( + rawValue: pendingTransaction!.amount, + fractionDigits: recipients!.first.amount.fractionDigits, + ); + } + } + + return sum; + } + + return null; + } Amount? get amountSpark => sparkRecipients != null && sparkRecipients!.isNotEmpty @@ -141,10 +152,22 @@ class TxData { fractionDigits: recipients!.first.amount.fractionDigits, ); } else { - return recipients! + final sum = recipients! .where((e) => !e.isChange) .map((e) => e.amount) .reduce((total, amount) => total += amount); + + // special xmr/wow check + if (pendingTransaction?.amount != null && fee != null) { + if (pendingTransaction!.amount + fee!.raw == sum.raw) { + return Amount( + rawValue: pendingTransaction!.amount, + fractionDigits: recipients!.first.amount.fractionDigits, + ); + } + } + + return sum; } } else { return null; @@ -196,8 +219,7 @@ class TxData { int? nonce, BigInt? chainId, BigInt? feeInWei, - PendingWowneroTransaction? pendingWowneroTransaction, - PendingMoneroTransaction? pendingMoneroTransaction, + lib_monero.PendingTransaction? pendingTransaction, int? jMintValue, List? spendCoinIndexes, int? height, @@ -241,10 +263,7 @@ class TxData { nonce: nonce ?? this.nonce, chainId: chainId ?? this.chainId, feeInWei: feeInWei ?? this.feeInWei, - pendingWowneroTransaction: - pendingWowneroTransaction ?? this.pendingWowneroTransaction, - pendingMoneroTransaction: - pendingMoneroTransaction ?? this.pendingMoneroTransaction, + pendingTransaction: pendingTransaction ?? this.pendingTransaction, jMintValue: jMintValue ?? this.jMintValue, spendCoinIndexes: spendCoinIndexes ?? this.spendCoinIndexes, height: height ?? this.height, @@ -284,8 +303,7 @@ class TxData { 'nonce: $nonce, ' 'chainId: $chainId, ' 'feeInWei: $feeInWei, ' - 'pendingWowneroTransaction: $pendingWowneroTransaction, ' - 'pendingMoneroTransaction: $pendingMoneroTransaction, ' + 'pendingTransaction: $pendingTransaction, ' 'jMintValue: $jMintValue, ' 'spendCoinIndexes: $spendCoinIndexes, ' 'height: $height, ' diff --git a/lib/wallets/wallet/impl/bitcoin_frost_wallet.dart b/lib/wallets/wallet/impl/bitcoin_frost_wallet.dart index 24a690b2a..462dacbde 100644 --- a/lib/wallets/wallet/impl/bitcoin_frost_wallet.dart +++ b/lib/wallets/wallet/impl/bitcoin_frost_wallet.dart @@ -32,6 +32,8 @@ import '../../models/tx_data.dart'; import '../wallet.dart'; import '../wallet_mixin_interfaces/multi_address_interface.dart'; +const kFrostSecureStartingIndex = 1; + class BitcoinFrostWallet extends Wallet with MultiAddressInterface { BitcoinFrostWallet(CryptoCurrencyNetwork network) @@ -85,8 +87,9 @@ class BitcoinFrostWallet extends Wallet final address = await _generateAddress( change: 0, - index: 0, + index: kFrostSecureStartingIndex, serializedKeys: serializedKeys, + secure: true, ); await mainDB.putAddresses([address]); @@ -198,6 +201,7 @@ class BitcoinFrostWallet extends Wallet outputs: txData.recipients!, changeAddress: changeAddress!.value, feePerWeight: feePerWeight, + serializedKeys: (await getSerializedKeys())!, ); } on FrostdartException catch (e) { if (e.errorCode == NOT_ENOUGH_FUNDS_ERROR && @@ -375,6 +379,14 @@ class BitcoinFrostWallet extends Wallet property: r"subType", value: AddressSubType.change, ), + const FilterCondition.equalTo( + property: r"zSafeFrost", + value: true, + ), + const FilterCondition.greaterThan( + property: r"derivationIndex", + value: 0, + ), ], ); @@ -389,6 +401,14 @@ class BitcoinFrostWallet extends Wallet property: r"subType", value: AddressSubType.receiving, ), + const FilterCondition.equalTo( + property: r"zSafeFrost", + value: true, + ), + const FilterCondition.greaterThan( + property: r"derivationIndex", + value: 0, + ), ], ); @@ -618,13 +638,30 @@ class BitcoinFrostWallet extends Wallet if (address == null) { final serializedKeys = await getSerializedKeys(); if (serializedKeys != null) { - final address = await _generateAddress( - change: 0, - index: 0, - serializedKeys: serializedKeys, - ); + int index = kFrostSecureStartingIndex; + const someSaneMaximum = 200; + Address? address; + while (index < someSaneMaximum) { + try { + address = await _generateAddress( + change: 0, + index: index, + serializedKeys: serializedKeys, + secure: true, + ); - await mainDB.updateOrPutAddresses([address]); + await mainDB.updateOrPutAddresses([address]); + } catch (_) {} + if (address != null) { + break; + } + index++; + } + + if (index >= someSaneMaximum) { + throw Exception( + "index < kFrostSecureStartingIndex hit someSaneMaximum"); + } } else { Logging.instance.log( "$runtimeType.checkSaveInitialReceivingAddress() failed due" @@ -818,6 +855,7 @@ class BitcoinFrostWallet extends Wallet _checkGapsLinearly( serializedKeys, receiveChain, + secure: true, ), ]; final List addresses})>> @@ -825,6 +863,7 @@ class BitcoinFrostWallet extends Wallet _checkGapsLinearly( serializedKeys, changeChain, + secure: true, ), ]; @@ -881,6 +920,8 @@ class BitcoinFrostWallet extends Wallet ); await mainDB.updateOrPutAddresses(addressesToStore); + + await _legacyInsecureScan(serializedKeys); }); GlobalEventBus.instance.fire( @@ -908,6 +949,80 @@ class BitcoinFrostWallet extends Wallet } } + // for legacy support secure is set to false to see + // funds received on insecure addresses + Future _legacyInsecureScan(String serializedKeys) async { + const receiveChain = 0; + const changeChain = 1; + + final List addresses})>> receiveFutures = + [ + _checkGapsLinearly( + serializedKeys, + receiveChain, + secure: false, + ), + ]; + final List addresses})>> changeFutures = [ + // for legacy support secure is set to false to see + // funds received on insecure addresses + _checkGapsLinearly( + serializedKeys, + changeChain, + secure: false, + ), + ]; + + // io limitations may require running these linearly instead + final futuresResult = await Future.wait([ + Future.wait(receiveFutures), + Future.wait(changeFutures), + ]); + + final receiveResults = futuresResult[0]; + final changeResults = futuresResult[1]; + + final List

addressesToStore = []; + + int highestReceivingIndexWithHistory = 0; + for (final tuple in receiveResults) { + if (tuple.addresses.isNotEmpty) { + highestReceivingIndexWithHistory = max( + tuple.index, + highestReceivingIndexWithHistory, + ); + addressesToStore.addAll(tuple.addresses); + } + } + + int highestChangeIndexWithHistory = 0; + for (final tuple in changeResults) { + if (tuple.addresses.isNotEmpty) { + highestChangeIndexWithHistory = max( + tuple.index, + highestChangeIndexWithHistory, + ); + addressesToStore.addAll(tuple.addresses); + } + } + + // remove extra addresses to help minimize risk of creating a large gap + addressesToStore.removeWhere( + (e) => + e.subType == AddressSubType.change && + e.derivationIndex > highestChangeIndexWithHistory, + ); + addressesToStore.removeWhere( + (e) => + e.subType == AddressSubType.receiving && + e.derivationIndex > highestReceivingIndexWithHistory, + ); + + if (addressesToStore.isNotEmpty) { + await mainDB.updateOrPutAddresses(addressesToStore); + } + } + @override Future updateBalance() async { final utxos = await mainDB.getUTXOs(walletId).findAll(); @@ -1394,7 +1509,9 @@ class BitcoinFrostWallet extends Wallet @override Future generateNewChangeAddress() async { final current = await getCurrentChangeAddress(); - int index = current == null ? 0 : current.derivationIndex + 1; + int index = current == null + ? kFrostSecureStartingIndex + : current.derivationIndex + 1; const chain = 1; // change address final serializedKeys = (await getSerializedKeys())!; @@ -1406,6 +1523,7 @@ class BitcoinFrostWallet extends Wallet change: chain, index: index, serializedKeys: serializedKeys, + secure: true, ); } on FrostdartException catch (e) { if (e.errorCode == 72) { @@ -1424,7 +1542,9 @@ class BitcoinFrostWallet extends Wallet @override Future generateNewReceivingAddress() async { final current = await getCurrentReceivingAddress(); - int index = current == null ? 0 : current.derivationIndex + 1; + int index = current == null + ? kFrostSecureStartingIndex + : current.derivationIndex + 1; const chain = 0; // receiving address final serializedKeys = (await getSerializedKeys())!; @@ -1436,6 +1556,7 @@ class BitcoinFrostWallet extends Wallet change: chain, index: index, serializedKeys: serializedKeys, + secure: true, ); } on FrostdartException catch (e) { if (e.errorCode == 72) { @@ -1532,6 +1653,7 @@ class BitcoinFrostWallet extends Wallet change: chain, index: startingIndex, serializedKeys: serializedKeys, + secure: true, ); } on FrostdartException catch (e) { if (e.errorCode == 72) { @@ -1554,6 +1676,7 @@ class BitcoinFrostWallet extends Wallet required int change, required int index, required String serializedKeys, + required bool secure, }) async { final addressDerivationData = ( account: account, @@ -1569,6 +1692,7 @@ class BitcoinFrostWallet extends Wallet : Network.Testnet, keys: keys, addressDerivationData: addressDerivationData, + secure: secure, ); return Address( @@ -1583,16 +1707,18 @@ class BitcoinFrostWallet extends Wallet ? AddressSubType.change : AddressSubType.unknown, type: AddressType.frostMS, + zSafeFrost: secure && index >= kFrostSecureStartingIndex, ); } Future<({List
addresses, int index})> _checkGapsLinearly( String serializedKeys, - int chain, - ) async { + int chain, { + required bool secure, + }) async { final List
addressArray = []; int gapCounter = 0; - int index = 0; + int index = secure ? kFrostSecureStartingIndex : 0; for (; gapCounter < 20; index++) { Logging.instance.log( "Frost index: $index, \t GapCounter chain=$chain: $gapCounter", @@ -1606,6 +1732,7 @@ class BitcoinFrostWallet extends Wallet change: chain, index: index, serializedKeys: serializedKeys, + secure: secure, ); } on FrostdartException catch (e) { if (e.errorCode == 72) { @@ -1620,13 +1747,13 @@ class BitcoinFrostWallet extends Wallet // get address tx count final count = await _fetchTxCount( - address: address!, + address: address, ); // check and add appropriate addresses if (count > 0) { // add address to array - addressArray.add(address!); + addressArray.add(address); // reset counter gapCounter = 0; // add info to derivations diff --git a/lib/wallets/wallet/impl/cardano_wallet.dart b/lib/wallets/wallet/impl/cardano_wallet.dart new file mode 100644 index 000000000..bf3abfd31 --- /dev/null +++ b/lib/wallets/wallet/impl/cardano_wallet.dart @@ -0,0 +1,567 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:blockchain_utils/bip/bip/bip44/base/bip44_base.dart'; +import 'package:blockchain_utils/bip/cardano/bip32/cardano_icarus_bip32.dart'; +import 'package:blockchain_utils/bip/cardano/cip1852/cip1852.dart'; +import 'package:blockchain_utils/bip/cardano/cip1852/conf/cip1852_coins.dart'; +import 'package:blockchain_utils/bip/cardano/mnemonic/cardano_icarus_seed_generator.dart'; +import 'package:blockchain_utils/bip/cardano/shelley/cardano_shelley.dart'; +import 'package:on_chain/ada/ada.dart'; +import 'package:socks5_proxy/socks.dart'; +import '../../../models/balance.dart'; +import '../../../models/isar/models/blockchain_data/address.dart'; +import 'package:tuple/tuple.dart'; +import '../../../models/isar/models/blockchain_data/transaction.dart' as isar; +import '../../../models/paymint/fee_object_model.dart'; +import '../../../networking/http.dart'; +import '../../../services/tor_service.dart'; +import '../../../utilities/amount/amount.dart'; +import 'package:isar/isar.dart'; +import '../../../utilities/logger.dart'; +import '../../../utilities/prefs.dart'; +import '../../api/cardano/blockfrost_http_provider.dart'; +import '../../crypto_currency/crypto_currency.dart'; +import '../../models/tx_data.dart'; +import '../intermediate/bip39_wallet.dart'; + +class CardanoWallet extends Bip39Wallet { + CardanoWallet(CryptoCurrencyNetwork network) : super(Cardano(network)); + + // Source: https://cips.cardano.org/cip/CIP-1852 + static const String _addressDerivationPath = "m/1852'/1815'/0'/0/0"; + static final HTTP _httpClient = HTTP(); + + BlockforestProvider? blockfrostProvider; + + @override + FilterOperation? get changeAddressFilterOperation => null; + + @override + FilterOperation? get receivingAddressFilterOperation => null; + + Future
_getAddress() async { + final mnemonic = await getMnemonic(); + final seed = CardanoIcarusSeedGenerator(mnemonic).generate(); + final cip1852 = Cip1852.fromSeed(seed, Cip1852Coins.cardanoIcarus); + final derivationAccount = cip1852.purpose.coin.account(0); + final shelley = CardanoShelley.fromCip1852Object(derivationAccount) + .change(Bip44Changes.chainExt) + .addressIndex(0); + final paymentPublicKey = shelley.bip44.publicKey.compressed; + final stakePublicKey = shelley.bip44Sk.publicKey.compressed; + final addressStr = ADABaseAddress.fromPublicKey( + basePubkeyBytes: paymentPublicKey, + stakePubkeyBytes: stakePublicKey, + ).address; + return Address( + walletId: walletId, + value: addressStr, + publicKey: paymentPublicKey, + derivationIndex: 0, + derivationPath: DerivationPath()..value = _addressDerivationPath, + type: AddressType.cardanoShelley, + subType: AddressSubType.receiving, + ); + } + + @override + Future checkSaveInitialReceivingAddress() async { + try { + final Address? address = await getCurrentReceivingAddress(); + + if (address == null) { + final address = await _getAddress(); + + await mainDB.updateOrPutAddresses([address]); + } + } catch (e, s) { + Logging.instance.log( + "$runtimeType checkSaveInitialReceivingAddress() failed: $e\n$s", + level: LogLevel.Error, + ); + } + } + + @override + Future pingCheck() async { + try { + await updateProvider(); + + final health = await blockfrostProvider!.request( + BlockfrostRequestBackendHealthStatus(), + ); + + return Future.value(health); + } catch (e, s) { + Logging.instance.log( + "Error ping checking in cardano_wallet.dart: $e\n$s", + level: LogLevel.Error, + ); + return Future.value(false); + } + } + + @override + Future estimateFeeFor(Amount amount, int feeRate) async { + await updateProvider(); + + if (info.cachedBalance.spendable.raw == BigInt.zero) { + return Amount( + rawValue: BigInt.zero, + fractionDigits: cryptoCurrency.fractionDigits, + ); + } + + final params = await blockfrostProvider!.request( + BlockfrostRequestLatestEpochProtocolParameters(), + ); + + final fee = params.calculateFee(284); + + return Amount( + rawValue: fee, + fractionDigits: cryptoCurrency.fractionDigits, + ); + } + + @override + Future get fees async { + try { + await updateProvider(); + + final params = await blockfrostProvider!.request( + BlockfrostRequestLatestEpochProtocolParameters(), + ); + + // 284 is the size of a basic transaction with one input and two outputs (change and recipient) + final fee = params.calculateFee(284).toInt(); + + return FeeObject( + numberOfBlocksFast: 2, + numberOfBlocksAverage: 2, + numberOfBlocksSlow: 2, + fast: fee, + medium: fee, + slow: fee, + ); + } catch (e, s) { + Logging.instance.log( + "Error getting fees in cardano_wallet.dart: $e\n$s", + level: LogLevel.Error, + ); + rethrow; + } + } + + @override + Future prepareSend({required TxData txData}) async { + try { + await updateProvider(); + + if (txData.amount!.raw < ADAHelper.toLovelaces("1")) { + throw Exception("By network rules, you can send minimum 1 ADA"); + } + + final utxos = await blockfrostProvider!.request( + BlockfrostRequestAddressUTXOsOfAGivenAsset( + address: ADAAddress.fromAddress( + (await getCurrentReceivingAddress())!.value, + ), + asset: "lovelace", + ), + ); + + var leftAmountForUtxos = txData.amount!.raw; + final listOfUtxosToBeUsed = []; + var totalBalance = BigInt.zero; + + for (final utxo in utxos) { + if (!(leftAmountForUtxos <= BigInt.parse("0"))) { + leftAmountForUtxos -= BigInt.parse(utxo.amount.first.quantity); + listOfUtxosToBeUsed.add(utxo); + } + totalBalance += BigInt.parse(utxo.amount.first.quantity); + } + + if (leftAmountForUtxos > BigInt.parse("0") || totalBalance < txData.amount!.raw) { + throw Exception("Insufficient balance"); + } + + final bip32 = CardanoIcarusBip32.fromSeed(CardanoIcarusSeedGenerator(await getMnemonic()).generate()); + final spend = bip32.derivePath("1852'/1815'/0'/0/0"); + final privateKey = AdaPrivateKey.fromBytes(spend.privateKey.raw); + + // Calculate fees with example tx + final exampleFee = ADAHelper.toLovelaces("0.10"); + final change = TransactionOutput(address: ADABaseAddress((await getCurrentReceivingAddress())!.value), amount: Value(coin: totalBalance - (txData.amount!.raw))); + final body = TransactionBody( + inputs: listOfUtxosToBeUsed.map((e) => TransactionInput(transactionId: TransactionHash.fromHex(e.txHash), index: e.outputIndex)).toList(), + outputs: [change, TransactionOutput(address: ADABaseAddress(txData.recipients!.first.address), amount: Value(coin: txData.amount!.raw - exampleFee))], + fee: exampleFee, + ); + final exampleTx = ADATransaction( + body: body, + witnessSet: TransactionWitnessSet(vKeys: [ + privateKey.createSignatureWitness(body.toHash().data), + ],) + ,); + final params = await blockfrostProvider!.request(BlockfrostRequestLatestEpochProtocolParameters()); + final fee = params.calculateFee(exampleTx.size); + + // Check if we are sending all balance, which means no change and only one output for recipient. + if (totalBalance == txData.amount!.raw) { + final List newRecipients = [( + address: txData.recipients!.first.address, + amount: Amount( + rawValue: txData.amount!.raw - fee, + fractionDigits: cryptoCurrency.fractionDigits, + ), + isChange: txData.recipients!.first.isChange, + ),]; + return txData.copyWith( + fee: Amount( + rawValue: fee, + fractionDigits: cryptoCurrency.fractionDigits, + ), + recipients: newRecipients, + ); + } else { + if (txData.amount!.raw + fee > totalBalance) { + throw Exception("Insufficient balance for fee"); + } + + // Minimum change in Cardano is 1 ADA and we need to have enough balance for that + if (totalBalance - (txData.amount!.raw + fee) < ADAHelper.toLovelaces("1")) { + throw Exception("Not enough balance for change. By network rules, please either send all balance or leave at least 1 ADA change."); + } + + return txData.copyWith( + fee: Amount( + rawValue: fee, + fractionDigits: cryptoCurrency.fractionDigits, + ), + ); + } + } catch (e, s) { + Logging.instance.log( + "$runtimeType Cardano prepareSend failed: $e\n$s", + level: LogLevel.Error, + ); + rethrow; + } + } + + @override + Future confirmSend({required TxData txData}) async { + try { + await updateProvider(); + + final utxos = await blockfrostProvider!.request( + BlockfrostRequestAddressUTXOsOfAGivenAsset( + address: ADAAddress.fromAddress( + (await getCurrentReceivingAddress())!.value, + ), + asset: "lovelace", + ), + ); + + + var leftAmountForUtxos = txData.amount!.raw + txData.fee!.raw; + final listOfUtxosToBeUsed = []; + var totalBalance = BigInt.zero; + + for (final utxo in utxos) { + if (!(leftAmountForUtxos <= BigInt.parse("0"))) { + leftAmountForUtxos -= BigInt.parse(utxo.amount.first.quantity); + listOfUtxosToBeUsed.add(utxo); + } + totalBalance += BigInt.parse(utxo.amount.first.quantity); + } + + var totalUtxoAmount = BigInt.zero; + + for (final utxo in listOfUtxosToBeUsed) { + totalUtxoAmount += BigInt.parse(utxo.amount.first.quantity); + } + + final bip32 = CardanoIcarusBip32.fromSeed(CardanoIcarusSeedGenerator(await getMnemonic()).generate()); + final spend = bip32.derivePath("1852'/1815'/0'/0/0"); + final privateKey = AdaPrivateKey.fromBytes(spend.privateKey.raw); + + final change = TransactionOutput(address: ADABaseAddress((await getCurrentReceivingAddress())!.value), amount: Value(coin: totalUtxoAmount - (txData.amount!.raw + txData.fee!.raw))); + List outputs = []; + if (totalBalance == (txData.amount!.raw + txData.fee!.raw)) { + outputs = [TransactionOutput(address: ADABaseAddress(txData.recipients!.first.address), amount: Value(coin: txData.amount!.raw))]; + } else { + outputs = [change, TransactionOutput(address: ADABaseAddress(txData.recipients!.first.address), amount: Value(coin: txData.amount!.raw))]; + } + final body = TransactionBody( + inputs: listOfUtxosToBeUsed.map((e) => TransactionInput(transactionId: TransactionHash.fromHex(e.txHash), index: e.outputIndex)).toList(), + outputs: outputs, + fee: txData.fee!.raw, + ); + final tx = ADATransaction( + body: body, + witnessSet: TransactionWitnessSet(vKeys: [ + privateKey.createSignatureWitness(body.toHash().data), + ],) + ,); + + final sentTx = await blockfrostProvider!.request(BlockfrostRequestSubmitTransaction( + transactionCborBytes: tx.serialize(),),); + return txData.copyWith( + txid: sentTx, + ); + } catch (e, s) { + Logging.instance.log( + "$runtimeType Cardano confirmSend failed: $e\n$s", + level: LogLevel.Error, + ); + rethrow; + } + } + + @override + Future recover({required bool isRescan}) async { + await refreshMutex.protect(() async { + final addressStruct = await _getAddress(); + + await mainDB.updateOrPutAddresses([addressStruct]); + + if (info.cachedReceivingAddress != addressStruct.value) { + await info.updateReceivingAddress( + newAddress: addressStruct.value, + isar: mainDB.isar, + ); + } + + await Future.wait([ + updateBalance(), + updateChainHeight(), + updateTransactions(), + ]); + }); + } + + @override + Future updateBalance() async { + try { + await updateProvider(); + + final addressUtxos = await blockfrostProvider!.request( + BlockfrostRequestAddressUTXOsOfAGivenAsset( + address: ADAAddress.fromAddress( + (await getCurrentReceivingAddress())!.value, + ), + asset: "lovelace", + ), + ); + + BigInt totalBalanceInLovelace = BigInt.parse("0"); + for (final utxo in addressUtxos) { + totalBalanceInLovelace += BigInt.parse(utxo.amount.first.quantity); + } + + final balance = Balance( + total: Amount( + rawValue: totalBalanceInLovelace, + fractionDigits: cryptoCurrency.fractionDigits,), + spendable: Amount( + rawValue: totalBalanceInLovelace, + fractionDigits: cryptoCurrency.fractionDigits,), + blockedTotal: Amount( + rawValue: BigInt.zero, + fractionDigits: cryptoCurrency.fractionDigits, + ), + pendingSpendable: Amount( + rawValue: BigInt.zero, + fractionDigits: cryptoCurrency.fractionDigits, + ), + ); + + await info.updateBalance(newBalance: balance, isar: mainDB.isar); + } catch (e, s) { + Logging.instance.log( + "Error getting balance in cardano_wallet.dart: $e\n$s", + level: LogLevel.Error, + ); + } + } + + @override + Future updateChainHeight() async { + try { + await updateProvider(); + + final latestBlock = await blockfrostProvider!.request( + BlockfrostRequestLatestBlock(), + ); + + await info.updateCachedChainHeight( + newHeight: latestBlock.height == null ? 0 : latestBlock.height!, + isar: mainDB.isar,); + } catch (e, s) { + Logging.instance.log( + "Error updating transactions in cardano_wallet.dart: $e\n$s", + level: LogLevel.Error, + ); + } + } + + @override + Future updateNode() async { + await refresh(); + } + + @override + Future updateTransactions() async { + try { + await updateProvider(); + + final currentAddr = (await getCurrentReceivingAddress())!.value; + + final txsList = await blockfrostProvider!.request( + BlockfrostRequestAddressTransactions( + ADAAddress.fromAddress( + currentAddr, + ), + ), + ); + + final parsedTxsList = + List>.empty(growable: true); + + for (final tx in txsList) { + final txInfo = await blockfrostProvider!.request( + BlockfrostRequestSpecificTransaction(tx.txHash), + ); + final utxoInfo = await blockfrostProvider!.request( + BlockfrostRequestTransactionUTXOs(tx.txHash), + ); + var txType = isar.TransactionType.unknown; + + for (final input in utxoInfo.inputs) { + if (input.address == currentAddr) { + txType = isar.TransactionType.outgoing; + } + } + + if (txType == isar.TransactionType.outgoing) { + var isSelfTx = true; + for (final output in utxoInfo.outputs) { + if (output.address != currentAddr) { + isSelfTx = false; + } + } + if (isSelfTx) { + txType = isar.TransactionType.sentToSelf; + } + } + + if (txType == isar.TransactionType.unknown) { + for (final output in utxoInfo.outputs) { + if (output.address == currentAddr) { + txType = isar.TransactionType.incoming; + } + } + } + + var receiverAddr = "Unknown?"; + var amount = 0; + + if (txType == isar.TransactionType.incoming) { + receiverAddr = currentAddr; + for (final output in utxoInfo.outputs) { + if (output.address == currentAddr && output.amount.first.unit == "lovelace") { + amount += int.parse(output.amount.first.quantity); + } + } + } else if (txType == isar.TransactionType.outgoing) { + for (final output in utxoInfo.outputs) { + if (output.address != currentAddr && output.amount.first.unit == "lovelace") { + receiverAddr = output.address; + amount += int.parse(output.amount.first.quantity); + } + } + } else if (txType == isar.TransactionType.sentToSelf) { + receiverAddr = currentAddr; + for (final output in utxoInfo.outputs) { + if (output.amount.first.unit == "lovelace") { + amount += int.parse(output.amount.first.quantity); + } + } + } + + final transaction = isar.Transaction( + walletId: walletId, + txid: txInfo.hash, + timestamp: tx.blockTime, + type: txType, + subType: isar.TransactionSubType.none, + amount: amount, + amountString: Amount( + rawValue: BigInt.from(amount), + fractionDigits: cryptoCurrency.fractionDigits, + ).toJsonString(), + fee: int.parse(txInfo.fees), + height: txInfo.blockHeight, + isCancelled: false, + isLelantus: false, + slateId: null, + otherData: null, + inputs: [], + outputs: [], + nonce: null, + numberOfMessages: 0, + ); + + final txAddress = Address( + walletId: walletId, + value: receiverAddr, + publicKey: List.empty(), + derivationIndex: 0, + derivationPath: DerivationPath()..value = _addressDerivationPath, + type: AddressType.cardanoShelley, + subType: txType == isar.TransactionType.outgoing + ? AddressSubType.unknown + : AddressSubType.receiving, + ); + + parsedTxsList.add(Tuple2(transaction, txAddress)); + } + + await mainDB.addNewTransactionData(parsedTxsList, walletId); + } catch (e, s) { + Logging.instance.log( + "Error updating transactions in cardano_wallet.dart: $e\n$s", + level: LogLevel.Error, + ); + } + } + + @override + Future updateUTXOs() async { + // TODO: implement updateUTXOs + return false; + } + + Future updateProvider() async { + final currentNode = getCurrentNode(); + final client = HttpClient(); + if (prefs.useTor) { + final proxyInfo = TorService.sharedInstance.getProxyInfo(); + final proxySettings = ProxySettings( + proxyInfo.host, + proxyInfo.port, + ); + SocksTCPClient.assignToHttpClient(client, [proxySettings]); + } + blockfrostProvider = BlockforestProvider( + BlockfrostHttpProvider( + url: "${currentNode.host}:${currentNode.port}/", + client: client, + ), + ); + } +} diff --git a/lib/wallets/wallet/impl/firo_wallet.dart b/lib/wallets/wallet/impl/firo_wallet.dart index f9fcb11b5..f68a83917 100644 --- a/lib/wallets/wallet/impl/firo_wallet.dart +++ b/lib/wallets/wallet/impl/firo_wallet.dart @@ -659,6 +659,11 @@ class FiroWallet extends Bip39HDWallet @override Future recover({required bool isRescan}) async { + if (isViewOnly) { + await recoverViewOnly(isRescan: isRescan); + return; + } + // reset last checked values await info.updateOtherData( newEntries: { diff --git a/lib/wallets/wallet/impl/monero_wallet.dart b/lib/wallets/wallet/impl/monero_wallet.dart index b84b557f2..bcec63851 100644 --- a/lib/wallets/wallet/impl/monero_wallet.dart +++ b/lib/wallets/wallet/impl/monero_wallet.dart @@ -1,185 +1,51 @@ import 'dart:async'; -import 'dart:io'; -import 'dart:math'; -import 'package:cw_core/monero_transaction_priority.dart'; -import 'package:cw_core/node.dart'; -import 'package:cw_core/pending_transaction.dart'; -import 'package:cw_core/sync_status.dart'; -import 'package:cw_core/transaction_direction.dart'; -import 'package:cw_core/wallet_base.dart'; -import 'package:cw_core/wallet_credentials.dart'; -import 'package:cw_core/wallet_info.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart'; -import 'package:cw_monero/monero_wallet.dart'; -import 'package:cw_monero/pending_monero_transaction.dart'; -import 'package:decimal/decimal.dart'; -import 'package:flutter_libmonero/core/wallet_creation_service.dart'; -import 'package:flutter_libmonero/monero/monero.dart' as xmr_dart; -import 'package:flutter_libmonero/view_model/send/output.dart' as monero_output; -import 'package:isar/isar.dart'; -import 'package:mutex/mutex.dart'; -import 'package:tuple/tuple.dart'; +import 'package:compat/compat.dart' as lib_monero_compat; +import 'package:cs_monero/cs_monero.dart' as lib_monero; -import '../../../db/hive/db.dart'; -import '../../../models/isar/models/blockchain_data/address.dart'; -import '../../../models/isar/models/blockchain_data/transaction.dart'; -import '../../../models/keys/cw_key_data.dart'; -import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart'; -import '../../../services/event_bus/events/global/tor_status_changed_event.dart'; -import '../../../services/event_bus/global_event_bus.dart'; -import '../../../services/tor_service.dart'; import '../../../utilities/amount/amount.dart'; -import '../../../utilities/enums/fee_rate_type_enum.dart'; -import '../../../utilities/logger.dart'; import '../../crypto_currency/crypto_currency.dart'; -import '../../models/tx_data.dart'; -import '../intermediate/cryptonote_wallet.dart'; -import '../wallet.dart'; -import '../wallet_mixin_interfaces/cw_based_interface.dart'; +import '../intermediate/lib_monero_wallet.dart'; -class MoneroWallet extends CryptonoteWallet with CwBasedInterface { - MoneroWallet(CryptoCurrencyNetwork network) : super(Monero(network)) { - final bus = GlobalEventBus.instance; - - // Listen for tor status changes. - _torStatusListener = bus.on().listen( - (event) async { - switch (event.newStatus) { - case TorConnectionStatus.connecting: - if (!_torConnectingLock.isLocked) { - await _torConnectingLock.acquire(); - } - _requireMutex = true; - break; - - case TorConnectionStatus.connected: - case TorConnectionStatus.disconnected: - if (_torConnectingLock.isLocked) { - _torConnectingLock.release(); - } - _requireMutex = false; - break; - } - }, - ); - - // Listen for tor preference changes. - _torPreferenceListener = bus.on().listen( - (event) async { - await updateNode(); - }, - ); - } - - @override - Address addressFor({required int index, int account = 0}) { - final String address = (CwBasedInterface.cwWalletBase as MoneroWalletBase) - .getTransactionAddress(account, index); - - final newReceivingAddress = Address( - walletId: walletId, - derivationIndex: index, - derivationPath: null, - value: address, - publicKey: [], - type: AddressType.cryptonote, - subType: AddressSubType.receiving, - ); - - return newReceivingAddress; - } - - @override - Future exitCwWallet() async { - (CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewBlock = null; - (CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewTransaction = - null; - (CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.syncStatusChanged = - null; - await (CwBasedInterface.cwWalletBase as MoneroWalletBase?) - ?.save(prioritySave: true); - } - - @override - Future open() async { - // await any previous exit - await CwBasedInterface.exitMutex.protect(() async {}); - - String? password; - try { - password = await cwKeysStorage.getWalletPassword(walletName: walletId); - } catch (e, s) { - throw Exception("Password not found $e, $s"); - } - - CwBasedInterface.cwWalletBase?.close(); - CwBasedInterface.cwWalletBase = (await CwBasedInterface.cwWalletService! - .openWallet(walletId, password)) as MoneroWalletBase; - - (CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewBlock = - onNewBlock; - (CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.onNewTransaction = - onNewTransaction; - (CwBasedInterface.cwWalletBase as MoneroWalletBase?)?.syncStatusChanged = - syncStatusChanged; - - await updateNode(); - - Address? currentAddress = await getCurrentReceivingAddress(); - if (currentAddress == null) { - currentAddress = addressFor(index: 0); - await mainDB.updateOrPutAddresses([currentAddress]); - } - if (info.cachedReceivingAddress != currentAddress.value) { - await info.updateReceivingAddress( - newAddress: currentAddress.value, - isar: mainDB.isar, - ); - } - - await CwBasedInterface.cwWalletBase?.startSync(); - unawaited(refresh()); - autoSaveTimer?.cancel(); - autoSaveTimer = Timer.periodic( - const Duration(seconds: 193), - (_) async => await CwBasedInterface.cwWalletBase?.save(), - ); - } +class MoneroWallet extends LibMoneroWallet { + MoneroWallet(CryptoCurrencyNetwork network) + : super( + Monero(network), + lib_monero_compat.WalletType.monero, + ); @override Future estimateFeeFor(Amount amount, int feeRate) async { - if (CwBasedInterface.cwWalletBase == null || - CwBasedInterface.cwWalletBase?.syncStatus is! SyncedSyncStatus) { + if (libMoneroWallet == null || + syncStatus is! lib_monero_compat.SyncedSyncStatus) { return Amount.zeroWith( fractionDigits: cryptoCurrency.fractionDigits, ); } - MoneroTransactionPriority priority; + lib_monero.TransactionPriority priority; switch (feeRate) { case 1: - priority = MoneroTransactionPriority.regular; + priority = lib_monero.TransactionPriority.low; break; case 2: - priority = MoneroTransactionPriority.medium; + priority = lib_monero.TransactionPriority.medium; break; case 3: - priority = MoneroTransactionPriority.fast; + priority = lib_monero.TransactionPriority.high; break; case 4: - priority = MoneroTransactionPriority.fastest; + priority = lib_monero.TransactionPriority.last; break; case 0: default: - priority = MoneroTransactionPriority.slow; + priority = lib_monero.TransactionPriority.normal; break; } int approximateFee = 0; await estimateFeeMutex.protect(() async { - approximateFee = CwBasedInterface.cwWalletBase!.calculateEstimatedFee( + approximateFee = await libMoneroWallet!.estimateFee( priority, amount.raw.toInt(), ); @@ -192,574 +58,65 @@ class MoneroWallet extends CryptonoteWallet with CwBasedInterface { } @override - Future pingCheck() async { - return await (CwBasedInterface.cwWalletBase as MoneroWalletBase?) - ?.isConnected() ?? - false; - } + bool walletExists(String path) => lib_monero.MoneroWallet.isWalletExist(path); @override - Future updateNode() async { - final node = getCurrentNode(); - - String host = Uri.parse(node.host).host; - if (host.isEmpty) { - host = node.host; - } - ({InternetAddress host, int port})? proxy; - if (prefs.useTor) { - proxy = TorService.sharedInstance.getProxyInfo(); - } - if (_requireMutex) { - await _torConnectingLock.protect(() async { - await CwBasedInterface.cwWalletBase?.connectToNode( - node: Node( - uri: "$host:${node.port}", - type: WalletType.monero, - trusted: node.trusted ?? false, - useSSL: node.useSSL, - ), - socksProxyAddress: - proxy == null ? null : "${proxy.host.address}:${proxy.port}", - ); - }); - } else { - await CwBasedInterface.cwWalletBase?.connectToNode( - node: Node( - uri: "$host:${node.port}", - type: WalletType.monero, - trusted: node.trusted ?? false, - useSSL: node.useSSL, - ), - socksProxyAddress: - proxy == null ? null : "${proxy.host.address}:${proxy.port}", - ); - } - - return; - } - - @override - Future getKeys() async { - final base = (CwBasedInterface.cwWalletBase as MoneroWalletBase?); - - if (base == null || - base.walletInfo.name != walletId || - CwBasedInterface.exitMutex.isLocked) { - return null; - } - - return CWKeyData( - walletId: walletId, - publicViewKey: base.keys.publicViewKey, - privateViewKey: base.keys.privateViewKey, - publicSpendKey: base.keys.publicSpendKey, - privateSpendKey: base.keys.privateSpendKey, + void loadWallet({ + required String path, + required String password, + }) { + libMoneroWallet = lib_monero.MoneroWallet.loadWallet( + path: path, + password: password, ); } @override - Future updateTransactions() async { - final base = (CwBasedInterface.cwWalletBase as MoneroWalletBase?); - - if (base == null || - base.walletInfo.name != walletId || - CwBasedInterface.exitMutex.isLocked) { - return; - } - await base.updateTransactions(); - final transactions = base.transactionHistory?.transactions; - - // final cachedTransactions = - // DB.instance.get(boxName: walletId, key: 'latest_tx_model') - // as TransactionData?; - // int latestTxnBlockHeight = - // DB.instance.get(boxName: walletId, key: "storedTxnDataHeight") - // as int? ?? - // 0; - // - // final txidsList = DB.instance - // .get(boxName: walletId, key: "cachedTxids") as List? ?? - // []; - // - // final Set cachedTxids = Set.from(txidsList); - - // TODO: filter to skip cached + confirmed txn processing in next step - // final unconfirmedCachedTransactions = - // cachedTransactions?.getAllTransactions() ?? {}; - // unconfirmedCachedTransactions - // .removeWhere((key, value) => value.confirmedStatus); - // - // if (cachedTransactions != null) { - // for (final tx in allTxHashes.toList(growable: false)) { - // final txHeight = tx["height"] as int; - // if (txHeight > 0 && - // txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) { - // if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) { - // allTxHashes.remove(tx); - // } - // } - // } - // } - - final List> txnsData = []; - - if (transactions != null) { - for (final tx in transactions.entries) { - Address? address; - TransactionType type; - if (tx.value.direction == TransactionDirection.incoming) { - final addressInfo = tx.value.additionalInfo; - - final addressString = - (CwBasedInterface.cwWalletBase as MoneroWalletBase?) - ?.getTransactionAddress( - addressInfo!['accountIndex'] as int, - addressInfo['addressIndex'] as int, - ); - - if (addressString != null) { - address = await mainDB - .getAddresses(walletId) - .filter() - .valueEqualTo(addressString) - .findFirst(); - } - - type = TransactionType.incoming; - } else { - // txn.address = ""; - type = TransactionType.outgoing; - } - - final txn = Transaction( - walletId: walletId, - txid: tx.value.id, - timestamp: (tx.value.date.millisecondsSinceEpoch ~/ 1000), - type: type, - subType: TransactionSubType.none, - amount: tx.value.amount ?? 0, - amountString: Amount( - rawValue: BigInt.from(tx.value.amount ?? 0), - fractionDigits: cryptoCurrency.fractionDigits, - ).toJsonString(), - fee: tx.value.fee ?? 0, - height: tx.value.height, - isCancelled: false, - isLelantus: false, - slateId: null, - otherData: null, - nonce: null, - inputs: [], - outputs: [], - numberOfMessages: null, - ); - - txnsData.add(Tuple2(txn, address)); - } - } - - await mainDB.isar.writeTxn(() async { - await mainDB.isar.transactions - .where() - .walletIdEqualTo(walletId) - .deleteAll(); - for (final data in txnsData) { - final tx = data.item1; - - // save transaction - await mainDB.isar.transactions.put(tx); - - if (data.item2 != null) { - final address = await mainDB.getAddress(walletId, data.item2!.value); - - // check if address exists in db and add if it does not - if (address == null) { - await mainDB.isar.addresses.put(data.item2!); - } - - // link and save address - tx.address.value = address ?? data.item2!; - await tx.address.save(); - } - } - }); - } - - @override - Future init({bool? isRestore}) async { - await CwBasedInterface.exitMutex.protect(() async {}); - - CwBasedInterface.cwWalletService = xmr_dart.monero - .createMoneroWalletService(DB.instance.moneroWalletInfoBox); - - if (!(await CwBasedInterface.cwWalletService!.isWalletExit(walletId)) && - isRestore != true) { - WalletInfo walletInfo; - WalletCredentials credentials; - try { - final dirPath = - await pathForWalletDir(name: walletId, type: WalletType.monero); - final path = - await pathForWallet(name: walletId, type: WalletType.monero); - credentials = xmr_dart.monero.createMoneroNewWalletCredentials( - name: walletId, - language: "English", - ); - - walletInfo = WalletInfo.external( - id: WalletBase.idFor(walletId, WalletType.monero), - name: walletId, - type: WalletType.monero, - isRecovery: false, - restoreHeight: credentials.height ?? 0, - date: DateTime.now(), - path: path, - dirPath: dirPath, - address: '', - ); - credentials.walletInfo = walletInfo; - - final _walletCreationService = WalletCreationService( - secureStorage: secureStorageInterface, - walletService: CwBasedInterface.cwWalletService, - keyService: cwKeysStorage, - ); - _walletCreationService.type = WalletType.monero; - // To restore from a seed - final wallet = await _walletCreationService.create(credentials); - - // subtract a couple days to ensure we have a buffer for SWB - final bufferedCreateHeight = xmr_dart.monero.getHeigthByDate( - date: DateTime.now().subtract(const Duration(days: 2)), - ); - - await info.updateRestoreHeight( - newRestoreHeight: bufferedCreateHeight, - isar: mainDB.isar, - ); - - // special case for xmr/wow. Normally mnemonic + passphrase is saved - // before wallet.init() is called - await secureStorageInterface.write( - key: Wallet.mnemonicKey(walletId: walletId), - value: wallet.seed.trim(), - ); - await secureStorageInterface.write( - key: Wallet.mnemonicPassphraseKey(walletId: walletId), - value: "", - ); - - walletInfo.restoreHeight = bufferedCreateHeight; - - walletInfo.address = wallet.walletAddresses.address; - await DB.instance - .add(boxName: WalletInfo.boxName, value: walletInfo); - - wallet.close(); - } catch (e, s) { - Logging.instance.log("$e\n$s", level: LogLevel.Fatal); - CwBasedInterface.cwWalletBase?.close(); - } - await updateNode(); - } - - return super.init(); - } - - @override - Future recover({required bool isRescan}) async { - await CwBasedInterface.exitMutex.protect(() async {}); - - if (isRescan) { - await refreshMutex.protect(() async { - // clear blockchain info - await mainDB.deleteWalletBlockchainData(walletId); - - final restoreHeight = - CwBasedInterface.cwWalletBase?.walletInfo.restoreHeight; - highestPercentCached = 0; - await CwBasedInterface.cwWalletBase?.rescan(height: restoreHeight ?? 0); - }); - unawaited(refresh()); - return; - } - - await refreshMutex.protect(() async { - final mnemonic = await getMnemonic(); - final seedLength = mnemonic.trim().split(" ").length; - - if (seedLength != 25 && seedLength != 16) { - throw Exception("Invalid monero mnemonic length found: $seedLength"); - } - - try { - final height = max(info.restoreHeight, 0); - - await info.updateRestoreHeight( - newRestoreHeight: height, - isar: mainDB.isar, - ); - - CwBasedInterface.cwWalletService = xmr_dart.monero - .createMoneroWalletService(DB.instance.moneroWalletInfoBox); - WalletInfo walletInfo; - WalletCredentials credentials; - final String name = walletId; - final dirPath = - await pathForWalletDir(name: name, type: WalletType.monero); - final path = await pathForWallet(name: name, type: WalletType.monero); - credentials = - xmr_dart.monero.createMoneroRestoreWalletFromSeedCredentials( - name: name, - height: height, - mnemonic: mnemonic.trim(), - ); - try { - walletInfo = WalletInfo.external( - id: WalletBase.idFor(name, WalletType.monero), - name: name, - type: WalletType.monero, - isRecovery: false, - restoreHeight: credentials.height ?? 0, - date: DateTime.now(), - path: path, - dirPath: dirPath, - address: '', - ); - credentials.walletInfo = walletInfo; - - final cwWalletCreationService = WalletCreationService( - secureStorage: secureStorageInterface, - walletService: CwBasedInterface.cwWalletService, - keyService: cwKeysStorage, - ); - cwWalletCreationService.type = WalletType.monero; - // To restore from a seed - final wallet = - await cwWalletCreationService.restoreFromSeed(credentials); - walletInfo.address = wallet.walletAddresses.address; - await DB.instance - .add(boxName: WalletInfo.boxName, value: walletInfo); - if (walletInfo.address != null) { - final newReceivingAddress = await getCurrentReceivingAddress() ?? - Address( - walletId: walletId, - derivationIndex: 0, - derivationPath: null, - value: walletInfo.address!, - publicKey: [], - type: AddressType.cryptonote, - subType: AddressSubType.receiving, - ); - - await mainDB.updateOrPutAddresses([newReceivingAddress]); - await info.updateReceivingAddress( - newAddress: newReceivingAddress.value, - isar: mainDB.isar, - ); - } - CwBasedInterface.cwWalletBase?.close(); - CwBasedInterface.cwWalletBase = wallet as MoneroWalletBase; - } catch (e, s) { - Logging.instance.log("$e\n$s", level: LogLevel.Fatal); - } - await updateNode(); - - await CwBasedInterface.cwWalletBase?.rescan(height: credentials.height); - CwBasedInterface.cwWalletBase?.close(); - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from recoverFromMnemonic(): $e\n$s", - level: LogLevel.Error, - ); - rethrow; - } - }); - } - - @override - Future prepareSend({required TxData txData}) async { - try { - final feeRate = txData.feeRateType; - if (feeRate is FeeRateType) { - MoneroTransactionPriority feePriority; - switch (feeRate) { - case FeeRateType.fast: - feePriority = MoneroTransactionPriority.fast; - break; - case FeeRateType.average: - feePriority = MoneroTransactionPriority.regular; - break; - case FeeRateType.slow: - feePriority = MoneroTransactionPriority.slow; - break; - default: - throw ArgumentError("Invalid use of custom fee"); - } - - Future? awaitPendingTransaction; - try { - // check for send all - bool isSendAll = false; - final balance = await availableBalance; - if (txData.amount! == balance && - txData.recipients!.first.amount == balance) { - isSendAll = true; - } - - final List outputs = []; - for (final recipient in txData.recipients!) { - final output = monero_output.Output(CwBasedInterface.cwWalletBase!); - output.address = recipient.address; - output.sendAll = isSendAll; - final String amountToSend = recipient.amount.decimal.toString(); - output.setCryptoAmount(amountToSend); - outputs.add(output); - } - - final tmp = - xmr_dart.monero.createMoneroTransactionCreationCredentials( - outputs: outputs, - priority: feePriority, - ); - - await prepareSendMutex.protect(() async { - awaitPendingTransaction = - CwBasedInterface.cwWalletBase!.createTransaction(tmp); - }); - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from prepareSend(): $e\n$s", - level: LogLevel.Warning, - ); - } - - final PendingMoneroTransaction pendingMoneroTransaction = - await (awaitPendingTransaction!) as PendingMoneroTransaction; - final realFee = Amount.fromDecimal( - Decimal.parse(pendingMoneroTransaction.feeFormatted), - fractionDigits: cryptoCurrency.fractionDigits, - ); - - return txData.copyWith( - fee: realFee, - pendingMoneroTransaction: pendingMoneroTransaction, - ); - } else { - throw ArgumentError("Invalid fee rate argument provided!"); - } - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from prepare send(): $e\n$s", - level: LogLevel.Info, + Future getCreatedWallet({ + required String path, + required String password, + }) async => + await lib_monero.MoneroWallet.create( + path: path, + password: password, + seedType: lib_monero.MoneroSeedType + .sixteen, // TODO: check we want to actually use 16 here ); - if (e.toString().contains("Incorrect unlocked balance")) { - throw Exception("Insufficient balance!"); - } else if (e is CreationTransactionException) { - throw Exception("Insufficient funds to pay for transaction fee!"); - } else { - throw Exception("Transaction failed with error code $e"); - } - } - } - @override - Future confirmSend({required TxData txData}) async { - try { - try { - await txData.pendingMoneroTransaction!.commit(); - Logging.instance.log( - "transaction ${txData.pendingMoneroTransaction!.id} has been sent", - level: LogLevel.Info, - ); - return txData.copyWith(txid: txData.pendingMoneroTransaction!.id); - } catch (e, s) { - Logging.instance.log( - "${info.name} monero confirmSend: $e\n$s", - level: LogLevel.Error, - ); - rethrow; - } - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from confirmSend(): $e\n$s", - level: LogLevel.Info, + Future getRestoredWallet({ + required String path, + required String password, + required String mnemonic, + int height = 0, + }) async => + await lib_monero.MoneroWallet.restoreWalletFromSeed( + path: path, + password: password, + seed: mnemonic, + restoreHeight: height, ); - rethrow; - } - } @override - Future get availableBalance async { - try { - if (CwBasedInterface.exitMutex.isLocked) { - throw Exception("Exit in progress"); - } - int runningBalance = 0; - for (final entry in (CwBasedInterface.cwWalletBase as MoneroWalletBase?)! - .balance! - .entries) { - runningBalance += entry.value.unlockedBalance; - } - return Amount( - rawValue: BigInt.from(runningBalance), - fractionDigits: cryptoCurrency.fractionDigits, + Future getRestoredFromViewKeyWallet({ + required String path, + required String password, + required String address, + required String privateViewKey, + int height = 0, + }) async => + lib_monero.MoneroWallet.createViewOnlyWallet( + path: path, + password: password, + address: address, + viewKey: privateViewKey, + restoreHeight: height, ); - } catch (_) { - return info.cachedBalance.spendable; - } - } @override - Future get totalBalance async { - try { - if (CwBasedInterface.exitMutex.isLocked) { - throw Exception("Exit in progress"); - } - final balanceEntries = - (CwBasedInterface.cwWalletBase as MoneroWalletBase?) - ?.balance - ?.entries; - if (balanceEntries != null) { - int bal = 0; - for (final element in balanceEntries) { - bal = bal + element.value.fullBalance; - } - return Amount( - rawValue: BigInt.from(bal), - fractionDigits: cryptoCurrency.fractionDigits, - ); - } else { - final transactions = - (CwBasedInterface.cwWalletBase as MoneroWalletBase?)! - .transactionHistory! - .transactions; - int transactionBalance = 0; - for (final tx in transactions!.entries) { - if (tx.value.direction == TransactionDirection.incoming) { - transactionBalance += tx.value.amount!; - } else { - transactionBalance += -tx.value.amount! - tx.value.fee!; - } - } - - return Amount( - rawValue: BigInt.from(transactionBalance), - fractionDigits: cryptoCurrency.fractionDigits, - ); - } - } catch (_) { - return info.cachedBalance.total; + void invalidSeedLengthCheck(int length) { + if (length != 25 && length != 16) { + throw Exception("Invalid monero mnemonic length found: $length"); } } - - // ============== Private ==================================================== - - StreamSubscription? _torStatusListener; - StreamSubscription? _torPreferenceListener; - - final Mutex _torConnectingLock = Mutex(); - bool _requireMutex = false; } diff --git a/lib/wallets/wallet/impl/wownero_wallet.dart b/lib/wallets/wallet/impl/wownero_wallet.dart index a3ef7d04b..a33bd2da7 100644 --- a/lib/wallets/wallet/impl/wownero_wallet.dart +++ b/lib/wallets/wallet/impl/wownero_wallet.dart @@ -1,130 +1,52 @@ import 'dart:async'; -import 'dart:io'; -import 'dart:math'; -import 'package:cw_core/monero_transaction_priority.dart'; -import 'package:cw_core/node.dart'; -import 'package:cw_core/pending_transaction.dart'; -import 'package:cw_core/sync_status.dart'; -import 'package:cw_core/transaction_direction.dart'; -import 'package:cw_core/wallet_base.dart'; -import 'package:cw_core/wallet_credentials.dart'; -import 'package:cw_core/wallet_info.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:cw_monero/api/exceptions/creation_transaction_exception.dart'; -import 'package:cw_wownero/api/account_list.dart'; -import 'package:cw_wownero/pending_wownero_transaction.dart'; -import 'package:cw_wownero/wownero_wallet.dart'; -import 'package:decimal/decimal.dart'; -import 'package:flutter_libmonero/core/wallet_creation_service.dart'; -import 'package:flutter_libmonero/view_model/send/output.dart' - as wownero_output; -import 'package:flutter_libmonero/wownero/wownero.dart' as wow_dart; -import 'package:isar/isar.dart'; -import 'package:monero/wownero.dart' as wownerodart; -import 'package:mutex/mutex.dart'; -import 'package:tuple/tuple.dart'; +import 'package:compat/compat.dart' as lib_monero_compat; +import 'package:cs_monero/cs_monero.dart' as lib_monero; -import '../../../db/hive/db.dart'; -import '../../../models/isar/models/blockchain_data/address.dart'; -import '../../../models/isar/models/blockchain_data/transaction.dart'; -import '../../../models/keys/cw_key_data.dart'; -import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart'; -import '../../../services/event_bus/events/global/tor_status_changed_event.dart'; -import '../../../services/event_bus/global_event_bus.dart'; -import '../../../services/tor_service.dart'; import '../../../utilities/amount/amount.dart'; import '../../../utilities/enums/fee_rate_type_enum.dart'; -import '../../../utilities/logger.dart'; import '../../crypto_currency/crypto_currency.dart'; import '../../models/tx_data.dart'; -import '../intermediate/cryptonote_wallet.dart'; -import '../wallet.dart'; -import '../wallet_mixin_interfaces/cw_based_interface.dart'; +import '../intermediate/lib_monero_wallet.dart'; -class WowneroWallet extends CryptonoteWallet with CwBasedInterface { - WowneroWallet(CryptoCurrencyNetwork network) : super(Wownero(network)) { - final bus = GlobalEventBus.instance; - - // Listen for tor status changes. - _torStatusListener = bus.on().listen( - (event) async { - switch (event.newStatus) { - case TorConnectionStatus.connecting: - if (!_torConnectingLock.isLocked) { - await _torConnectingLock.acquire(); - } - _requireMutex = true; - break; - - case TorConnectionStatus.connected: - case TorConnectionStatus.disconnected: - if (_torConnectingLock.isLocked) { - _torConnectingLock.release(); - } - _requireMutex = false; - break; - } - }, - ); - - // Listen for tor preference changes. - _torPreferenceListener = bus.on().listen( - (event) async { - await updateNode(); - }, - ); - } - - @override - Address addressFor({required int index, int account = 0}) { - final String address = (CwBasedInterface.cwWalletBase as WowneroWalletBase) - .getTransactionAddress(account, index); - - final newReceivingAddress = Address( - walletId: walletId, - derivationIndex: index, - derivationPath: null, - value: address, - publicKey: [], - type: AddressType.cryptonote, - subType: AddressSubType.receiving, - ); - - return newReceivingAddress; - } +class WowneroWallet extends LibMoneroWallet { + WowneroWallet(CryptoCurrencyNetwork network) + : super( + Wownero(network), + lib_monero_compat.WalletType.wownero, + ); @override Future estimateFeeFor(Amount amount, int feeRate) async { - if (CwBasedInterface.cwWalletBase == null || - CwBasedInterface.cwWalletBase?.syncStatus is! SyncedSyncStatus) { + if (libMoneroWallet == null || + syncStatus is! lib_monero_compat.SyncedSyncStatus) { return Amount.zeroWith( fractionDigits: cryptoCurrency.fractionDigits, ); } - MoneroTransactionPriority priority; + lib_monero.TransactionPriority priority; FeeRateType feeRateType = FeeRateType.slow; switch (feeRate) { case 1: - priority = MoneroTransactionPriority.regular; + priority = lib_monero.TransactionPriority.low; feeRateType = FeeRateType.average; break; case 2: - priority = MoneroTransactionPriority.medium; + priority = lib_monero.TransactionPriority.medium; feeRateType = FeeRateType.average; break; case 3: - priority = MoneroTransactionPriority.fast; + priority = lib_monero.TransactionPriority.high; feeRateType = FeeRateType.fast; break; case 4: - priority = MoneroTransactionPriority.fastest; + priority = lib_monero.TransactionPriority.last; feeRateType = FeeRateType.fast; break; case 0: default: - priority = MoneroTransactionPriority.slow; + priority = lib_monero.TransactionPriority.normal; feeRateType = FeeRateType.slow; break; } @@ -152,7 +74,7 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface { // unsure why this delay? await Future.delayed(const Duration(milliseconds: 500)); } catch (e) { - approximateFee = CwBasedInterface.cwWalletBase!.calculateEstimatedFee( + approximateFee = libMoneroWallet!.estimateFee( priority, amount.raw.toInt(), ); @@ -171,639 +93,67 @@ class WowneroWallet extends CryptonoteWallet with CwBasedInterface { } @override - Future pingCheck() async { - return await (CwBasedInterface.cwWalletBase as WowneroWalletBase?) - ?.isConnected() ?? - false; - } + bool walletExists(String path) => + lib_monero.WowneroWallet.isWalletExist(path); @override - Future updateNode() async { - final node = getCurrentNode(); - - final host = Uri.parse(node.host).host; - ({InternetAddress host, int port})? proxy; - if (prefs.useTor) { - proxy = TorService.sharedInstance.getProxyInfo(); - } - if (_requireMutex) { - await _torConnectingLock.protect(() async { - await CwBasedInterface.cwWalletBase?.connectToNode( - node: Node( - uri: "$host:${node.port}", - type: WalletType.wownero, - trusted: node.trusted ?? false, - useSSL: node.useSSL, - ), - socksProxyAddress: - proxy == null ? null : "${proxy.host.address}:${proxy.port}", - ); - }); - } else { - await CwBasedInterface.cwWalletBase?.connectToNode( - node: Node( - uri: "$host:${node.port}", - type: WalletType.wownero, - trusted: node.trusted ?? false, - useSSL: node.useSSL, - ), - socksProxyAddress: - proxy == null ? null : "${proxy.host.address}:${proxy.port}", - ); - } - - return; - } - - @override - Future getKeys() async { - final base = (CwBasedInterface.cwWalletBase as WowneroWalletBase?); - - if (base == null || - base.walletInfo.name != walletId || - CwBasedInterface.exitMutex.isLocked) { - return null; - } - - return CWKeyData( - walletId: walletId, - publicViewKey: base.keys.publicViewKey, - privateViewKey: base.keys.privateViewKey, - publicSpendKey: base.keys.publicSpendKey, - privateSpendKey: base.keys.privateSpendKey, + void loadWallet({ + required String path, + required String password, + }) { + libMoneroWallet = lib_monero.WowneroWallet.loadWallet( + path: path, + password: password, ); } @override - Future updateTransactions() async { - final base = (CwBasedInterface.cwWalletBase as WowneroWalletBase?); - - if (base == null || - base.walletInfo.name != walletId || - CwBasedInterface.exitMutex.isLocked) { - return; - } - await base.updateTransactions(); - final transactions = base.transactionHistory?.transactions; - - // final cachedTransactions = - // DB.instance.get(boxName: walletId, key: 'latest_tx_model') - // as TransactionData?; - // int latestTxnBlockHeight = - // DB.instance.get(boxName: walletId, key: "storedTxnDataHeight") - // as int? ?? - // 0; - // - // final txidsList = DB.instance - // .get(boxName: walletId, key: "cachedTxids") as List? ?? - // []; - // - // final Set cachedTxids = Set.from(txidsList); - - // TODO: filter to skip cached + confirmed txn processing in next step - // final unconfirmedCachedTransactions = - // cachedTransactions?.getAllTransactions() ?? {}; - // unconfirmedCachedTransactions - // .removeWhere((key, value) => value.confirmedStatus); - // - // if (cachedTransactions != null) { - // for (final tx in allTxHashes.toList(growable: false)) { - // final txHeight = tx["height"] as int; - // if (txHeight > 0 && - // txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) { - // if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) { - // allTxHashes.remove(tx); - // } - // } - // } - // } - - final List> txnsData = []; - - if (transactions != null) { - for (final tx in transactions.entries) { - Address? address; - TransactionType type; - if (tx.value.direction == TransactionDirection.incoming) { - final addressInfo = tx.value.additionalInfo; - - final addressString = - (CwBasedInterface.cwWalletBase as WowneroWalletBase?) - ?.getTransactionAddress( - addressInfo!['accountIndex'] as int, - addressInfo['addressIndex'] as int, - ); - - if (addressString != null) { - address = await mainDB - .getAddresses(walletId) - .filter() - .valueEqualTo(addressString) - .findFirst(); - } - - type = TransactionType.incoming; - } else { - // txn.address = ""; - type = TransactionType.outgoing; - } - - final txn = Transaction( - walletId: walletId, - txid: tx.value.id, - timestamp: (tx.value.date.millisecondsSinceEpoch ~/ 1000), - type: type, - subType: TransactionSubType.none, - amount: tx.value.amount ?? 0, - amountString: Amount( - rawValue: BigInt.from(tx.value.amount ?? 0), - fractionDigits: cryptoCurrency.fractionDigits, - ).toJsonString(), - fee: tx.value.fee ?? 0, - height: tx.value.height, - isCancelled: false, - isLelantus: false, - slateId: null, - otherData: null, - nonce: null, - inputs: [], - outputs: [], - numberOfMessages: null, - ); - - txnsData.add(Tuple2(txn, address)); - } - } - - await mainDB.isar.writeTxn(() async { - await mainDB.isar.transactions - .where() - .walletIdEqualTo(walletId) - .deleteAll(); - for (final data in txnsData) { - final tx = data.item1; - - // save transaction - await mainDB.isar.transactions.put(tx); - - if (data.item2 != null) { - final address = await mainDB.getAddress(walletId, data.item2!.value); - - // check if address exists in db and add if it does not - if (address == null) { - await mainDB.isar.addresses.put(data.item2!); - } - - // link and save address - tx.address.value = address ?? data.item2!; - await tx.address.save(); - } - } - }); - } - - @override - Future init({bool? isRestore}) async { - await CwBasedInterface.exitMutex.protect(() async {}); - CwBasedInterface.cwWalletService = wow_dart.wownero - .createWowneroWalletService(DB.instance.moneroWalletInfoBox); - - if (!(await CwBasedInterface.cwWalletService!.isWalletExit(walletId)) && - isRestore != true) { - WalletInfo walletInfo; - WalletCredentials credentials; - try { - final dirPath = - await pathForWalletDir(name: walletId, type: WalletType.wownero); - final path = - await pathForWallet(name: walletId, type: WalletType.wownero); - credentials = wow_dart.wownero.createWowneroNewWalletCredentials( - name: walletId, - language: "English", - seedWordsLength: 14, - ); - - walletInfo = WalletInfo.external( - id: WalletBase.idFor(walletId, WalletType.wownero), - name: walletId, - type: WalletType.wownero, - isRecovery: false, - restoreHeight: credentials.height ?? 0, - date: DateTime.now(), - path: path, - dirPath: dirPath, - address: '', - ); - credentials.walletInfo = walletInfo; - - final _walletCreationService = WalletCreationService( - secureStorage: secureStorageInterface, - walletService: CwBasedInterface.cwWalletService, - keyService: cwKeysStorage, - ); - // _walletCreationService.changeWalletType(); - _walletCreationService.type = WalletType.wownero; - // To restore from a seed - final wallet = await _walletCreationService.create(credentials); - - final height = wownerodart.Wallet_getRefreshFromBlockHeight(wptr!); - - await info.updateRestoreHeight( - newRestoreHeight: height, - isar: mainDB.isar, - ); - - // special case for xmr/wow. Normally mnemonic + passphrase is saved - // before wallet.init() is called - await secureStorageInterface.write( - key: Wallet.mnemonicKey(walletId: walletId), - value: wallet.seed.trim(), - ); - await secureStorageInterface.write( - key: Wallet.mnemonicPassphraseKey(walletId: walletId), - value: "", - ); - - walletInfo.restoreHeight = height; - - walletInfo.address = wallet.walletAddresses.address; - await DB.instance - .add(boxName: WalletInfo.boxName, value: walletInfo); - - wallet.close(); - } catch (e, s) { - Logging.instance.log("$e\n$s", level: LogLevel.Fatal); - CwBasedInterface.cwWalletBase?.close(); - } - await updateNode(); - } - - return super.init(); - } - - @override - Future open() async { - // await any previous exit - await CwBasedInterface.exitMutex.protect(() async {}); - - String? password; - try { - password = await cwKeysStorage.getWalletPassword(walletName: walletId); - } catch (e, s) { - throw Exception("Password not found $e, $s"); - } - - CwBasedInterface.cwWalletBase?.close(); - CwBasedInterface.cwWalletBase = (await CwBasedInterface.cwWalletService! - .openWallet(walletId, password)) as WowneroWalletBase; - - (CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewBlock = - onNewBlock; - (CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewTransaction = - onNewTransaction; - (CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.syncStatusChanged = - syncStatusChanged; - - await updateNode(); - - Address? currentAddress = await getCurrentReceivingAddress(); - if (currentAddress == null) { - currentAddress = addressFor(index: 0); - await mainDB.updateOrPutAddresses([currentAddress]); - } - if (info.cachedReceivingAddress != currentAddress.value) { - await info.updateReceivingAddress( - newAddress: currentAddress.value, - isar: mainDB.isar, - ); - } - - await (CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.startSync(); - unawaited(refresh()); - autoSaveTimer?.cancel(); - autoSaveTimer = Timer.periodic( - const Duration(seconds: 193), - (_) async => await CwBasedInterface.cwWalletBase?.save(), - ); - } - - @override - Future exitCwWallet() async { - (CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewBlock = null; - (CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.onNewTransaction = - null; - (CwBasedInterface.cwWalletBase as WowneroWalletBase?)?.syncStatusChanged = - null; - await (CwBasedInterface.cwWalletBase as WowneroWalletBase?) - ?.save(prioritySave: true); - } - - @override - Future recover({required bool isRescan}) async { - await CwBasedInterface.exitMutex.protect(() async {}); - - if (isRescan) { - await refreshMutex.protect(() async { - // clear blockchain info - await mainDB.deleteWalletBlockchainData(walletId); - - final restoreHeight = - CwBasedInterface.cwWalletBase?.walletInfo.restoreHeight; - highestPercentCached = 0; - await CwBasedInterface.cwWalletBase?.rescan(height: restoreHeight ?? 0); - }); - unawaited(refresh()); - return; - } - - await refreshMutex.protect(() async { - final mnemonic = await getMnemonic(); - final seedLength = mnemonic.trim().split(" ").length; - - if (!(seedLength == 14 || seedLength == 25)) { - throw Exception("Invalid wownero mnemonic length found: $seedLength"); - } - - try { - int height = info.restoreHeight; - - // extract seed height from 14 word seed - if (seedLength == 14) { - height = 0; - } else { - height = max(height, 0); - } - - // TODO: info.updateRestoreHeight - // await DB.instance - // .put(boxName: walletId, key: "restoreHeight", value: height); - - CwBasedInterface.cwWalletService = wow_dart.wownero - .createWowneroWalletService(DB.instance.moneroWalletInfoBox); - WalletInfo walletInfo; - WalletCredentials credentials; - final String name = walletId; - final dirPath = - await pathForWalletDir(name: name, type: WalletType.wownero); - final path = await pathForWallet(name: name, type: WalletType.wownero); - credentials = - wow_dart.wownero.createWowneroRestoreWalletFromSeedCredentials( - name: name, - height: height, - mnemonic: mnemonic.trim(), - ); - try { - walletInfo = WalletInfo.external( - id: WalletBase.idFor(name, WalletType.wownero), - name: name, - type: WalletType.wownero, - isRecovery: false, - restoreHeight: credentials.height ?? 0, - date: DateTime.now(), - path: path, - dirPath: dirPath, - // TODO: find out what to put for address - address: '', - ); - credentials.walletInfo = walletInfo; - - final cwWalletCreationService = WalletCreationService( - secureStorage: secureStorageInterface, - walletService: CwBasedInterface.cwWalletService, - keyService: cwKeysStorage, - ); - cwWalletCreationService.type = WalletType.wownero; - // To restore from a seed - final wallet = await cwWalletCreationService - .restoreFromSeed(credentials) as WowneroWalletBase; - height = wownerodart.Wallet_getRefreshFromBlockHeight(wptr!); - walletInfo.address = wallet.walletAddresses.address; - walletInfo.restoreHeight = height; - await info.updateRestoreHeight( - newRestoreHeight: height, - isar: mainDB.isar, - ); - await DB.instance - .add(boxName: WalletInfo.boxName, value: walletInfo); - CwBasedInterface.cwWalletBase?.close(); - CwBasedInterface.cwWalletBase = wallet; - if (walletInfo.address != null) { - final newReceivingAddress = await getCurrentReceivingAddress() ?? - Address( - walletId: walletId, - derivationIndex: 0, - derivationPath: null, - value: walletInfo.address!, - publicKey: [], - type: AddressType.cryptonote, - subType: AddressSubType.receiving, - ); - - await mainDB.updateOrPutAddresses([newReceivingAddress]); - await info.updateReceivingAddress( - newAddress: newReceivingAddress.value, - isar: mainDB.isar, - ); - } - } catch (e, s) { - Logging.instance.log("$e\n$s", level: LogLevel.Fatal); - } - await updateNode(); - - await CwBasedInterface.cwWalletBase?.rescan(height: credentials.height); - CwBasedInterface.cwWalletBase?.close(); - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from recoverFromMnemonic(): $e\n$s", - level: LogLevel.Error, - ); - rethrow; - } - }); - } - - @override - Future prepareSend({required TxData txData}) async { - try { - final feeRate = txData.feeRateType; - if (feeRate is FeeRateType) { - MoneroTransactionPriority feePriority; - switch (feeRate) { - case FeeRateType.fast: - feePriority = MoneroTransactionPriority.fast; - break; - case FeeRateType.average: - feePriority = MoneroTransactionPriority.regular; - break; - case FeeRateType.slow: - feePriority = MoneroTransactionPriority.slow; - break; - default: - throw ArgumentError("Invalid use of custom fee"); - } - - Future? awaitPendingTransaction; - try { - // check for send all - bool isSendAll = false; - final balance = await availableBalance; - if (txData.amount! == balance && - txData.recipients!.first.amount == balance) { - isSendAll = true; - } - - final List outputs = []; - for (final recipient in txData.recipients!) { - final output = - wownero_output.Output(CwBasedInterface.cwWalletBase!); - output.address = recipient.address; - output.sendAll = isSendAll; - final String amountToSend = recipient.amount.decimal.toString(); - output.setCryptoAmount(amountToSend); - outputs.add(output); - } - - final tmp = - wow_dart.wownero.createWowneroTransactionCreationCredentials( - outputs: outputs, - priority: feePriority, - ); - - await prepareSendMutex.protect(() async { - awaitPendingTransaction = - CwBasedInterface.cwWalletBase!.createTransaction(tmp); - }); - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from prepareSend(): $e\n$s", - level: LogLevel.Warning, - ); - } - - final PendingWowneroTransaction pendingWowneroTransaction = - await (awaitPendingTransaction!) as PendingWowneroTransaction; - final realFee = Amount.fromDecimal( - Decimal.parse(pendingWowneroTransaction.feeFormatted), - fractionDigits: cryptoCurrency.fractionDigits, - ); - - return txData.copyWith( - fee: realFee, - pendingWowneroTransaction: pendingWowneroTransaction, - ); - } else { - throw ArgumentError("Invalid fee rate argument provided!"); - } - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from prepare send(): $e\n$s", - level: LogLevel.Info, + Future getCreatedWallet({ + required String path, + required String password, + }) async => + await lib_monero.WowneroWallet.create( + path: path, + password: password, + seedType: lib_monero.WowneroSeedType + .fourteen, // TODO: check we want to actually use 14 here + overrideDeprecated14WordSeedException: true, ); - if (e.toString().contains("Incorrect unlocked balance")) { - throw Exception("Insufficient balance!"); - } else if (e is CreationTransactionException) { - throw Exception("Insufficient funds to pay for transaction fee!"); - } else { - throw Exception("Transaction failed with error code $e"); - } - } - } - @override - Future confirmSend({required TxData txData}) async { - try { - try { - await txData.pendingWowneroTransaction!.commit(); - Logging.instance.log( - "transaction ${txData.pendingWowneroTransaction!.id} has been sent", - level: LogLevel.Info, - ); - return txData.copyWith(txid: txData.pendingWowneroTransaction!.id); - } catch (e, s) { - Logging.instance.log( - "${info.name} wownero confirmSend: $e\n$s", - level: LogLevel.Error, - ); - rethrow; - } - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from confirmSend(): $e\n$s", - level: LogLevel.Info, + Future getRestoredWallet({ + required String path, + required String password, + required String mnemonic, + int height = 0, + }) async => + await lib_monero.WowneroWallet.restoreWalletFromSeed( + path: path, + password: password, + seed: mnemonic, + restoreHeight: height, ); - rethrow; - } - } @override - Future get availableBalance async { - try { - if (CwBasedInterface.exitMutex.isLocked) { - throw Exception("Exit in progress"); - } - - int runningBalance = 0; - for (final entry in (CwBasedInterface.cwWalletBase as WowneroWalletBase?)! - .balance! - .entries) { - runningBalance += entry.value.unlockedBalance; - } - return Amount( - rawValue: BigInt.from(runningBalance), - fractionDigits: cryptoCurrency.fractionDigits, + Future getRestoredFromViewKeyWallet({ + required String path, + required String password, + required String address, + required String privateViewKey, + int height = 0, + }) async => + lib_monero.WowneroWallet.createViewOnlyWallet( + path: path, + password: password, + address: address, + viewKey: privateViewKey, + restoreHeight: height, ); - } catch (_) { - return info.cachedBalance.spendable; - } - } @override - Future get totalBalance async { - try { - if (CwBasedInterface.exitMutex.isLocked) { - throw Exception("Exit in progress"); - } - final balanceEntries = - (CwBasedInterface.cwWalletBase as WowneroWalletBase?) - ?.balance - ?.entries; - if (balanceEntries != null) { - int bal = 0; - for (final element in balanceEntries) { - bal = bal + element.value.fullBalance; - } - return Amount( - rawValue: BigInt.from(bal), - fractionDigits: cryptoCurrency.fractionDigits, - ); - } else { - final transactions = - CwBasedInterface.cwWalletBase!.transactionHistory!.transactions; - int transactionBalance = 0; - for (final tx in transactions!.entries) { - if (tx.value.direction == TransactionDirection.incoming) { - transactionBalance += tx.value.amount!; - } else { - transactionBalance += -tx.value.amount! - tx.value.fee!; - } - } - - return Amount( - rawValue: BigInt.from(transactionBalance), - fractionDigits: cryptoCurrency.fractionDigits, - ); - } - } catch (_) { - return info.cachedBalance.total; + void invalidSeedLengthCheck(int length) { + if (!(length == 14 || length == 16 || length == 25)) { + throw Exception("Invalid wownero mnemonic length found: $length"); } } - - // ============== Private ==================================================== - - StreamSubscription? _torStatusListener; - StreamSubscription? _torPreferenceListener; - - final Mutex _torConnectingLock = Mutex(); - bool _requireMutex = false; } diff --git a/lib/wallets/wallet/intermediate/bip39_hd_wallet.dart b/lib/wallets/wallet/intermediate/bip39_hd_wallet.dart index 3d603fc03..d2ca7b254 100644 --- a/lib/wallets/wallet/intermediate/bip39_hd_wallet.dart +++ b/lib/wallets/wallet/intermediate/bip39_hd_wallet.dart @@ -6,15 +6,17 @@ import 'package:isar/isar.dart'; import '../../../models/balance.dart'; import '../../../models/isar/models/blockchain_data/address.dart'; +import '../../../models/keys/view_only_wallet_data.dart'; import '../../../utilities/amount/amount.dart'; import '../../../utilities/enums/derive_path_type_enum.dart'; import '../../../utilities/extensions/extensions.dart'; import '../../crypto_currency/intermediate/bip39_hd_currency.dart'; import '../wallet_mixin_interfaces/multi_address_interface.dart'; +import '../wallet_mixin_interfaces/view_only_option_interface.dart'; import 'bip39_wallet.dart'; abstract class Bip39HDWallet extends Bip39Wallet - with MultiAddressInterface { + with MultiAddressInterface, ViewOnlyOptionInterface { Bip39HDWallet(super.cryptoCurrency); Set get supportedAddressTypes => @@ -83,10 +85,17 @@ abstract class Bip39HDWallet extends Bip39Wallet final index = current == null ? 0 : current.derivationIndex + 1; const chain = 0; // receiving address + final DerivePathType type; + if (isViewOnly) { + type = await _viewOnlyPathHelper(); + } else { + type = _fromAddressType(info.mainAddressType); + } + final address = await _generateAddress( chain: chain, index: index, - derivePathType: _fromAddressType(info.mainAddressType), + derivePathType: type, ); await mainDB.updateOrPutAddresses([address]); @@ -105,10 +114,17 @@ abstract class Bip39HDWallet extends Bip39Wallet final index = current == null ? 0 : current.derivationIndex + 1; const chain = 1; // change address + final DerivePathType type; + if (isViewOnly) { + type = await _viewOnlyPathHelper(); + } else { + type = _fromAddressType(info.mainAddressType); + } + final address = await _generateAddress( chain: chain, index: index, - derivePathType: _fromAddressType(info.mainAddressType), + derivePathType: type, ); await mainDB.updateOrPutAddresses([address]); @@ -116,12 +132,21 @@ abstract class Bip39HDWallet extends Bip39Wallet @override Future checkSaveInitialReceivingAddress() async { - final current = await getCurrentChangeAddress(); + if (isViewOnly && viewOnlyType == ViewOnlyWalletType.addressOnly) return; + + final current = await getCurrentReceivingAddress(); if (current == null) { + final DerivePathType type; + if (isViewOnly) { + type = await _viewOnlyPathHelper(); + } else { + type = _fromAddressType(info.mainAddressType); + } + final address = await _generateAddress( chain: 0, // receiving index: 0, // initial index - derivePathType: _fromAddressType(info.mainAddressType), + derivePathType: type, ); await mainDB.updateOrPutAddresses([address]); @@ -138,6 +163,25 @@ abstract class Bip39HDWallet extends Bip39Wallet // ========== Private ======================================================== + Future _viewOnlyPathHelper() async { + final voData = + await getViewOnlyWalletData() as ExtendedKeysViewOnlyWalletData; + for (final type in cryptoCurrency.supportedDerivationPathTypes) { + final testPath = cryptoCurrency.constructDerivePath( + derivePathType: type, + chain: 0, + index: 0, + ); + if (testPath.startsWith(voData.xPubs.first.path)) { + return type; + } + } + + throw Exception( + "_viewOnlyPathHelper viewOnly failed to match paths", + ); + } + DerivePathType _fromAddressType(AddressType addressType) { switch (addressType) { case AddressType.p2pkh: @@ -174,15 +218,29 @@ abstract class Bip39HDWallet extends Bip39Wallet required int index, required DerivePathType derivePathType, }) async { - final root = await getRootHDNode(); - final derivationPath = cryptoCurrency.constructDerivePath( derivePathType: derivePathType, chain: chain, index: index, ); - final keys = root.derivePath(derivationPath); + final coinlib.HDKey keys; + if (isViewOnly) { + final idx = derivationPath.lastIndexOf("'/"); + final path = derivationPath.substring(idx + 2); + final data = + await getViewOnlyWalletData() as ExtendedKeysViewOnlyWalletData; + + final xPub = data.xPubs.firstWhere( + (e) => derivationPath.startsWith(e.path), + ); + + final node = coinlib.HDPublicKey.decode(xPub.encoded); + keys = node.derivePath(path); + } else { + final root = await getRootHDNode(); + keys = root.derivePath(derivationPath); + } final data = cryptoCurrency.getAddressForPublicKey( publicKey: keys.publicKey, @@ -205,7 +263,8 @@ abstract class Bip39HDWallet extends Bip39Wallet value: convertAddressString(data.address.toString()), publicKey: keys.publicKey.data, derivationIndex: index, - derivationPath: DerivationPath()..value = derivationPath, + derivationPath: + isViewOnly ? null : (DerivationPath()..value = derivationPath), type: data.addressType, subType: subType, ); diff --git a/lib/wallets/wallet/intermediate/cryptonote_wallet.dart b/lib/wallets/wallet/intermediate/cryptonote_wallet.dart index aabee237b..131bf8f04 100644 --- a/lib/wallets/wallet/intermediate/cryptonote_wallet.dart +++ b/lib/wallets/wallet/intermediate/cryptonote_wallet.dart @@ -1,51 +1,9 @@ -import 'dart:async'; - import '../../crypto_currency/intermediate/cryptonote_currency.dart'; -import '../../models/tx_data.dart'; import '../wallet.dart'; +import '../wallet_mixin_interfaces/coin_control_interface.dart'; import '../wallet_mixin_interfaces/mnemonic_interface.dart'; abstract class CryptonoteWallet extends Wallet - with MnemonicInterface { + with MnemonicInterface, CoinControlInterface { CryptonoteWallet(super.currency); - - Completer? walletOpenCompleter; - - void resetWalletOpenCompleter() { - if (walletOpenCompleter == null || walletOpenCompleter!.isCompleted) { - walletOpenCompleter = Completer(); - } - } - - Future waitForWalletOpen() async { - if (walletOpenCompleter != null && !walletOpenCompleter!.isCompleted) { - await walletOpenCompleter!.future; - } - } - - // ========== Overrides ====================================================== - - @override - Future confirmSend({required TxData txData}) { - // TODO: implement confirmSend - throw UnimplementedError(); - } - - @override - Future prepareSend({required TxData txData}) { - // TODO: implement prepareSend - throw UnimplementedError(); - } - - @override - Future recover({required bool isRescan}) { - // TODO: implement recover - throw UnimplementedError(); - } - - @override - Future updateUTXOs() async { - // do nothing for now - return false; - } } diff --git a/lib/wallets/wallet/intermediate/lib_monero_wallet.dart b/lib/wallets/wallet/intermediate/lib_monero_wallet.dart new file mode 100644 index 000000000..f1ac98c80 --- /dev/null +++ b/lib/wallets/wallet/intermediate/lib_monero_wallet.dart @@ -0,0 +1,1415 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:math'; + +import 'package:compat/compat.dart' as lib_monero_compat; +import 'package:cs_monero/cs_monero.dart' as lib_monero; +import 'package:isar/isar.dart'; +import 'package:mutex/mutex.dart'; +import 'package:stack_wallet_backup/generate_password.dart'; + +import '../../../db/hive/db.dart'; +import '../../../models/balance.dart'; +import '../../../models/isar/models/blockchain_data/address.dart'; +import '../../../models/isar/models/blockchain_data/transaction.dart'; +import '../../../models/isar/models/blockchain_data/utxo.dart'; +import '../../../models/isar/models/blockchain_data/v2/input_v2.dart'; +import '../../../models/isar/models/blockchain_data/v2/output_v2.dart'; +import '../../../models/isar/models/blockchain_data/v2/transaction_v2.dart'; +import '../../../models/keys/cw_key_data.dart'; +import '../../../models/keys/view_only_wallet_data.dart'; +import '../../../models/paymint/fee_object_model.dart'; +import '../../../services/event_bus/events/global/blocks_remaining_event.dart'; +import '../../../services/event_bus/events/global/refresh_percent_changed_event.dart'; +import '../../../services/event_bus/events/global/tor_connection_status_changed_event.dart'; +import '../../../services/event_bus/events/global/tor_status_changed_event.dart'; +import '../../../services/event_bus/events/global/updated_in_background_event.dart'; +import '../../../services/event_bus/events/global/wallet_sync_status_changed_event.dart'; +import '../../../services/event_bus/global_event_bus.dart'; +import '../../../services/tor_service.dart'; +import '../../../utilities/amount/amount.dart'; +import '../../../utilities/enums/fee_rate_type_enum.dart'; +import '../../../utilities/logger.dart'; +import '../../../utilities/stack_file_system.dart'; +import '../../crypto_currency/intermediate/cryptonote_currency.dart'; +import '../../isar/models/wallet_info.dart'; +import '../../models/tx_data.dart'; +import '../wallet.dart'; +import '../wallet_mixin_interfaces/multi_address_interface.dart'; +import '../wallet_mixin_interfaces/view_only_option_interface.dart'; +import 'cryptonote_wallet.dart'; + +abstract class LibMoneroWallet + extends CryptonoteWallet + with ViewOnlyOptionInterface + implements MultiAddressInterface { + @override + int get isarTransactionVersion => 2; + + LibMoneroWallet(super.currency, this.compatType) { + final bus = GlobalEventBus.instance; + + // Listen for tor status changes. + _torStatusListener = bus.on().listen( + (event) async { + switch (event.newStatus) { + case TorConnectionStatus.connecting: + if (!_torConnectingLock.isLocked) { + await _torConnectingLock.acquire(); + } + _requireMutex = true; + break; + + case TorConnectionStatus.connected: + case TorConnectionStatus.disconnected: + if (_torConnectingLock.isLocked) { + _torConnectingLock.release(); + } + _requireMutex = false; + break; + } + }, + ); + + // Listen for tor preference changes. + _torPreferenceListener = bus.on().listen( + (event) async { + await updateNode(); + }, + ); + + // Potentially dangerous hack. See comments in _startInit() + _startInit(); + } + // cw based wallet listener to handle synchronization of utxo frozen states + late final StreamSubscription> _streamSub; + Future _startInit() async { + // Delay required as `mainDB` is not initialized in constructor. + // This is a hack and could lead to a race condition. + Future.delayed(const Duration(seconds: 2), () { + _streamSub = mainDB.isar.utxos + .where() + .walletIdEqualTo(walletId) + .watch(fireImmediately: true) + .listen((utxos) async { + try { + await onUTXOsChanged(utxos); + await updateBalance(shouldUpdateUtxos: false); + } catch (e, s) { + lib_monero.Logging.log?.i( + "_startInit", + error: e, + stackTrace: s, + ); + } + }); + }); + } + + final lib_monero_compat.WalletType compatType; + lib_monero.Wallet? libMoneroWallet; + + lib_monero_compat.SyncStatus? get syncStatus => _syncStatus; + lib_monero_compat.SyncStatus? _syncStatus; + int _syncedCount = 0; + void _setSyncStatus(lib_monero_compat.SyncStatus status) { + if (status is lib_monero_compat.SyncedSyncStatus) { + if (_syncStatus is lib_monero_compat.SyncedSyncStatus) { + _syncedCount++; + } + } else { + _syncedCount = 0; + } + + if (_syncedCount < 3) { + _syncStatus = status; + syncStatusChanged(); + } + } + + final prepareSendMutex = Mutex(); + final estimateFeeMutex = Mutex(); + + bool _txRefreshLock = false; + int _lastCheckedHeight = -1; + int _txCount = 0; + int currentKnownChainHeight = 0; + double highestPercentCached = 0; + + void loadWallet({required String path, required String password}); + + Future getCreatedWallet({ + required String path, + required String password, + }); + + Future getRestoredWallet({ + required String path, + required String password, + required String mnemonic, + int height = 0, + }); + + Future getRestoredFromViewKeyWallet({ + required String path, + required String password, + required String address, + required String privateViewKey, + int height = 0, + }); + + void invalidSeedLengthCheck(int length); + + bool walletExists(String path); + + void _setListener() { + if (libMoneroWallet != null && libMoneroWallet!.getListeners().isEmpty) { + libMoneroWallet?.addListener( + lib_monero.WalletListener( + onSyncingUpdate: onSyncingUpdate, + onNewBlock: onNewBlock, + onBalancesChanged: onBalancesChanged, + onError: (e, s) { + Logging.instance.log("$e\n$s", level: LogLevel.Warning); + }, + ), + ); + } + } + + Future open() async { + bool wasNull = false; + + if (libMoneroWallet == null) { + wasNull = true; + // libMoneroWalletT?.close(); + final path = await pathForWallet( + name: walletId, + type: compatType, + ); + + final String password; + try { + password = (await secureStorageInterface.read( + key: lib_monero_compat.libMoneroWalletPasswordKey(walletId), + ))!; + } catch (e, s) { + throw Exception("Password not found $e, $s"); + } + + loadWallet(path: path, password: password); + + _setListener(); + + await updateNode(); + } + + Address? currentAddress = await getCurrentReceivingAddress(); + if (currentAddress == null) { + currentAddress = addressFor(index: 0); + await mainDB.updateOrPutAddresses([currentAddress]); + } + if (info.cachedReceivingAddress != currentAddress.value) { + await info.updateReceivingAddress( + newAddress: currentAddress.value, + isar: mainDB.isar, + ); + } + + if (wasNull) { + try { + _setSyncStatus(lib_monero_compat.ConnectingSyncStatus()); + libMoneroWallet?.startSyncing(); + } catch (_) { + _setSyncStatus(lib_monero_compat.FailedSyncStatus()); + // TODO log + } + } + _setListener(); + libMoneroWallet?.startListeners(); + libMoneroWallet?.startAutoSaving(); + + unawaited(refresh()); + } + + @Deprecated("Only used in the case of older wallets") + lib_monero_compat.WalletInfo? getLibMoneroWalletInfo( + String walletId, + ) { + try { + return DB.instance.moneroWalletInfoBox.values.firstWhere( + (info) => info.id == lib_monero_compat.hiveIdFor(walletId, compatType), + ); + } catch (_) { + return null; + } + } + + Future save() async { + if (!Platform.isWindows) { + final appRoot = await StackFileSystem.applicationRootDirectory(); + await lib_monero_compat.backupWalletFiles( + name: walletId, + type: compatType, + appRoot: appRoot, + ); + } + await libMoneroWallet!.save(); + } + + Address addressFor({required int index, int account = 0}) { + final address = libMoneroWallet!.getAddress( + accountIndex: account, + addressIndex: index, + ); + + final newReceivingAddress = Address( + walletId: walletId, + derivationIndex: index, + derivationPath: null, + value: address.value, + publicKey: [], + type: AddressType.cryptonote, + subType: AddressSubType.receiving, + ); + + return newReceivingAddress; + } + + Future getKeys() async { + final base = libMoneroWallet; + + final oldInfo = getLibMoneroWalletInfo( + walletId, + ); + if (base == null || (oldInfo != null && oldInfo.name != walletId)) { + return null; + } + + return CWKeyData( + walletId: walletId, + publicViewKey: base.getPublicViewKey(), + privateViewKey: base.getPrivateViewKey(), + publicSpendKey: base.getPublicSpendKey(), + privateSpendKey: base.getPrivateSpendKey(), + ); + } + + Future<(String, String)> + hackToCreateNewViewOnlyWalletDataFromNewlyCreatedWalletThisFunctionShouldNotBeCalledUnlessYouKnowWhatYouAreDoing() async { + final path = await pathForWallet(name: walletId, type: compatType); + final String password; + try { + password = (await secureStorageInterface.read( + key: lib_monero_compat.libMoneroWalletPasswordKey(walletId), + ))!; + } catch (e, s) { + throw Exception("Password not found $e, $s"); + } + loadWallet(path: path, password: password); + final wallet = libMoneroWallet!; + return (wallet.getAddress().value, wallet.getPrivateViewKey()); + } + + @override + Future init({bool? isRestore}) async { + final path = await pathForWallet( + name: walletId, + type: compatType, + ); + if (!(walletExists(path)) && isRestore != true) { + try { + final password = generatePassword(); + await secureStorageInterface.write( + key: lib_monero_compat.libMoneroWalletPasswordKey(walletId), + value: password, + ); + final wallet = await getCreatedWallet(path: path, password: password); + + final height = wallet.getRefreshFromBlockHeight(); + + await info.updateRestoreHeight( + newRestoreHeight: height, + isar: mainDB.isar, + ); + + // special case for xmr/wow. Normally mnemonic + passphrase is saved + // before wallet.init() is called + await secureStorageInterface.write( + key: Wallet.mnemonicKey(walletId: walletId), + value: wallet.getSeed().trim(), + ); + await secureStorageInterface.write( + key: Wallet.mnemonicPassphraseKey(walletId: walletId), + value: "", + ); + } catch (e, s) { + Logging.instance.log("$e\n$s", level: LogLevel.Fatal); + } + await updateNode(); + } + + return super.init(); + } + + @override + Future recover({required bool isRescan}) async { + if (isRescan) { + await refreshMutex.protect(() async { + // clear blockchain info + await mainDB.deleteWalletBlockchainData(walletId); + + highestPercentCached = 0; + unawaited(libMoneroWallet?.rescanBlockchain()); + libMoneroWallet?.startSyncing(); + // unawaited(save()); + }); + unawaited(refresh()); + return; + } + + if (isViewOnly) { + await recoverViewOnly(); + return; + } + + await refreshMutex.protect(() async { + final mnemonic = await getMnemonic(); + final seedLength = mnemonic.trim().split(" ").length; + + invalidSeedLengthCheck(seedLength); + + try { + final height = max(info.restoreHeight, 0); + + await info.updateRestoreHeight( + newRestoreHeight: height, + isar: mainDB.isar, + ); + + final String name = walletId; + + final path = await pathForWallet( + name: name, + type: compatType, + ); + + try { + final password = generatePassword(); + await secureStorageInterface.write( + key: lib_monero_compat.libMoneroWalletPasswordKey(walletId), + value: password, + ); + final wallet = await getRestoredWallet( + path: path, + password: password, + mnemonic: mnemonic, + height: height, + ); + + if (libMoneroWallet != null) { + await exit(); + } + + libMoneroWallet = wallet; + + _setListener(); + + final newReceivingAddress = await getCurrentReceivingAddress() ?? + Address( + walletId: walletId, + derivationIndex: 0, + derivationPath: null, + value: wallet.getAddress().value, + publicKey: [], + type: AddressType.cryptonote, + subType: AddressSubType.receiving, + ); + + await mainDB.updateOrPutAddresses([newReceivingAddress]); + await info.updateReceivingAddress( + newAddress: newReceivingAddress.value, + isar: mainDB.isar, + ); + } catch (e, s) { + Logging.instance.log("$e\n$s", level: LogLevel.Fatal); + } + await updateNode(); + _setListener(); + + // libMoneroWallet?.setRecoveringFromSeed(isRecovery: true); + unawaited(libMoneroWallet?.rescanBlockchain()); + libMoneroWallet?.startSyncing(); + + // await save(); + libMoneroWallet?.startListeners(); + libMoneroWallet?.startAutoSaving(); + } catch (e, s) { + Logging.instance.log( + "Exception rethrown from recoverFromMnemonic(): $e\n$s", + level: LogLevel.Error, + ); + rethrow; + } + }); + } + + @override + Future pingCheck() async { + return (await libMoneroWallet?.isConnectedToDaemon()) ?? false; + } + + @override + Future updateNode() async { + final node = getCurrentNode(); + + final host = Uri.parse(node.host).host; + ({InternetAddress host, int port})? proxy; + if (prefs.useTor) { + proxy = TorService.sharedInstance.getProxyInfo(); + } + + _setSyncStatus(lib_monero_compat.ConnectingSyncStatus()); + try { + if (_requireMutex) { + await _torConnectingLock.protect(() async { + await libMoneroWallet?.connect( + daemonAddress: "$host:${node.port}", + daemonUsername: node.loginName, + daemonPassword: await node.getPassword(secureStorageInterface), + trusted: node.trusted ?? false, + useSSL: node.useSSL, + socksProxyAddress: + proxy == null ? null : "${proxy.host.address}:${proxy.port}", + ); + }); + } else { + await libMoneroWallet?.connect( + daemonAddress: "$host:${node.port}", + daemonUsername: node.loginName, + daemonPassword: await node.getPassword(secureStorageInterface), + trusted: node.trusted ?? false, + useSSL: node.useSSL, + socksProxyAddress: + proxy == null ? null : "${proxy.host.address}:${proxy.port}", + ); + } + + _setSyncStatus(lib_monero_compat.ConnectedSyncStatus()); + } catch (e, s) { + _setSyncStatus(lib_monero_compat.FailedSyncStatus()); + Logging.instance.log( + "Exception caught in $runtimeType.updateNode(): $e\n$s", + level: LogLevel.Error, + ); + } + + return; + } + + @override + Future updateTransactions() async { + final base = libMoneroWallet; + + if (base == null) { + return; + } + + final transactions = await base.getTxs(refresh: true); + + final allOutputs = await base.getOutputs(includeSpent: true, refresh: true); + + // final cachedTransactions = + // DB.instance.get(boxName: walletId, key: 'latest_tx_model') + // as TransactionData?; + // int latestTxnBlockHeight = + // DB.instance.get(boxName: walletId, key: "storedTxnDataHeight") + // as int? ?? + // 0; + // + // final txidsList = DB.instance + // .get(boxName: walletId, key: "cachedTxids") as List? ?? + // []; + // + // final Set cachedTxids = Set.from(txidsList); + + // TODO: filter to skip cached + confirmed txn processing in next step + // final unconfirmedCachedTransactions = + // cachedTransactions?.getAllTransactions() ?? {}; + // unconfirmedCachedTransactions + // .removeWhere((key, value) => value.confirmedStatus); + // + // if (cachedTransactions != null) { + // for (final tx in allTxHashes.toList(growable: false)) { + // final txHeight = tx["height"] as int; + // if (txHeight > 0 && + // txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) { + // if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) { + // allTxHashes.remove(tx); + // } + // } + // } + // } + + final List txns = []; + + for (final tx in transactions) { + final associatedOutputs = allOutputs.where((e) => e.hash == tx.hash); + final List inputs = []; + final List outputs = []; + TransactionType type; + if (!tx.isSpend) { + type = TransactionType.incoming; + for (final output in associatedOutputs) { + outputs.add( + OutputV2.isarCantDoRequiredInDefaultConstructor( + scriptPubKeyHex: "", + valueStringSats: output.value.toString(), + addresses: [output.address], + walletOwns: true, + ), + ); + } + } else { + type = TransactionType.outgoing; + for (final output in associatedOutputs) { + inputs.add( + InputV2.isarCantDoRequiredInDefaultConstructor( + scriptSigHex: null, + scriptSigAsm: null, + sequence: null, + outpoint: null, + addresses: [output.address], + valueStringSats: output.value.toString(), + witness: null, + innerRedeemScriptAsm: null, + coinbase: null, + walletOwns: true, + ), + ); + } + } + + final txn = TransactionV2( + walletId: walletId, + blockHash: null, // not exposed via current cs_monero + hash: tx.hash, + txid: tx.hash, + timestamp: (tx.timeStamp.millisecondsSinceEpoch ~/ 1000), + height: tx.blockHeight, + inputs: inputs, + outputs: outputs, + version: -1, // not exposed via current cs_monero + type: type, + subType: TransactionSubType.none, + otherData: jsonEncode({ + TxV2OdKeys.overrideFee: Amount( + rawValue: tx.fee, + fractionDigits: cryptoCurrency.fractionDigits, + ).toJsonString(), + TxV2OdKeys.moneroAmount: Amount( + rawValue: tx.amount, + fractionDigits: cryptoCurrency.fractionDigits, + ).toJsonString(), + TxV2OdKeys.moneroAccountIndex: tx.accountIndex, + TxV2OdKeys.isMoneroTransaction: true, + }), + ); + + txns.add(txn); + } + + await mainDB.updateOrPutTransactionV2s(txns); + } + + Future get availableBalance async { + try { + return Amount( + rawValue: libMoneroWallet!.getUnlockedBalance(), + fractionDigits: cryptoCurrency.fractionDigits, + ); + } catch (_) { + return info.cachedBalance.spendable; + } + } + + Future get totalBalance async { + try { + final full = libMoneroWallet?.getBalance(); + if (full != null) { + return Amount( + rawValue: full, + fractionDigits: cryptoCurrency.fractionDigits, + ); + } else { + final transactions = await libMoneroWallet!.getTxs(refresh: true); + BigInt transactionBalance = BigInt.zero; + for (final tx in transactions) { + if (!tx.isSpend) { + transactionBalance += tx.amount; + } else { + transactionBalance += -tx.amount - tx.fee; + } + } + + return Amount( + rawValue: transactionBalance, + fractionDigits: cryptoCurrency.fractionDigits, + ); + } + } catch (_) { + return info.cachedBalance.total; + } + } + + @override + Future exit() async { + libMoneroWallet?.stopAutoSaving(); + libMoneroWallet?.stopListeners(); + libMoneroWallet?.stopSyncing(); + await libMoneroWallet?.save(); + } + + Future pathForWalletDir({ + required String name, + required lib_monero_compat.WalletType type, + }) async { + final Directory root = await StackFileSystem.applicationRootDirectory(); + return lib_monero_compat.pathForWalletDir( + name: name, + type: type.name.toLowerCase(), + appRoot: root, + ); + } + + Future pathForWallet({ + required String name, + required lib_monero_compat.WalletType type, + }) async => + await pathForWalletDir(name: name, type: type) + .then((path) => '$path/$name'); + + void onSyncingUpdate({ + required int syncHeight, + required int nodeHeight, + String? message, + }) { + if (nodeHeight > 0 && syncHeight >= 0) { + currentKnownChainHeight = nodeHeight; + updateChainHeight(); + final blocksLeft = nodeHeight - syncHeight; + final lib_monero_compat.SyncStatus status; + if (blocksLeft < 100) { + status = lib_monero_compat.SyncedSyncStatus(); + + // if (!_hasSyncAfterStartup) { + // _hasSyncAfterStartup = true; + // await save(); + // } + // + // if (walletInfo.isRecovery!) { + // await setAsRecovered(); + // } + } else { + final percent = syncHeight / currentKnownChainHeight; + + status = lib_monero_compat.SyncingSyncStatus( + blocksLeft, + percent, + currentKnownChainHeight, + ); + } + + _setSyncStatus(status); + _refreshTxDataHelper(); + } + } + + void onBalancesChanged({ + required BigInt newBalance, + required BigInt newUnlockedBalance, + }) { + // do something? + } + + void onNewBlock(int nodeHeight) { + // do something? + } + + final _utxosUpdateLock = Mutex(); + Future onUTXOsChanged(List utxos) async { + await _utxosUpdateLock.protect(() async { + final cwUtxos = await libMoneroWallet?.getOutputs(refresh: true) ?? []; + + // bool changed = false; + + for (final cw in cwUtxos) { + final match = utxos.where( + (e) => + e.keyImage != null && + e.keyImage!.isNotEmpty && + e.keyImage == cw.keyImage, + ); + + if (match.isNotEmpty) { + final u = match.first; + + if (u.isBlocked) { + if (!cw.isFrozen) { + await libMoneroWallet?.freezeOutput(cw.keyImage); + // changed = true; + } + } else { + if (cw.isFrozen) { + await libMoneroWallet?.thawOutput(cw.keyImage); + // changed = true; + } + } + } + } + + // if (changed) { + // await libMoneroWallet?.updateUTXOs(); + // } + }); + } + + void onNewTransaction() { + // TODO: [prio=low] get rid of UpdatedInBackgroundEvent and move to + // adding the v2 tx to the db which would update ui automagically since the + // db is watched by the ui + // call this here? + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "New data found in $walletId ${info.name} in background!", + walletId, + ), + ); + } + + void syncStatusChanged() async { + final _syncStatus = syncStatus; + + if (_syncStatus != null) { + if (_syncStatus.progress() == 1 && refreshMutex.isLocked) { + refreshMutex.release(); + } + + WalletSyncStatus? status; + xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(true); + + if (_syncStatus is lib_monero_compat.SyncingSyncStatus) { + final int blocksLeft = _syncStatus.blocksLeft; + + // ensure at least 1 to prevent math errors + final int height = max(1, _syncStatus.height); + + final nodeHeight = height + blocksLeft; + currentKnownChainHeight = nodeHeight; + + // final percent = height / nodeHeight; + final percent = _syncStatus.ptc; + + final highest = max(highestPercentCached, percent); + + final unchanged = highest == highestPercentCached; + if (unchanged) { + return; + } + + // update cached + if (highestPercentCached < percent) { + highestPercentCached = percent; + } + + GlobalEventBus.instance.fire( + RefreshPercentChangedEvent( + highest, + walletId, + ), + ); + GlobalEventBus.instance.fire( + BlocksRemainingEvent( + blocksLeft, + walletId, + ), + ); + } else if (_syncStatus is lib_monero_compat.SyncedSyncStatus) { + status = WalletSyncStatus.synced; + } else if (_syncStatus is lib_monero_compat.NotConnectedSyncStatus) { + status = WalletSyncStatus.unableToSync; + xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(false); + } else if (_syncStatus is lib_monero_compat.StartingSyncStatus) { + status = WalletSyncStatus.syncing; + GlobalEventBus.instance.fire( + RefreshPercentChangedEvent( + highestPercentCached, + walletId, + ), + ); + } else if (_syncStatus is lib_monero_compat.FailedSyncStatus) { + status = WalletSyncStatus.unableToSync; + xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(false); + } else if (_syncStatus is lib_monero_compat.ConnectingSyncStatus) { + status = WalletSyncStatus.syncing; + GlobalEventBus.instance.fire( + RefreshPercentChangedEvent( + highestPercentCached, + walletId, + ), + ); + } else if (_syncStatus is lib_monero_compat.ConnectedSyncStatus) { + status = WalletSyncStatus.syncing; + GlobalEventBus.instance.fire( + RefreshPercentChangedEvent( + highestPercentCached, + walletId, + ), + ); + } else if (_syncStatus is lib_monero_compat.LostConnectionSyncStatus) { + status = WalletSyncStatus.unableToSync; + xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(false); + } + + if (status != null) { + GlobalEventBus.instance.fire( + WalletSyncStatusChangedEvent( + status, + walletId, + info.coin, + ), + ); + } + } + } + + @override + Future checkSaveInitialReceivingAddress() async { + // this doesn't work without opening the wallet first which takes a while + } + + // ============ Private ====================================================== + Future _refreshTxDataHelper() async { + if (_txRefreshLock) return; + _txRefreshLock = true; + + final _syncStatus = syncStatus; + + if (_syncStatus != null && + _syncStatus is lib_monero_compat.SyncingSyncStatus) { + final int blocksLeft = _syncStatus.blocksLeft; + final tenKChange = blocksLeft ~/ 10000; + + // only refresh transactions periodically during a sync + if (_lastCheckedHeight == -1 || tenKChange < _lastCheckedHeight) { + _lastCheckedHeight = tenKChange; + await _refreshTxData(); + } + } else { + await _refreshTxData(); + } + + _txRefreshLock = false; + } + + Future _refreshTxData() async { + await updateTransactions(); + final count = await mainDB.getTransactions(walletId).count(); + + if (count > _txCount) { + _txCount = count; + await updateBalance(); + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "New transaction data found in $walletId ${info.name}!", + walletId, + ), + ); + } + } + + // ============ Overrides ==================================================== + + @override + FilterOperation? get changeAddressFilterOperation => null; + + @override + FilterOperation? get receivingAddressFilterOperation => null; + + @override + Future updateUTXOs() async { + final List outputArray = []; + final utxos = await libMoneroWallet?.getOutputs(refresh: true) ?? + []; + for (final rawUTXO in utxos) { + if (!rawUTXO.spent) { + final current = await mainDB.isar.utxos + .where() + .walletIdEqualTo(walletId) + .filter() + .voutEqualTo(rawUTXO.vout) + .and() + .txidEqualTo(rawUTXO.hash) + .findFirst(); + final tx = await mainDB.isar.transactionV2s + .where() + .walletIdEqualTo(walletId) + .filter() + .txidEqualTo(rawUTXO.hash) + .findFirst(); + + final otherDataMap = { + "keyImage": rawUTXO.keyImage, + "spent": rawUTXO.spent, + }; + + final utxo = UTXO( + address: rawUTXO.address, + walletId: walletId, + txid: rawUTXO.hash, + vout: rawUTXO.vout, + value: rawUTXO.value.toInt(), + name: current?.name ?? "", + isBlocked: current?.isBlocked ?? rawUTXO.isFrozen, + blockedReason: current?.blockedReason ?? "", + isCoinbase: rawUTXO.coinbase, + blockHash: "", + blockHeight: + tx?.height ?? (rawUTXO.height > 0 ? rawUTXO.height : null), + blockTime: tx?.timestamp, + otherData: jsonEncode(otherDataMap), + ); + + outputArray.add(utxo); + } + } + + await mainDB.updateUTXOs(walletId, outputArray); + + return true; + } + + @override + Future updateBalance({bool shouldUpdateUtxos = true}) async { + if (shouldUpdateUtxos) { + await updateUTXOs(); + } + + final total = await totalBalance; + final available = await availableBalance; + + final balance = Balance( + total: total, + spendable: available, + blockedTotal: Amount( + rawValue: BigInt.zero, + fractionDigits: cryptoCurrency.fractionDigits, + ), + pendingSpendable: total - available, + ); + + await info.updateBalance(newBalance: balance, isar: mainDB.isar); + } + + @override + Future refresh() async { + // Awaiting this lock could be dangerous. + // Since refresh is periodic (generally) + if (refreshMutex.isLocked) { + return; + } + + // this acquire should be almost instant due to above check. + // Slight possibility of race but should be irrelevant + await refreshMutex.acquire(); + + libMoneroWallet?.startSyncing(); + _setSyncStatus(lib_monero_compat.StartingSyncStatus()); + + await updateTransactions(); + await updateBalance(); + + if (info.otherData[WalletInfoKeys.reuseAddress] != true) { + await checkReceivingAddressForTransactions(); + } + + if (refreshMutex.isLocked) { + refreshMutex.release(); + } + + final synced = await libMoneroWallet?.isSynced(); + + if (synced == true) { + _setSyncStatus(lib_monero_compat.SyncedSyncStatus()); + } + } + + @override + Future generateNewReceivingAddress() async { + try { + final currentReceiving = await getCurrentReceivingAddress(); + + final newReceivingIndex = + currentReceiving == null ? 0 : currentReceiving.derivationIndex + 1; + + final newReceivingAddress = addressFor(index: newReceivingIndex); + + // Add that new receiving address + await mainDB.putAddress(newReceivingAddress); + await info.updateReceivingAddress( + newAddress: newReceivingAddress.value, + isar: mainDB.isar, + ); + } catch (e, s) { + Logging.instance.log( + "Exception in generateNewAddress(): $e\n$s", + level: LogLevel.Error, + ); + } + } + + @override + Future checkReceivingAddressForTransactions() async { + if (info.otherData[WalletInfoKeys.reuseAddress] == true) { + try { + throw Exception(); + } catch (_, s) { + Logging.instance.log( + "checkReceivingAddressForTransactions called but reuse address flag set: $s", + level: LogLevel.Error, + ); + } + } + + try { + int highestIndex = -1; + final entries = await libMoneroWallet?.getTxs(refresh: true); + if (entries != null) { + for (final element in entries) { + if (!element.isSpend) { + final int curAddressIndex = element.addressIndexes.isEmpty + ? 0 + : element.addressIndexes.reduce(max); + if (curAddressIndex > highestIndex) { + highestIndex = curAddressIndex; + } + } + } + } + + // Check the new receiving index + final currentReceiving = await getCurrentReceivingAddress(); + final curIndex = currentReceiving?.derivationIndex ?? -1; + + if (highestIndex >= curIndex) { + // First increment the receiving index + final newReceivingIndex = curIndex + 1; + + // Use new index to derive a new receiving address + final newReceivingAddress = addressFor(index: newReceivingIndex); + + final existing = await mainDB + .getAddresses(walletId) + .filter() + .valueEqualTo(newReceivingAddress.value) + .findFirst(); + if (existing == null) { + // Add that new change address + await mainDB.putAddress(newReceivingAddress); + } else { + // we need to update the address + await mainDB.updateAddress(existing, newReceivingAddress); + } + if (info.otherData[WalletInfoKeys.reuseAddress] != true) { + // keep checking until address with no tx history is set as current + await checkReceivingAddressForTransactions(); + } + } + } on SocketException catch (se, s) { + Logging.instance.log( + "SocketException caught in _checkReceivingAddressForTransactions(): $se\n$s", + level: LogLevel.Error, + ); + return; + } catch (e, s) { + Logging.instance.log( + "Exception rethrown from _checkReceivingAddressForTransactions(): $e\n$s", + level: LogLevel.Error, + ); + rethrow; + } + } + + // TODO: this needs some work. Prio's may need to be changed as well as estimated blocks + @override + Future get fees async => FeeObject( + numberOfBlocksFast: 10, + numberOfBlocksAverage: 15, + numberOfBlocksSlow: 20, + fast: lib_monero.TransactionPriority.high.value, + medium: lib_monero.TransactionPriority.medium.value, + slow: lib_monero.TransactionPriority.normal.value, + ); + + @override + Future updateChainHeight() async { + await info.updateCachedChainHeight( + newHeight: currentKnownChainHeight, + isar: mainDB.isar, + ); + } + + @override + Future checkChangeAddressForTransactions() async { + // do nothing + } + + @override + Future generateNewChangeAddress() async { + // do nothing + } + + @override + Future prepareSend({required TxData txData}) async { + try { + final feeRate = txData.feeRateType; + if (feeRate is FeeRateType) { + lib_monero.TransactionPriority feePriority; + switch (feeRate) { + case FeeRateType.fast: + feePriority = lib_monero.TransactionPriority.high; + break; + case FeeRateType.average: + feePriority = lib_monero.TransactionPriority.medium; + break; + case FeeRateType.slow: + feePriority = lib_monero.TransactionPriority.normal; + break; + default: + throw ArgumentError("Invalid use of custom fee"); + } + + try { + final bool sweep; + + if (txData.utxos == null) { + final balance = await availableBalance; + sweep = txData.amount! == balance; + } else { + final totalInputsValue = txData.utxos! + .map((e) => e.value) + .fold(BigInt.zero, (p, e) => p + BigInt.from(e)); + sweep = txData.amount!.raw == totalInputsValue; + } + + // TODO: test this one day + // cs_monero may not support this yet properly + if (sweep && txData.recipients!.length > 1) { + throw Exception("Send all not supported with multiple recipients"); + } + + final List outputs = []; + for (final recipient in txData.recipients!) { + final output = lib_monero.Recipient( + address: recipient.address, + amount: recipient.amount.raw, + ); + + outputs.add(output); + } + + if (outputs.isEmpty) { + throw Exception("No recipients provided"); + } + + final height = await chainHeight; + final inputs = txData.utxos + ?.map( + (e) => lib_monero.Output( + address: e.address!, + hash: e.txid, + keyImage: e.keyImage!, + value: BigInt.from(e.value), + isFrozen: e.isBlocked, + isUnlocked: e.blockHeight != null && + (height - (e.blockHeight ?? 0)) >= + cryptoCurrency.minConfirms, + height: e.blockHeight ?? 0, + vout: e.vout, + spent: e.used ?? false, + spentHeight: null, // doesn't matter here + coinbase: e.isCoinbase, + ), + ) + .toList(); + + return await prepareSendMutex.protect(() async { + final lib_monero.PendingTransaction pendingTransaction; + if (outputs.length == 1) { + pendingTransaction = await libMoneroWallet!.createTx( + output: outputs.first, + paymentId: "", + sweep: sweep, + priority: feePriority, + preferredInputs: inputs, + accountIndex: 0, // sw only uses account 0 at this time + ); + } else { + pendingTransaction = await libMoneroWallet!.createTxMultiDest( + outputs: outputs, + paymentId: "", + priority: feePriority, + preferredInputs: inputs, + sweep: sweep, + accountIndex: 0, // sw only uses account 0 at this time + ); + } + + final realFee = Amount( + rawValue: pendingTransaction.fee, + fractionDigits: cryptoCurrency.fractionDigits, + ); + + return txData.copyWith( + fee: realFee, + pendingTransaction: pendingTransaction, + ); + }); + } catch (e) { + rethrow; + } + } else { + throw ArgumentError("Invalid fee rate argument provided!"); + } + } catch (e, s) { + Logging.instance.log( + "Exception rethrown from prepare send(): $e\n$s", + level: LogLevel.Info, + ); + + if (e.toString().contains("Incorrect unlocked balance")) { + throw Exception("Insufficient balance!"); + } else { + throw Exception("Transaction failed with error: $e"); + } + } + } + + @override + Future confirmSend({required TxData txData}) async { + try { + try { + await libMoneroWallet!.commitTx( + txData.pendingTransaction!, + ); + + Logging.instance.log( + "transaction ${txData.pendingTransaction!.txid} has been sent", + level: LogLevel.Info, + ); + return txData.copyWith(txid: txData.pendingTransaction!.txid); + } catch (e, s) { + Logging.instance.log( + "${info.name} ${compatType.name.toLowerCase()} confirmSend: $e\n$s", + level: LogLevel.Error, + ); + rethrow; + } + } catch (e, s) { + Logging.instance.log( + "Exception rethrown from confirmSend(): $e\n$s", + level: LogLevel.Info, + ); + rethrow; + } + } + + // ============== View only ================================================== + + @override + Future recoverViewOnly() async { + await refreshMutex.protect(() async { + final data = + await getViewOnlyWalletData() as CryptonoteViewOnlyWalletData; + + try { + final height = max(info.restoreHeight, 0); + + await info.updateRestoreHeight( + newRestoreHeight: height, + isar: mainDB.isar, + ); + + final String name = walletId; + + final path = await pathForWallet( + name: name, + type: compatType, + ); + + final password = generatePassword(); + await secureStorageInterface.write( + key: lib_monero_compat.libMoneroWalletPasswordKey(walletId), + value: password, + ); + final wallet = await getRestoredFromViewKeyWallet( + path: path, + password: password, + address: data.address, + privateViewKey: data.privateViewKey, + height: height, + ); + + if (libMoneroWallet != null) { + await exit(); + } + + libMoneroWallet = wallet; + + _setListener(); + + final newReceivingAddress = await getCurrentReceivingAddress() ?? + Address( + walletId: walletId, + derivationIndex: 0, + derivationPath: null, + value: wallet.getAddress().value, + publicKey: [], + type: AddressType.cryptonote, + subType: AddressSubType.receiving, + ); + + await mainDB.updateOrPutAddresses([newReceivingAddress]); + await info.updateReceivingAddress( + newAddress: newReceivingAddress.value, + isar: mainDB.isar, + ); + + await updateNode(); + _setListener(); + + unawaited(libMoneroWallet?.rescanBlockchain()); + libMoneroWallet?.startSyncing(); + + // await save(); + libMoneroWallet?.startListeners(); + libMoneroWallet?.startAutoSaving(); + } catch (e, s) { + Logging.instance.log( + "Exception rethrown from recoverViewOnly(): $e\n$s", + level: LogLevel.Error, + ); + rethrow; + } + }); + } + + // ============== Private ==================================================== + + StreamSubscription? _torStatusListener; + StreamSubscription? _torPreferenceListener; + + final Mutex _torConnectingLock = Mutex(); + bool _requireMutex = false; +} diff --git a/lib/wallets/wallet/wallet.dart b/lib/wallets/wallet/wallet.dart index 4837eb8d3..0beaf2a80 100644 --- a/lib/wallets/wallet/wallet.dart +++ b/lib/wallets/wallet/wallet.dart @@ -7,6 +7,7 @@ import 'package:mutex/mutex.dart'; import '../../db/isar/main_db.dart'; import '../../models/isar/models/blockchain_data/address.dart'; import '../../models/isar/models/ethereum/eth_contract.dart'; +import '../../models/keys/view_only_wallet_data.dart'; import '../../models/node_model.dart'; import '../../models/paymint/fee_object_model.dart'; import '../../services/event_bus/events/global/node_connection_status_changed_event.dart'; @@ -28,6 +29,7 @@ import 'impl/banano_wallet.dart'; import 'impl/bitcoin_frost_wallet.dart'; import 'impl/bitcoin_wallet.dart'; import 'impl/bitcoincash_wallet.dart'; +import 'impl/cardano_wallet.dart'; import 'impl/dash_wallet.dart'; import 'impl/dogecoin_wallet.dart'; import 'impl/ecash_wallet.dart'; @@ -53,6 +55,7 @@ import 'wallet_mixin_interfaces/multi_address_interface.dart'; import 'wallet_mixin_interfaces/paynym_interface.dart'; import 'wallet_mixin_interfaces/private_key_interface.dart'; import 'wallet_mixin_interfaces/spark_interface.dart'; +import 'wallet_mixin_interfaces/view_only_option_interface.dart'; abstract class Wallet { // default to Transaction class. For TransactionV2 set to 2 @@ -144,7 +147,13 @@ abstract class Wallet { String? mnemonic, String? mnemonicPassphrase, String? privateKey, + ViewOnlyWalletData? viewOnlyData, }) async { + // TODO: rework soon? + if (walletInfo.isViewOnly && viewOnlyData == null) { + throw Exception("Missing view key while creating view only wallet!"); + } + final Wallet wallet = await _construct( walletInfo: walletInfo, mainDB: mainDB, @@ -153,7 +162,12 @@ abstract class Wallet { prefs: prefs, ); - if (wallet is MnemonicInterface) { + if (wallet is ViewOnlyOptionInterface && walletInfo.isViewOnly) { + await secureStorageInterface.write( + key: getViewOnlyWalletDataSecStoreKey(walletId: walletInfo.walletId), + value: viewOnlyData!.toJsonEncodedString(), + ); + } else if (wallet is MnemonicInterface) { if (wallet is CryptonoteWallet) { // currently a special case due to the xmr/wow libraries handling their // own mnemonic generation on new wallet creation @@ -278,6 +292,12 @@ abstract class Wallet { }) => "${walletId}_privateKey"; + // secure storage key + static String getViewOnlyWalletDataSecStoreKey({ + required String walletId, + }) => + "${walletId}_viewOnlyWalletData"; + //============================================================================ // ========== Private ======================================================== @@ -324,6 +344,9 @@ abstract class Wallet { case const (Bitcoincash): return BitcoincashWallet(net); + case const (Cardano): + return CardanoWallet(net); + case const (Dash): return DashWallet(net); @@ -407,6 +430,17 @@ abstract class Wallet { ); _isConnected = hasNetwork; + + if (status == NodeConnectionStatus.disconnected) { + GlobalEventBus.instance.fire( + WalletSyncStatusChangedEvent( + WalletSyncStatus.unableToSync, + walletId, + cryptoCurrency, + ), + ); + } + if (hasNetwork) { unawaited(refresh()); } @@ -472,6 +506,61 @@ abstract class Wallet { // Should fire events Future refresh() async { + final refreshCompleter = Completer(); + final future = refreshCompleter.future.then( + (_) { + GlobalEventBus.instance.fire( + WalletSyncStatusChangedEvent( + WalletSyncStatus.synced, + walletId, + cryptoCurrency, + ), + ); + + if (shouldAutoSync) { + _periodicRefreshTimer ??= + Timer.periodic(const Duration(seconds: 150), (timer) async { + // chain height check currently broken + // if ((await chainHeight) != (await storedChainHeight)) { + + // TODO: [prio=med] some kind of quick check if wallet needs to refresh to replace the old refreshIfThereIsNewData call + // if (await refreshIfThereIsNewData()) { + unawaited(refresh()); + + // } + // } + }); + } + }, + onError: (Object error, StackTrace strace) { + GlobalEventBus.instance.fire( + NodeConnectionStatusChangedEvent( + NodeConnectionStatus.disconnected, + walletId, + cryptoCurrency, + ), + ); + GlobalEventBus.instance.fire( + WalletSyncStatusChangedEvent( + WalletSyncStatus.unableToSync, + walletId, + cryptoCurrency, + ), + ); + Logging.instance.log( + "Caught exception in refreshWalletData(): $error\n$strace", + level: LogLevel.Error, + ); + }, + ); + + unawaited(_refresh(refreshCompleter)); + + return future; + } + + // Should fire events + Future _refresh(Completer completer) async { // Awaiting this lock could be dangerous. // Since refresh is periodic (generally) if (refreshMutex.isLocked) { @@ -479,6 +568,25 @@ abstract class Wallet { } final start = DateTime.now(); + bool tAlive = true; + final t = Timer.periodic(const Duration(seconds: 1), (timer) async { + if (tAlive) { + final pingSuccess = await pingCheck(); + if (!pingSuccess) { + tAlive = false; + } + } else { + timer.cancel(); + } + }); + + void _checkAlive() { + if (!tAlive) throw Exception("refresh alive ping failure"); + } + + final viewOnly = this is ViewOnlyOptionInterface && + (this as ViewOnlyOptionInterface).isViewOnly; + try { // this acquire should be almost instant due to above check. // Slight possibility of race but should be irrelevant @@ -492,136 +600,137 @@ abstract class Wallet { ), ); + _checkAlive(); + // add some small buffer before making calls. // this can probably be removed in the future but was added as a // debugging feature await Future.delayed(const Duration(milliseconds: 300)); + _checkAlive(); // TODO: [prio=low] handle this differently. Extra modification of this file for coin specific functionality should be avoided. final Set codesToCheck = {}; - if (this is PaynymInterface) { + _checkAlive(); + if (this is PaynymInterface && !viewOnly) { // isSegwit does not matter here at all final myCode = await (this as PaynymInterface).getPaymentCode(isSegwit: false); + _checkAlive(); final nym = await PaynymIsApi().nym(myCode.toString()); + _checkAlive(); if (nym.value != null) { for (final follower in nym.value!.followers) { codesToCheck.add(follower.code); } + _checkAlive(); for (final following in nym.value!.following) { codesToCheck.add(following.code); } } + _checkAlive(); } GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.0, walletId)); + _checkAlive(); await updateChainHeight(); + _checkAlive(); if (this is BitcoinFrostWallet) { await (this as BitcoinFrostWallet).lookAhead(); } + _checkAlive(); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.1, walletId)); + _checkAlive(); // TODO: [prio=low] handle this differently. Extra modification of this file for coin specific functionality should be avoided. if (this is MultiAddressInterface) { if (info.otherData[WalletInfoKeys.reuseAddress] != true) { await (this as MultiAddressInterface) .checkReceivingAddressForTransactions(); } + _checkAlive(); } GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.2, walletId)); + _checkAlive(); // TODO: [prio=low] handle this differently. Extra modification of this file for coin specific functionality should be avoided. if (this is MultiAddressInterface) { - await (this as MultiAddressInterface) - .checkChangeAddressForTransactions(); + if (info.otherData[WalletInfoKeys.reuseAddress] != true) { + await (this as MultiAddressInterface) + .checkChangeAddressForTransactions(); + } } + _checkAlive(); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId)); - if (this is SparkInterface) { + if (this is SparkInterface && !viewOnly) { // this should be called before updateTransactions() await (this as SparkInterface).refreshSparkData(); } + _checkAlive(); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.50, walletId)); + _checkAlive(); final fetchFuture = updateTransactions(); + _checkAlive(); final utxosRefreshFuture = updateUTXOs(); // if (currentHeight != storedHeight) { GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.60, walletId)); + _checkAlive(); await utxosRefreshFuture; GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.70, walletId)); + _checkAlive(); await fetchFuture; // TODO: [prio=low] handle this differently. Extra modification of this file for coin specific functionality should be avoided. - if (this is PaynymInterface && codesToCheck.isNotEmpty) { + if (!viewOnly && this is PaynymInterface && codesToCheck.isNotEmpty) { + _checkAlive(); await (this as PaynymInterface) .checkForNotificationTransactionsTo(codesToCheck); // check utxos again for notification outputs + _checkAlive(); await updateUTXOs(); } + _checkAlive(); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.80, walletId)); // await getAllTxsToWatch(); + _checkAlive(); // TODO: [prio=low] handle this differently. Extra modification of this file for coin specific functionality should be avoided. - if (this is LelantusInterface) { + if (this is LelantusInterface && !viewOnly) { if (info.otherData[WalletInfoKeys.enableLelantusScanning] as bool? ?? false) { await (this as LelantusInterface).refreshLelantusData(); + _checkAlive(); } } GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.90, walletId)); + _checkAlive(); await updateBalance(); + _checkAlive(); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(1.0, walletId)); - GlobalEventBus.instance.fire( - WalletSyncStatusChangedEvent( - WalletSyncStatus.synced, - walletId, - cryptoCurrency, - ), - ); - if (shouldAutoSync) { - _periodicRefreshTimer ??= - Timer.periodic(const Duration(seconds: 150), (timer) async { - // chain height check currently broken - // if ((await chainHeight) != (await storedChainHeight)) { + tAlive = false; // interrupt timer as its not needed anymore - // TODO: [prio=med] some kind of quick check if wallet needs to refresh to replace the old refreshIfThereIsNewData call - // if (await refreshIfThereIsNewData()) { - unawaited(refresh()); - - // } - // } - }); - } + completer.complete(); } catch (error, strace) { - GlobalEventBus.instance.fire( - NodeConnectionStatusChangedEvent( - NodeConnectionStatus.disconnected, - walletId, - cryptoCurrency, - ), - ); - GlobalEventBus.instance.fire( - WalletSyncStatusChangedEvent( - WalletSyncStatus.unableToSync, - walletId, - cryptoCurrency, - ), - ); - Logging.instance.log( - "Caught exception in refreshWalletData(): $error\n$strace", - level: LogLevel.Error, - ); + completer.completeError(error, strace); } finally { + t.cancel(); refreshMutex.release(); + if (!completer.isCompleted) { + completer.completeError( + "finally block hit before completer completed", + StackTrace.current, + ); + } Logging.instance.log( "Refresh for " diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart index 36cd710fd..f72ec36b2 100644 --- a/lib/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart +++ b/lib/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart @@ -1,7 +1,7 @@ -import '../../crypto_currency/intermediate/bip39_hd_currency.dart'; -import '../intermediate/bip39_hd_wallet.dart'; +import '../../crypto_currency/crypto_currency.dart'; +import '../wallet.dart'; -mixin CoinControlInterface on Bip39HDWallet { +mixin CoinControlInterface on Wallet { // any required here? // currently only used to id which wallets support coin control } diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart deleted file mode 100644 index 661b10bd3..000000000 --- a/lib/wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart +++ /dev/null @@ -1,443 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'dart:math'; - -import 'package:cw_core/monero_transaction_priority.dart'; -import 'package:cw_core/sync_status.dart'; -import 'package:cw_core/transaction_direction.dart'; -import 'package:cw_core/wallet_base.dart'; -import 'package:cw_core/wallet_service.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:flutter_libmonero/core/key_service.dart'; -import 'package:isar/isar.dart'; -import 'package:mutex/mutex.dart'; - -import '../../../models/balance.dart'; -import '../../../models/isar/models/blockchain_data/address.dart'; -import '../../../models/keys/cw_key_data.dart'; -import '../../../models/paymint/fee_object_model.dart'; -import '../../../services/event_bus/events/global/blocks_remaining_event.dart'; -import '../../../services/event_bus/events/global/refresh_percent_changed_event.dart'; -import '../../../services/event_bus/events/global/updated_in_background_event.dart'; -import '../../../services/event_bus/events/global/wallet_sync_status_changed_event.dart'; -import '../../../services/event_bus/global_event_bus.dart'; -import '../../../utilities/amount/amount.dart'; -import '../../../utilities/logger.dart'; -import '../../../utilities/stack_file_system.dart'; -import '../../crypto_currency/intermediate/cryptonote_currency.dart'; -import '../../isar/models/wallet_info.dart'; -import '../intermediate/cryptonote_wallet.dart'; -import 'multi_address_interface.dart'; - -mixin CwBasedInterface on CryptonoteWallet - implements MultiAddressInterface { - final prepareSendMutex = Mutex(); - final estimateFeeMutex = Mutex(); - - KeyService? _cwKeysStorageCached; - KeyService get cwKeysStorage => - _cwKeysStorageCached ??= KeyService(secureStorageInterface); - - static WalletService? cwWalletService; - static WalletBase? cwWalletBase; - - bool _hasCalledExit = false; - bool _txRefreshLock = false; - int _lastCheckedHeight = -1; - int _txCount = 0; - int currentKnownChainHeight = 0; - double highestPercentCached = 0; - - Timer? autoSaveTimer; - Future pathForWalletDir({ - required String name, - required WalletType type, - }) async { - final Directory root = await StackFileSystem.applicationRootDirectory(); - - final prefix = walletTypeToString(type).toLowerCase(); - final walletsDir = Directory('${root.path}/wallets'); - final walletDire = Directory('${walletsDir.path}/$prefix/$name'); - - if (!walletDire.existsSync()) { - walletDire.createSync(recursive: true); - } - - return walletDire.path; - } - - Future pathForWallet({ - required String name, - required WalletType type, - }) async => - await pathForWalletDir(name: name, type: type) - .then((path) => '$path/$name'); - - void onNewBlock({required int height, required int blocksLeft}) { - currentKnownChainHeight = height; - updateChainHeight(); - _refreshTxDataHelper(); - } - - void onNewTransaction() { - // TODO: [prio=low] get rid of UpdatedInBackgroundEvent and move to - // adding the v2 tx to the db which would update ui automagically since the - // db is watched by the ui - // call this here? - GlobalEventBus.instance.fire( - UpdatedInBackgroundEvent( - "New data found in $walletId ${info.name} in background!", - walletId, - ), - ); - } - - void syncStatusChanged() async { - final syncStatus = cwWalletBase?.syncStatus; - if (syncStatus != null) { - if (syncStatus.progress() == 1 && refreshMutex.isLocked) { - refreshMutex.release(); - } - - WalletSyncStatus? status; - xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(true); - - if (syncStatus is SyncingSyncStatus) { - final int blocksLeft = syncStatus.blocksLeft; - - // ensure at least 1 to prevent math errors - final int height = max(1, syncStatus.height); - - final nodeHeight = height + blocksLeft; - currentKnownChainHeight = nodeHeight; - - final percent = height / nodeHeight; - - final highest = max(highestPercentCached, percent); - - // update cached - if (highestPercentCached < percent) { - highestPercentCached = percent; - } - - GlobalEventBus.instance.fire( - RefreshPercentChangedEvent( - highest, - walletId, - ), - ); - GlobalEventBus.instance.fire( - BlocksRemainingEvent( - blocksLeft, - walletId, - ), - ); - } else if (syncStatus is SyncedSyncStatus) { - status = WalletSyncStatus.synced; - } else if (syncStatus is NotConnectedSyncStatus) { - status = WalletSyncStatus.unableToSync; - xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(false); - } else if (syncStatus is StartingSyncStatus) { - status = WalletSyncStatus.syncing; - GlobalEventBus.instance.fire( - RefreshPercentChangedEvent( - highestPercentCached, - walletId, - ), - ); - } else if (syncStatus is FailedSyncStatus) { - status = WalletSyncStatus.unableToSync; - xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(false); - } else if (syncStatus is ConnectingSyncStatus) { - status = WalletSyncStatus.syncing; - GlobalEventBus.instance.fire( - RefreshPercentChangedEvent( - highestPercentCached, - walletId, - ), - ); - } else if (syncStatus is ConnectedSyncStatus) { - status = WalletSyncStatus.syncing; - GlobalEventBus.instance.fire( - RefreshPercentChangedEvent( - highestPercentCached, - walletId, - ), - ); - } else if (syncStatus is LostConnectionSyncStatus) { - status = WalletSyncStatus.unableToSync; - xmrAndWowSyncSpecificFunctionThatShouldBeGottenRidOfInTheFuture(false); - } - - if (status != null) { - GlobalEventBus.instance.fire( - WalletSyncStatusChangedEvent( - status, - walletId, - info.coin, - ), - ); - } - } - } - - @override - Future checkSaveInitialReceivingAddress() async { - // this doesn't work without opening the wallet first which takes a while - } - - // ============ Interface ==================================================== - - Future get availableBalance; - Future get totalBalance; - - Future exitCwWallet(); - - Future open(); - - Address addressFor({required int index, int account = 0}); - - Future getKeys(); - - // ============ Private ====================================================== - Future _refreshTxDataHelper() async { - if (_txRefreshLock) return; - _txRefreshLock = true; - - final syncStatus = cwWalletBase?.syncStatus; - - if (syncStatus != null && syncStatus is SyncingSyncStatus) { - final int blocksLeft = syncStatus.blocksLeft; - final tenKChange = blocksLeft ~/ 10000; - - // only refresh transactions periodically during a sync - if (_lastCheckedHeight == -1 || tenKChange < _lastCheckedHeight) { - _lastCheckedHeight = tenKChange; - await _refreshTxData(); - } - } else { - await _refreshTxData(); - } - - _txRefreshLock = false; - } - - Future _refreshTxData() async { - await updateTransactions(); - final count = await mainDB.getTransactions(walletId).count(); - - if (count > _txCount) { - _txCount = count; - await updateBalance(); - GlobalEventBus.instance.fire( - UpdatedInBackgroundEvent( - "New transaction data found in $walletId ${info.name}!", - walletId, - ), - ); - } - } - - // ============ Overrides ==================================================== - - @override - FilterOperation? get changeAddressFilterOperation => null; - - @override - FilterOperation? get receivingAddressFilterOperation => null; - - @override - Future updateBalance() async { - final total = await totalBalance; - final available = await availableBalance; - - final balance = Balance( - total: total, - spendable: available, - blockedTotal: Amount( - rawValue: BigInt.zero, - fractionDigits: cryptoCurrency.fractionDigits, - ), - pendingSpendable: total - available, - ); - - await info.updateBalance(newBalance: balance, isar: mainDB.isar); - } - - @override - Future refresh() async { - // Awaiting this lock could be dangerous. - // Since refresh is periodic (generally) - if (refreshMutex.isLocked) { - return; - } - - // this acquire should be almost instant due to above check. - // Slight possibility of race but should be irrelevant - await refreshMutex.acquire(); - - GlobalEventBus.instance.fire( - WalletSyncStatusChangedEvent( - WalletSyncStatus.syncing, - walletId, - info.coin, - ), - ); - - await updateTransactions(); - await updateBalance(); - - if (info.otherData[WalletInfoKeys.reuseAddress] != true) { - await checkReceivingAddressForTransactions(); - } - - if (cwWalletBase?.syncStatus is SyncedSyncStatus) { - refreshMutex.release(); - GlobalEventBus.instance.fire( - WalletSyncStatusChangedEvent( - WalletSyncStatus.synced, - walletId, - info.coin, - ), - ); - } - } - - static Mutex exitMutex = Mutex(); - - @override - Future exit() async { - if (!_hasCalledExit) { - await exitMutex.protect(() async { - _hasCalledExit = true; - autoSaveTimer?.cancel(); - await exitCwWallet(); - cwWalletBase?.close(); - cwWalletBase = null; - cwWalletService = null; - }); - } - } - - @override - Future generateNewReceivingAddress() async { - try { - final currentReceiving = await getCurrentReceivingAddress(); - - final newReceivingIndex = - currentReceiving == null ? 0 : currentReceiving.derivationIndex + 1; - - final newReceivingAddress = addressFor(index: newReceivingIndex); - - // Add that new receiving address - await mainDB.putAddress(newReceivingAddress); - await info.updateReceivingAddress( - newAddress: newReceivingAddress.value, - isar: mainDB.isar, - ); - } catch (e, s) { - Logging.instance.log( - "Exception in generateNewAddress(): $e\n$s", - level: LogLevel.Error, - ); - } - } - - @override - Future checkReceivingAddressForTransactions() async { - if (info.otherData[WalletInfoKeys.reuseAddress] == true) { - try { - throw Exception(); - } catch (_, s) { - Logging.instance.log( - "checkReceivingAddressForTransactions called but reuse address flag set: $s", - level: LogLevel.Error, - ); - } - } - - try { - int highestIndex = -1; - final entries = cwWalletBase?.transactionHistory?.transactions?.entries; - if (entries != null) { - for (final element in entries) { - if (element.value.direction == TransactionDirection.incoming) { - final int curAddressIndex = - element.value.additionalInfo!['addressIndex'] as int; - if (curAddressIndex > highestIndex) { - highestIndex = curAddressIndex; - } - } - } - } - - // Check the new receiving index - final currentReceiving = await getCurrentReceivingAddress(); - final curIndex = currentReceiving?.derivationIndex ?? -1; - - if (highestIndex >= curIndex) { - // First increment the receiving index - final newReceivingIndex = curIndex + 1; - - // Use new index to derive a new receiving address - final newReceivingAddress = addressFor(index: newReceivingIndex); - - final existing = await mainDB - .getAddresses(walletId) - .filter() - .valueEqualTo(newReceivingAddress.value) - .findFirst(); - if (existing == null) { - // Add that new change address - await mainDB.putAddress(newReceivingAddress); - } else { - // we need to update the address - await mainDB.updateAddress(existing, newReceivingAddress); - } - if (info.otherData[WalletInfoKeys.reuseAddress] != true) { - // keep checking until address with no tx history is set as current - await checkReceivingAddressForTransactions(); - } - } - } on SocketException catch (se, s) { - Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(): $se\n$s", - level: LogLevel.Error, - ); - return; - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(): $e\n$s", - level: LogLevel.Error, - ); - rethrow; - } - } - - @override - Future get fees async => FeeObject( - numberOfBlocksFast: 10, - numberOfBlocksAverage: 15, - numberOfBlocksSlow: 20, - fast: MoneroTransactionPriority.fast.raw!, - medium: MoneroTransactionPriority.regular.raw!, - slow: MoneroTransactionPriority.slow.raw!, - ); - @override - Future updateChainHeight() async { - await info.updateCachedChainHeight( - newHeight: currentKnownChainHeight, - isar: mainDB.isar, - ); - } - - @override - Future checkChangeAddressForTransactions() async { - // do nothing - } - - @override - Future generateNewChangeAddress() async { - // do nothing - } -} diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart index 4122b257a..d65fb7b62 100644 --- a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart +++ b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart @@ -13,6 +13,7 @@ import '../../../models/isar/models/blockchain_data/v2/input_v2.dart'; import '../../../models/isar/models/blockchain_data/v2/output_v2.dart'; import '../../../models/isar/models/blockchain_data/v2/transaction_v2.dart'; import '../../../models/isar/models/isar_models.dart'; +import '../../../models/keys/view_only_wallet_data.dart'; import '../../../models/paymint/fee_object_model.dart'; import '../../../models/signing_data.dart'; import '../../../utilities/amount/amount.dart'; @@ -32,9 +33,10 @@ import '../intermediate/bip39_hd_wallet.dart'; import 'cpfp_interface.dart'; import 'paynym_interface.dart'; import 'rbf_interface.dart'; +import 'view_only_option_interface.dart'; mixin ElectrumXInterface - on Bip39HDWallet { + on Bip39HDWallet implements ViewOnlyOptionInterface { late ElectrumXClient electrumXClient; late CachedElectrumXClient electrumXCachedClient; @@ -137,7 +139,9 @@ mixin ElectrumXInterface (e.used != true) && (canCPFP || e.isConfirmed( - currentChainHeight, cryptoCurrency.minConfirms)), + currentChainHeight, + cryptoCurrency.minConfirms, + )), ) .toList(); final spendableSatoshiValue = @@ -944,7 +948,7 @@ mixin ElectrumXInterface Future<({List
addresses, int index})> checkGapsBatched( int txCountBatchSize, - coinlib.HDPrivateKey root, + coinlib.HDKey node, DerivePathType type, int chain, ) async { @@ -969,7 +973,14 @@ mixin ElectrumXInterface index: index + j, ); - final keys = root.derivePath(derivePath); + final coinlib.HDKey keys; + if (isViewOnly) { + final idx = derivePath.lastIndexOf("'/"); + final path = derivePath.substring(idx + 2); + keys = node.derivePath(path); + } else { + keys = node.derivePath(derivePath); + } final addressData = cryptoCurrency.getAddressForPublicKey( publicKey: keys.publicKey, @@ -986,7 +997,8 @@ mixin ElectrumXInterface publicKey: keys.publicKey.data, type: addressData.addressType, derivationIndex: index + j, - derivationPath: DerivationPath()..value = derivePath, + derivationPath: + isViewOnly ? null : (DerivationPath()..value = derivePath), subType: chain == 0 ? AddressSubType.receiving : AddressSubType.change, ); @@ -1025,13 +1037,14 @@ mixin ElectrumXInterface } Future<({List
addresses, int index})> checkGapsLinearly( - coinlib.HDPrivateKey root, + coinlib.HDKey node, DerivePathType type, int chain, ) async { final List
addressArray = []; int gapCounter = 0; int index = 0; + for (; gapCounter < cryptoCurrency.maxUnusedAddressGap; index++) { Logging.instance.log( "index: $index, \t GapCounter chain=$chain ${type.name}: $gapCounter", @@ -1043,7 +1056,16 @@ mixin ElectrumXInterface chain: chain, index: index, ); - final keys = root.derivePath(derivePath); + + final coinlib.HDKey keys; + if (isViewOnly) { + final idx = derivePath.lastIndexOf("'/"); + final path = derivePath.substring(idx + 2); + keys = node.derivePath(path); + } else { + keys = node.derivePath(derivePath); + } + final addressData = cryptoCurrency.getAddressForPublicKey( publicKey: keys.publicKey, derivePathType: type, @@ -1059,7 +1081,8 @@ mixin ElectrumXInterface publicKey: keys.publicKey.data, type: addressData.addressType, derivationIndex: index, - derivationPath: DerivationPath()..value = derivePath, + derivationPath: + isViewOnly ? null : (DerivationPath()..value = derivePath), subType: chain == 0 ? AddressSubType.receiving : AddressSubType.change, ); @@ -1331,6 +1354,10 @@ mixin ElectrumXInterface @override Future checkReceivingAddressForTransactions() async { + if (isViewOnly && viewOnlyType == ViewOnlyWalletType.addressOnly) { + return; + } + if (info.otherData[WalletInfoKeys.reuseAddress] == true) { try { throw Exception(); @@ -1382,6 +1409,21 @@ mixin ElectrumXInterface @override Future checkChangeAddressForTransactions() async { + if (isViewOnly && viewOnlyType == ViewOnlyWalletType.addressOnly) { + return; + } + + if (info.otherData[WalletInfoKeys.reuseAddress] == true) { + try { + throw Exception(); + } catch (_, s) { + Logging.instance.log( + "checkChangeAddressForTransactions called but reuse address flag set: $s", + level: LogLevel.Error, + ); + } + } + try { final currentChange = await getCurrentChangeAddress(); @@ -1419,6 +1461,11 @@ mixin ElectrumXInterface @override Future recover({required bool isRescan}) async { + if (isViewOnly) { + await recoverViewOnly(isRescan: isRescan); + return; + } + final root = await getRootHDNode(); final List addresses})>> receiveFutures = @@ -1575,7 +1622,7 @@ mixin ElectrumXInterface ); } catch (e, s) { Logging.instance.log( - "Failed to check paynym.is followers/following for history during " + "Failed to check ${PaynymIsApi.baseURL} followers/following for history during " "bitcoin wallet ($walletId ${info.name}) " "_recoverWalletFromBIP32SeedPhrase: $e/n$s", level: LogLevel.Error, @@ -1918,5 +1965,219 @@ mixin ElectrumXInterface return address; } + // ============== View only ================================================== + + @override + Future recoverViewOnly({bool isRescan = false}) async { + final data = await getViewOnlyWalletData(); + + final coinlib.HDKey? root; + if (data is AddressViewOnlyWalletData) { + root = null; + } else { + if ((data as ExtendedKeysViewOnlyWalletData).xPubs.length != 1) { + throw Exception( + "Only single xpub view only wallets are currently supported", + ); + } + + root = coinlib.HDPublicKey.decode(data.xPubs.first.encoded); + } + + final List addresses})>> receiveFutures = + []; + final List addresses})>> changeFutures = + []; + + const receiveChain = 0; + const changeChain = 1; + + const txCountBatchSize = 12; + + try { + await refreshMutex.protect(() async { + if (isRescan) { + // clear cache + await electrumXCachedClient.clearSharedTransactionCache( + cryptoCurrency: info.coin, + ); + // clear blockchain info + await mainDB.deleteWalletBlockchainData(walletId); + } + + final List
addressesToStore = []; + + if (root != null) { + // receiving addresses + Logging.instance.log( + "checking receiving addresses...", + level: LogLevel.Info, + ); + + final canBatch = await serverCanBatch; + + for (final type in cryptoCurrency.supportedDerivationPathTypes) { + final path = cryptoCurrency.constructDerivePath( + derivePathType: type, + chain: 0, + index: 0, + ); + if (path.startsWith( + (data as ExtendedKeysViewOnlyWalletData).xPubs.first.path, + )) { + receiveFutures.add( + canBatch + ? checkGapsBatched( + txCountBatchSize, + root, + type, + receiveChain, + ) + : checkGapsLinearly( + root, + type, + receiveChain, + ), + ); + } + } + + // change addresses + Logging.instance.log( + "checking change addresses...", + level: LogLevel.Info, + ); + for (final type in cryptoCurrency.supportedDerivationPathTypes) { + final path = cryptoCurrency.constructDerivePath( + derivePathType: type, + chain: 0, + index: 0, + ); + if (path.startsWith( + (data as ExtendedKeysViewOnlyWalletData).xPubs.first.path, + )) { + changeFutures.add( + canBatch + ? checkGapsBatched( + txCountBatchSize, + root, + type, + changeChain, + ) + : checkGapsLinearly( + root, + type, + changeChain, + ), + ); + } + } + + // io limitations may require running these linearly instead + final futuresResult = await Future.wait([ + Future.wait(receiveFutures), + Future.wait(changeFutures), + ]); + + final receiveResults = futuresResult[0]; + final changeResults = futuresResult[1]; + + int highestReceivingIndexWithHistory = 0; + + for (final tuple in receiveResults) { + if (tuple.addresses.isEmpty) { + await checkReceivingAddressForTransactions(); + } else { + highestReceivingIndexWithHistory = max( + tuple.index, + highestReceivingIndexWithHistory, + ); + addressesToStore.addAll(tuple.addresses); + } + } + + int highestChangeIndexWithHistory = 0; + // If restoring a wallet that never sent any funds with change, then set changeArray + // manually. If we didn't do this, it'd store an empty array. + for (final tuple in changeResults) { + if (tuple.addresses.isEmpty) { + await checkChangeAddressForTransactions(); + } else { + highestChangeIndexWithHistory = max( + tuple.index, + highestChangeIndexWithHistory, + ); + addressesToStore.addAll(tuple.addresses); + } + } + + // remove extra addresses to help minimize risk of creating a large gap + addressesToStore.removeWhere( + (e) => + e.subType == AddressSubType.change && + e.derivationIndex > highestChangeIndexWithHistory, + ); + addressesToStore.removeWhere( + (e) => + e.subType == AddressSubType.receiving && + e.derivationIndex > highestReceivingIndexWithHistory, + ); + } else { + final clAddress = coinlib.Address.fromString( + (data as AddressViewOnlyWalletData).address, + cryptoCurrency.networkParams, + ); + + final AddressType addressType; + switch (clAddress.runtimeType) { + case const (coinlib.P2PKHAddress): + addressType = AddressType.p2pkh; + break; + + case const (coinlib.P2SHAddress): + addressType = AddressType.p2sh; + break; + + case const (coinlib.P2WPKHAddress): + addressType = AddressType.p2wpkh; + break; + + case const (coinlib.P2TRAddress): + addressType = AddressType.p2tr; + break; + + default: + throw Exception( + "Unsupported address type: ${clAddress.runtimeType}", + ); + } + + addressesToStore.add( + Address( + walletId: walletId, + value: clAddress.toString(), + publicKey: [], + derivationIndex: -1, + derivationPath: null, + type: addressType, + subType: AddressSubType.receiving, + ), + ); + } + + await mainDB.updateOrPutAddresses(addressesToStore); + }); + + unawaited(refresh()); + } catch (e, s) { + Logging.instance.log( + "Exception rethrown from electrumx_mixin recoverViewOnly(): $e\n$s", + level: LogLevel.Info, + ); + + rethrow; + } + } + // =========================================================================== } diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart index 1606b1295..8b41dc122 100644 --- a/lib/wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart +++ b/lib/wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart @@ -2,35 +2,35 @@ import '../../../models/keys/xpriv_data.dart'; import '../../crypto_currency/interfaces/electrumx_currency_interface.dart'; import 'electrumx_interface.dart'; -typedef XPub = ({String path, String xpub}); -typedef XPriv = ({String path, String xpriv}); +abstract class XKey { + XKey({required this.path}); + final String path; +} + +class XPub extends XKey { + XPub({required super.path, required this.encoded}); + final String encoded; +} + +class XPriv extends XKey { + XPriv({required super.path, required this.encoded}); + final String encoded; +} mixin ExtendedKeysInterface on ElectrumXInterface { Future<({List xpubs, String fingerprint})> getXPubs() async { - final paths = cryptoCurrency.supportedDerivationPathTypes.map( - (e) => ( - path: e, - addressType: e.getAddressType(), - ), - ); + final paths = cryptoCurrency.supportedHardenedDerivationPaths; final master = await getRootHDNode(); final fingerprint = master.fingerprint.toRadixString(16); - final futures = paths.map((e) async { - String path = cryptoCurrency.constructDerivePath( - derivePathType: e.path, - chain: 0, - index: 0, - ); - // trim chain and address index - path = path.substring(0, path.lastIndexOf("'") + 1); + final futures = paths.map((path) async { final node = master.derivePath(path); - return ( + return XPub( path: path, - xpub: node.hdPublicKey.encode( + encoded: node.hdPublicKey.encode( cryptoCurrency.networkParams.pubHDPrefix, // 0x04b24746, ), @@ -44,29 +44,17 @@ mixin ExtendedKeysInterface } Future getXPrivs() async { - final paths = cryptoCurrency.supportedDerivationPathTypes.map( - (e) => ( - path: e, - addressType: e.getAddressType(), - ), - ); + final paths = cryptoCurrency.supportedHardenedDerivationPaths; final master = await getRootHDNode(); final fingerprint = master.fingerprint.toRadixString(16); - final futures = paths.map((e) async { - String path = cryptoCurrency.constructDerivePath( - derivePathType: e.path, - chain: 0, - index: 0, - ); - // trim chain and address index - path = path.substring(0, path.lastIndexOf("'") + 1); + final futures = paths.map((path) async { final node = master.derivePath(path); - return ( + return XPriv( path: path, - xpriv: node.encode( + encoded: node.encode( cryptoCurrency.networkParams.privHDPrefix, ), ); @@ -76,9 +64,9 @@ mixin ExtendedKeysInterface walletId: walletId, fingerprint: fingerprint, xprivs: [ - ( + XPriv( path: "Master", - xpriv: master.encode( + encoded: master.encode( cryptoCurrency.networkParams.privHDPrefix, ), ), diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart new file mode 100644 index 000000000..4989ce0d0 --- /dev/null +++ b/lib/wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart @@ -0,0 +1,27 @@ +import '../../../models/keys/view_only_wallet_data.dart'; +import '../../crypto_currency/interfaces/view_only_option_currency_interface.dart'; +import '../wallet.dart'; + +mixin ViewOnlyOptionInterface + on Wallet { + ViewOnlyWalletType get viewOnlyType => info.viewOnlyWalletType!; + + bool get isViewOnly => info.isViewOnly; + + Future recoverViewOnly(); + + Future getViewOnlyWalletData() async { + if (!isViewOnly) { + throw Exception("This is not a view only wallet"); + } + + final encoded = await secureStorageInterface.read( + key: Wallet.getViewOnlyWalletDataSecStoreKey(walletId: walletId), + ); + + return ViewOnlyWalletData.fromJsonEncodedString( + encoded!, + walletId: walletId, + ); + } +} diff --git a/lib/widgets/churning/churn_progress_item.dart b/lib/widgets/churning/churn_progress_item.dart new file mode 100644 index 000000000..8e989bc08 --- /dev/null +++ b/lib/widgets/churning/churn_progress_item.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../../pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart'; +import '../../services/churning_service.dart'; +import '../../themes/stack_colors.dart'; +import '../../utilities/assets.dart'; +import '../../utilities/text_styles.dart'; +import '../../utilities/util.dart'; +import '../conditional_parent.dart'; +import '../rounded_container.dart'; + +class ProgressItem extends StatelessWidget { + const ProgressItem({ + super.key, + required this.iconAsset, + required this.label, + required this.status, + this.error, + }); + + final String iconAsset; + final String label; + final ChurnStatus status; + final Object? error; + + Widget _getIconForState(ChurnStatus status, BuildContext context) { + switch (status) { + case ChurnStatus.waiting: + return SvgPicture.asset( + Assets.svg.loader, + color: + Theme.of(context).extension()!.buttonBackSecondary, + ); + case ChurnStatus.running: + return SvgPicture.asset( + Assets.svg.loader, + color: Theme.of(context).extension()!.accentColorGreen, + ); + case ChurnStatus.success: + return SvgPicture.asset( + Assets.svg.checkCircle, + color: Theme.of(context).extension()!.accentColorGreen, + ); + case ChurnStatus.failed: + return SvgPicture.asset( + Assets.svg.circleAlert, + color: Theme.of(context).extension()!.textError, + ); + } + } + + @override + Widget build(BuildContext context) { + return ConditionalParent( + condition: Util.isDesktop, + builder: (child) => RoundedContainer( + padding: EdgeInsets.zero, + color: Theme.of(context).extension()!.popupBG, + borderColor: Theme.of(context).extension()!.background, + child: child, + ), + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: + Theme.of(context).extension()!.buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + iconAsset, + width: 18, + height: 18, + color: Theme.of(context).extension()!.textDark, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(status, context), + ), + title: label, + subTitle: error != null + ? Text( + error!.toString(), + style: STextStyles.w500_12(context).copyWith( + color: Theme.of(context).extension()!.textError, + ), + ) + : null, + ), + ); + } +} diff --git a/lib/widgets/custom_buttons/checkbox_text_button.dart b/lib/widgets/custom_buttons/checkbox_text_button.dart index 29e6c5ada..6a451335b 100644 --- a/lib/widgets/custom_buttons/checkbox_text_button.dart +++ b/lib/widgets/custom_buttons/checkbox_text_button.dart @@ -1,18 +1,31 @@ import 'package:flutter/material.dart'; + import '../../utilities/text_styles.dart'; class CheckboxTextButton extends StatefulWidget { - const CheckboxTextButton({super.key, required this.label, this.onChanged}); + const CheckboxTextButton({ + super.key, + required this.label, + this.onChanged, + this.initialValue = false, + }); final String label; final void Function(bool)? onChanged; + final bool initialValue; @override State createState() => _CheckboxTextButtonState(); } class _CheckboxTextButtonState extends State { - bool _value = false; + late bool _value; + + @override + void initState() { + super.initState(); + _value = widget.initialValue; + } @override Widget build(BuildContext context) { diff --git a/lib/widgets/desktop/desktop_fee_dialog.dart b/lib/widgets/desktop/desktop_fee_dialog.dart index 90304e80c..322fbb876 100644 --- a/lib/widgets/desktop/desktop_fee_dialog.dart +++ b/lib/widgets/desktop/desktop_fee_dialog.dart @@ -1,6 +1,7 @@ -import 'package:cw_core/monero_transaction_priority.dart'; import 'package:flutter/material.dart'; +import 'package:cs_monero/cs_monero.dart' as lib_monero; import 'package:flutter_riverpod/flutter_riverpod.dart'; + import '../../models/models.dart'; import '../../pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart'; import '../../pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart'; @@ -61,7 +62,7 @@ class _DesktopFeeDialogState extends ConsumerState { if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.fast.raw!, + lib_monero.TransactionPriority.high.value, ); ref.read(feeSheetSessionCacheProvider).fast[amount] = fee; } else if (coin is Firo) { @@ -111,7 +112,7 @@ class _DesktopFeeDialogState extends ConsumerState { if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.regular.raw!, + lib_monero.TransactionPriority.medium.value, ); ref.read(feeSheetSessionCacheProvider).average[amount] = fee; } else if (coin is Firo) { @@ -161,7 +162,7 @@ class _DesktopFeeDialogState extends ConsumerState { if (coin is Monero || coin is Wownero) { final fee = await wallet.estimateFeeFor( amount, - MoneroTransactionPriority.slow.raw!, + lib_monero.TransactionPriority.normal.value, ); ref.read(feeSheetSessionCacheProvider).slow[amount] = fee; } else if (coin is Firo) { diff --git a/lib/widgets/stack_dialog.dart b/lib/widgets/stack_dialog.dart index 1541256a0..ff921d24c 100644 --- a/lib/widgets/stack_dialog.dart +++ b/lib/widgets/stack_dialog.dart @@ -94,7 +94,7 @@ class StackDialog extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( - child: Text( + child: SelectableText( title, style: STextStyles.pageTitleH2(context), ), @@ -110,7 +110,7 @@ class StackDialog extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( + SelectableText( message!, style: STextStyles.smallMed14(context), ), diff --git a/lib/widgets/stack_text_field.dart b/lib/widgets/stack_text_field.dart index c64c6a5e8..318b59119 100644 --- a/lib/widgets/stack_text_field.dart +++ b/lib/widgets/stack_text_field.dart @@ -9,10 +9,15 @@ */ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import '../themes/stack_colors.dart'; +import '../utilities/constants.dart'; import '../utilities/text_styles.dart'; import '../utilities/util.dart'; +import 'icon_widgets/clipboard_icon.dart'; +import 'icon_widgets/x_icon.dart'; +import 'textfield_icon_button.dart'; InputDecoration standardInputDecoration( String? labelText, @@ -52,3 +57,113 @@ InputDecoration standardInputDecoration( focusedErrorBorder: InputBorder.none, ); } + +class FullTextField extends StatefulWidget { + const FullTextField({ + super.key, + this.controller, + this.focusNode, + required this.label, + this.onChanged, + }); + + final String label; + + final TextEditingController? controller; + final FocusNode? focusNode; + + final void Function(String)? onChanged; + + @override + State createState() => _FullTextFieldState(); +} + +class _FullTextFieldState extends State { + late final TextEditingController controller; + late final FocusNode focusNode; + + bool _hasValue = false; + + @override + void initState() { + super.initState(); + controller = widget.controller ?? TextEditingController(); + focusNode = widget.focusNode ?? FocusNode(); + } + + @override + void dispose() { + if (widget.controller == null) { + controller.dispose(); + } + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + controller: controller, + autocorrect: false, + enableSuggestions: false, + onChanged: (newValue) { + widget.onChanged?.call(newValue); + }, + focusNode: focusNode, + style: STextStyles.field(context), + decoration: standardInputDecoration( + widget.label, + focusNode, + context, + ).copyWith( + contentPadding: const EdgeInsets.only( + left: 16, + top: 6, + bottom: 8, + right: 5, + ), + suffixIcon: Padding( + padding: controller.text.isEmpty + ? const EdgeInsets.only(right: 8) + : const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + TextFieldIconButton( + onTap: () async { + if (_hasValue) { + controller.text = ""; + + setState(() { + _hasValue = false; + }); + } else { + final data = + await Clipboard.getData(Clipboard.kTextPlain); + if (data?.text != null && data!.text!.isNotEmpty) { + final content = data.text!.trim(); + + controller.text = content; + setState(() { + _hasValue = content.isNotEmpty; + }); + } + } + + widget.onChanged?.call(controller.text); + }, + child: _hasValue ? const XIcon() : const ClipboardIcon(), + ), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/widgets/wallet_card.dart b/lib/widgets/wallet_card.dart index a2185186c..79ab0d41d 100644 --- a/lib/widgets/wallet_card.dart +++ b/lib/widgets/wallet_card.dart @@ -27,8 +27,8 @@ import '../utilities/util.dart'; import '../wallets/isar/providers/eth/current_token_wallet_provider.dart'; import '../wallets/wallet/impl/ethereum_wallet.dart'; import '../wallets/wallet/impl/sub_wallets/eth_token_wallet.dart'; +import '../wallets/wallet/intermediate/lib_monero_wallet.dart'; import '../wallets/wallet/wallet.dart'; -import '../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; import 'conditional_parent.dart'; import 'desktop/primary_button.dart'; import 'dialogs/basic_dialog.dart'; @@ -97,7 +97,7 @@ class SimpleWalletCard extends ConsumerWidget { if (context.mounted) { final Future loadFuture; - if (wallet is CwBasedInterface) { + if (wallet is LibMoneroWallet) { loadFuture = wallet.init().then((value) async => await (wallet).open()); } else { loadFuture = wallet.init(); diff --git a/lib/widgets/wallet_navigation_bar/components/icons/churn_nav_icon.dart b/lib/widgets/wallet_navigation_bar/components/icons/churn_nav_icon.dart new file mode 100644 index 000000000..af404f5c2 --- /dev/null +++ b/lib/widgets/wallet_navigation_bar/components/icons/churn_nav_icon.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../../../../themes/stack_colors.dart'; +import '../../../../utilities/assets.dart'; + +class ChurnNavIcon extends StatelessWidget { + const ChurnNavIcon({super.key}); + + @override + Widget build(BuildContext context) { + return SvgPicture.asset( + Assets.svg.churn, + height: 20, + width: 20, + color: Theme.of(context).extension()!.bottomNavIconIcon, + ); + } +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 499e835f2..88c196c5e 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,10 +6,10 @@ #include "generated_plugin_registrant.h" +#include #include #include #include -#include #include #include #include @@ -18,6 +18,9 @@ #include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) cs_monero_flutter_libs_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "CsMoneroFlutterLibsLinuxPlugin"); + cs_monero_flutter_libs_linux_plugin_register_with_registrar(cs_monero_flutter_libs_linux_registrar); g_autoptr(FlPluginRegistrar) desktop_drop_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopDropPlugin"); desktop_drop_plugin_register_with_registrar(desktop_drop_registrar); @@ -27,9 +30,6 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) flutter_libepiccash_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterLibepiccashPlugin"); flutter_libepiccash_plugin_register_with_registrar(flutter_libepiccash_registrar); - g_autoptr(FlPluginRegistrar) flutter_libmonero_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterLibmoneroPlugin"); - flutter_libmonero_plugin_register_with_registrar(flutter_libmonero_registrar); g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index b4a4986e6..72a81025c 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,10 +3,10 @@ # list(APPEND FLUTTER_PLUGIN_LIST + cs_monero_flutter_libs_linux desktop_drop devicelocale flutter_libepiccash - flutter_libmonero flutter_secure_storage_linux isar_flutter_libs sqlite3_flutter_libs diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index ca56fcfeb..66db749d9 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,6 +7,7 @@ import Foundation import camera_macos import connectivity_plus +import cs_monero_flutter_libs_macos import desktop_drop import device_info_plus import devicelocale @@ -15,18 +16,20 @@ import flutter_local_notifications import flutter_secure_storage_macos import isar_flutter_libs import lelantus +import local_auth_darwin import package_info_plus import path_provider_foundation import share_plus import sqlite3_flutter_libs import stack_wallet_backup import url_launcher_macos -import wakelock_macos +import wakelock_plus import window_size func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { CameraMacosPlugin.register(with: registry.registrar(forPlugin: "CameraMacosPlugin")) ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + CsMoneroFlutterLibsMacosPlugin.register(with: registry.registrar(forPlugin: "CsMoneroFlutterLibsMacosPlugin")) DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) @@ -35,12 +38,13 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 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")) + FLALocalAuthPlugin.register(with: registry.registrar(forPlugin: "FLALocalAuthPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin")) StackWalletBackupPlugin.register(with: registry.registrar(forPlugin: "StackWalletBackupPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) - WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin")) + WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) WindowSizePlugin.register(with: registry.registrar(forPlugin: "WindowSizePlugin")) } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 27b39dbc1..b9159cd55 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -7,6 +7,8 @@ PODS: - connectivity_plus (0.0.1): - FlutterMacOS - ReachabilitySwift + - cs_monero_flutter_libs (0.0.1): + - FlutterMacOS - desktop_drop (0.0.1): - FlutterMacOS - device_info_plus (0.0.1): @@ -28,6 +30,9 @@ PODS: - FlutterMacOS - lelantus (0.0.1): - FlutterMacOS + - local_auth_darwin (0.0.1): + - Flutter + - FlutterMacOS - package_info_plus (0.0.1): - FlutterMacOS - path_provider_foundation (0.0.1): @@ -39,6 +44,8 @@ PODS: - "sqlite3 (3.46.0+1)": - "sqlite3/common (= 3.46.0+1)" - "sqlite3/common (3.46.0+1)" + - "sqlite3/dbstatvtab (3.46.0+1)": + - sqlite3/common - "sqlite3/fts5 (3.46.0+1)": - sqlite3/common - "sqlite3/perf-threadsafe (3.46.0+1)": @@ -47,7 +54,8 @@ PODS: - sqlite3/common - sqlite3_flutter_libs (0.0.1): - FlutterMacOS - - sqlite3 (~> 3.46.0) + - "sqlite3 (~> 3.46.0+1)" + - sqlite3/dbstatvtab - sqlite3/fts5 - sqlite3/perf-threadsafe - sqlite3/rtree @@ -56,7 +64,7 @@ PODS: - tor_ffi_plugin (0.0.1) - url_launcher_macos (0.0.1): - FlutterMacOS - - wakelock_macos (0.0.1): + - wakelock_plus (0.0.1): - FlutterMacOS - window_size (0.0.2): - FlutterMacOS @@ -65,6 +73,7 @@ DEPENDENCIES: - camera_macos (from `Flutter/ephemeral/.symlinks/plugins/camera_macos/macos`) - coinlib_flutter (from `Flutter/ephemeral/.symlinks/plugins/coinlib_flutter/darwin`) - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`) + - cs_monero_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/cs_monero_flutter_libs/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`) @@ -76,6 +85,7 @@ DEPENDENCIES: - frostdart (from `Flutter/ephemeral/.symlinks/plugins/frostdart/macos`) - isar_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos`) - lelantus (from `Flutter/ephemeral/.symlinks/plugins/lelantus/macos`) + - local_auth_darwin (from `Flutter/ephemeral/.symlinks/plugins/local_auth_darwin/darwin`) - 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`) @@ -83,7 +93,7 @@ DEPENDENCIES: - stack_wallet_backup (from `Flutter/ephemeral/.symlinks/plugins/stack_wallet_backup/macos`) - tor_ffi_plugin (from `Flutter/ephemeral/.symlinks/plugins/tor_ffi_plugin/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - - wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`) + - wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`) - window_size (from `Flutter/ephemeral/.symlinks/plugins/window_size/macos`) SPEC REPOS: @@ -98,6 +108,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/coinlib_flutter/darwin connectivity_plus: :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos + cs_monero_flutter_libs: + :path: Flutter/ephemeral/.symlinks/plugins/cs_monero_flutter_libs/macos desktop_drop: :path: Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos device_info_plus: @@ -120,6 +132,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos lelantus: :path: Flutter/ephemeral/.symlinks/plugins/lelantus/macos + local_auth_darwin: + :path: Flutter/ephemeral/.symlinks/plugins/local_auth_darwin/darwin package_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos path_provider_foundation: @@ -134,8 +148,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/tor_ffi_plugin/macos url_launcher_macos: :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos - wakelock_macos: - :path: Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos + wakelock_plus: + :path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos window_size: :path: Flutter/ephemeral/.symlinks/plugins/window_size/macos @@ -143,27 +157,29 @@ SPEC CHECKSUMS: camera_macos: c2603f5eed16f05076cf17e12030d2ce55a77839 coinlib_flutter: 9275e8255ef67d3da33beb6e117d09ced4f46eb5 connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747 + cs_monero_flutter_libs: e91a436103857259f5855cad4971301a5a29b38d desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 - device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f + device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720 devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225 flutter_libepiccash: be1560a04150c5cc85bcf08d236ec2b3d1f5d8da flutter_libsparkmobile: df2d36af1691379c81249e7be7b68be3c81d388b flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4 - flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea + flutter_secure_storage_macos: 59459653abe1adb92abbc8ea747d79f8d19866c9 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 frostdart: e6bf3119527ccfbcec1b8767da6ede5bb4c4f716 isar_flutter_libs: 43385c99864c168fadba7c9adeddc5d38838ca6a lelantus: 308e42c5a648598936a07a234471dd8cf8e687a0 - package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce - path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 + local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3 + package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7 sqlite3: 292c3e1bfe89f64e51ea7fc7dab9182a017c8630 - sqlite3_flutter_libs: 1be4459672f8168ded2d8667599b8e3ca5e72b83 + sqlite3_flutter_libs: 5ca46c1a04eddfbeeb5b16566164aa7ad1616e7b stack_wallet_backup: 6ebc60b1bdcf11cf1f1cbad9aa78332e1e15778c tor_ffi_plugin: 2566c1ed174688cca560fa0c64b7a799c66f07cb - url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 - wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9 + url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399 + wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269 window_size: 339dafa0b27a95a62a843042038fa6c3c48de195 PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367 diff --git a/pubspec.lock b/pubspec.lock index 7bd79531d..7cee10d78 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,23 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted - version: "61.0.0" + version: "72.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.3.2" analyzer: dependency: "direct dev" description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "6.7.0" another_flushbar: dependency: "direct main" description: @@ -29,10 +34,10 @@ packages: dependency: transitive description: name: ansicolor - sha256: "8bf17a8ff6ea17499e40a2d2542c2f481cd7615760c6d34065cb22bfd22e6880" + sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f" url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.3" archive: dependency: "direct main" description: @@ -45,18 +50,10 @@ packages: dependency: transitive description: name: args - sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.4.2" - asn1lib: - dependency: transitive - description: - name: asn1lib - sha256: "21afe4333076c02877d14f4a89df111e658a6d466cbfc802eb705eb91bd5adfd" - url: "https://pub.dev" - source: hosted - version: "1.5.0" + version: "2.6.0" async: dependency: "direct main" description: @@ -69,18 +66,18 @@ packages: dependency: "direct main" description: name: barcode_scan2 - sha256: "0b0625d27841a21e36e896195d86b2aada335e3c486f63647cce701495718e16" + sha256: a2ab566027cd57b2795ea42aa26835dbaa8fe70bcc1aff54942a14d3705dff97 url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "4.3.3" basic_utils: dependency: "direct main" description: name: basic_utils - sha256: "8815477fcf58499e42326bd858e391442425fa57db9a45e48e15224c62049262" + sha256: "2064b21d3c41ed7654bc82cc476fd65542e04d60059b74d5eed490a4da08fc6c" url: "https://pub.dev" source: hosted - version: "5.5.4" + version: "5.7.0" bech32: dependency: "direct main" description: @@ -150,6 +147,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.0" + blockchain_utils: + dependency: "direct main" + description: + name: blockchain_utils + sha256: ebb6c336ba0120de0982c50d8bc597cb494a530bd22bd462895bb5cebde405af + url: "https://pub.dev" + source: hosted + version: "3.4.0" boolean_selector: dependency: transitive description: @@ -194,34 +199,34 @@ packages: dependency: transitive description: name: build_daemon - sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.2" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: d912852cce27c9e80a93603db721c267716894462e7033165178b91138587972 + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" url: "https://pub.dev" source: hosted - version: "2.4.6" + version: "2.4.13" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41" + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 url: "https://pub.dev" source: hosted - version: "7.2.10" + version: "7.3.2" built_collection: dependency: transitive description: @@ -234,18 +239,18 @@ packages: dependency: transitive description: name: built_value - sha256: ff627b645b28fb8bdb69e645f910c2458fd6b65f6585c3a53e0626024897dedf + sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb url: "https://pub.dev" source: hosted - version: "8.6.2" + version: "8.9.2" calendar_date_picker2: dependency: "direct main" description: name: calendar_date_picker2 - sha256: "7ff3f372faff6814a2ba69427d116fb9a3d52e28644b9de4b06db6638fdac798" + sha256: "986955aea43081c8cf70fe01735ccdfe9a7041218b2be53ed92d5d4e639e8a1a" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.7" camera_linux: dependency: "direct main" description: @@ -258,10 +263,10 @@ packages: dependency: "direct main" description: name: camera_macos - sha256: e2ac75c56560f0e86a44de839e6e7f792d786e224c653d51d0c745db80adaff8 + sha256: a0e15729caf4e7c2831b9cd964e8c2e2ea985cd816e56316be03355de44aa743 url: "https://pub.dev" source: hosted - version: "0.0.8" + version: "0.0.9" camera_platform_interface: dependency: "direct main" description: @@ -279,6 +284,14 @@ packages: url: "https://github.com/cypherstack/packages.git" source: git version: "0.2.4" + cbor: + dependency: "direct main" + description: + name: cbor + sha256: "69b1fe99f4632acc597034d73a5eb440f82667b58e2489223bb798e31b6c90db" + url: "https://pub.dev" + source: hosted + version: "6.3.3" characters: dependency: transitive description: @@ -307,10 +320,10 @@ packages: dependency: transitive description: name: cli_util - sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "0.4.2" clock: dependency: transitive description: @@ -323,28 +336,28 @@ packages: dependency: transitive description: name: code_builder - sha256: "315a598c7fbe77f22de1c9da7cfd6fd21816312f16ffa124453b4fc679e540f1" + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" url: "https://pub.dev" source: hosted - version: "4.6.0" + version: "4.10.1" coinlib: dependency: "direct overridden" description: path: coinlib - ref: b88e68e2e10ffe54d802deeed6b9e83da7721a1f - resolved-ref: b88e68e2e10ffe54d802deeed6b9e83da7721a1f - url: "https://github.com/peercoin/coinlib.git" + ref: "0acacfd17eacf72135c693a7b862bd9b7cc56739" + resolved-ref: "0acacfd17eacf72135c693a7b862bd9b7cc56739" + url: "https://github.com/julian-CStack/coinlib.git" source: git - version: "2.1.0-rc.1" + version: "2.2.0" coinlib_flutter: dependency: "direct main" description: path: coinlib_flutter - ref: b88e68e2e10ffe54d802deeed6b9e83da7721a1f - resolved-ref: b88e68e2e10ffe54d802deeed6b9e83da7721a1f - url: "https://github.com/peercoin/coinlib.git" + ref: "0acacfd17eacf72135c693a7b862bd9b7cc56739" + resolved-ref: "0acacfd17eacf72135c693a7b862bd9b7cc56739" + url: "https://github.com/julian-CStack/coinlib.git" source: git - version: "2.1.0-rc.1" + version: "2.2.0" collection: dependency: transitive description: @@ -353,6 +366,15 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + compat: + dependency: "direct main" + description: + path: compat + ref: b2b12cfeaf15d057ea18b14c196e04f3002de2da + resolved-ref: b2b12cfeaf15d057ea18b14c196e04f3002de2da + url: "https://github.com/cypherstack/cs_monero" + source: git + version: "1.0.0" connectivity_plus: dependency: "direct main" description: @@ -373,26 +395,26 @@ packages: dependency: "direct main" description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" coverage: dependency: transitive description: name: coverage - sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" + sha256: "88b0fddbe4c92910fefc09cc0248f5e7f0cd23e450ded4c28f16ab8ee8f83268" url: "https://pub.dev" source: hosted - version: "1.7.2" + version: "1.10.0" cross_file: dependency: transitive description: name: cross_file - sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" url: "https://pub.dev" source: hosted - version: "0.3.4+1" + version: "0.3.4+2" crypto: dependency: "direct main" description: @@ -405,39 +427,106 @@ packages: dependency: transitive description: name: cryptography - sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35 + sha256: d146b76d33d94548cf035233fbc2f4338c1242fa119013bead807d033fc4ae05 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.7.0" + cs_monero: + dependency: "direct main" + description: + name: cs_monero + sha256: b9b9db6602361587b1ce512002f174fd833818ff2a63787c3058e0532fc0d9d8 + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre" + cs_monero_flutter_libs: + dependency: "direct main" + description: + name: cs_monero_flutter_libs + sha256: ccfd2c80e3f283f447602ecc548c9922b526002928a0fa1d34f1d6d74f73952e + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre.0" + cs_monero_flutter_libs_android: + dependency: transitive + description: + name: cs_monero_flutter_libs_android + sha256: "8a03a93b84a091a6c09be2a3504002885af5e3e8e316b2776544271e9509d352" + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre" + cs_monero_flutter_libs_android_arm64_v8a: + dependency: transitive + description: + name: cs_monero_flutter_libs_android_arm64_v8a + sha256: a412c30e8f72aefc2671f2ed76b50fdb70fc9eaa697f8c7050e0ede941f5863e + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre" + cs_monero_flutter_libs_android_armeabi_v7a: + dependency: transitive + description: + name: cs_monero_flutter_libs_android_armeabi_v7a + sha256: "2177af9a62ca9c2997f88af09d54c784dc1ee49a3540abe73c0271d25eb8dadb" + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre" + cs_monero_flutter_libs_android_x86_64: + dependency: transitive + description: + name: cs_monero_flutter_libs_android_x86_64 + sha256: ac5e03624c86438bbe47c986dab5bfe1fb3060a0b4bdb5dd8eea09795a5fc2c8 + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre" + cs_monero_flutter_libs_ios: + dependency: transitive + description: + name: cs_monero_flutter_libs_ios + sha256: ec2e5b9b3ae3100f390deeff6114ffe3259a0701fafdc0f1028996e0da78b17b + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre.0" + cs_monero_flutter_libs_linux: + dependency: transitive + description: + name: cs_monero_flutter_libs_linux + sha256: "65651535e028211d4c535dac53fdfec940935f1037f0a01bfdf4f6cf8b904362" + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre" + cs_monero_flutter_libs_macos: + dependency: transitive + description: + name: cs_monero_flutter_libs_macos + sha256: "609586b4e4524452698b4877ff886ad9aafd721373cddebba45d9d8a63a8cfc9" + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre" + cs_monero_flutter_libs_platform_interface: + dependency: transitive + description: + name: cs_monero_flutter_libs_platform_interface + sha256: "9df4ced42f5746c85c008f504f70b39efd05aa409bb82eaf4b2058d8454e0bb7" + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre" + cs_monero_flutter_libs_windows: + dependency: transitive + description: + name: cs_monero_flutter_libs_windows + sha256: "4294f62e40ba2f155c52fccfdbb12029ed5c856ea8a546aebb3ebc94bc856e43" + url: "https://pub.dev" + source: hosted + version: "1.0.0-pre" csslib: dependency: transitive description: name: csslib - sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" url: "https://pub.dev" source: hosted - version: "1.0.0" - cw_core: - dependency: "direct main" - description: - path: "crypto_plugins/flutter_libmonero/cw_core" - relative: true - source: path - version: "0.0.1" - cw_monero: - dependency: "direct main" - description: - path: "crypto_plugins/flutter_libmonero/cw_monero" - relative: true - source: path - version: "0.0.1" - cw_wownero: - dependency: "direct main" - description: - path: "crypto_plugins/flutter_libmonero/cw_wownero" - relative: true - source: path - version: "0.0.1" + version: "1.0.2" dart_base_x: dependency: transitive description: @@ -474,10 +563,10 @@ packages: dependency: transitive description: name: dart_style - sha256: abd7625e16f51f554ea244d090292945ec4d4be7bfbaf2ec8cccea568919d334 + sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.3.7" dartx: dependency: transitive description: @@ -490,10 +579,10 @@ packages: dependency: transitive description: name: dbus - sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" url: "https://pub.dev" source: hosted - version: "0.7.8" + version: "0.7.10" decimal: dependency: "direct main" description: @@ -506,18 +595,18 @@ packages: dependency: "direct dev" description: name: dependency_validator - sha256: "08349175533ed0bd06eb9b6043cde66c45b2bfc7ebc222a7542cdb1324f1bf03" + sha256: f727a5627aa405965fab4aef4f468e50a9b632ba0737fd2f98c932fec6d712b9 url: "https://pub.dev" source: hosted - version: "3.2.2" + version: "3.2.3" desktop_drop: dependency: "direct main" description: name: desktop_drop - sha256: ebba9c9cb0b54385998a977d741cc06fd8324878c08d5a36e9da61cd56b04cc6 + sha256: d55a010fe46c8e8fcff4ea4b451a9ff84a162217bdb3b2a0aa1479776205e15d url: "https://pub.dev" source: hosted - version: "0.4.3" + version: "0.4.4" device_info_plus: dependency: "direct main" description: @@ -538,18 +627,26 @@ packages: dependency: "direct main" description: name: devicelocale - sha256: "09cc0bce937b34dafcaac0b2a9b350d763dd16770f15e59560b7abaaaad3d65b" + sha256: "0812b66f9eac57bc55c6ed4c178e0779440aa4e4e7c7e32fe1db02a758501d0e" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.7.1" dio: dependency: transitive description: name: dio - sha256: "11e40df547d418cc0c4900a9318b26304e665da6fa4755399a9ff9efd09034b5" + sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260" url: "https://pub.dev" source: hosted - version: "5.4.3+1" + version: "5.7.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" + url: "https://pub.dev" + source: hosted + version: "2.0.0" dropdown_button2: dependency: "direct main" description: @@ -562,18 +659,18 @@ packages: dependency: transitive description: name: ed25519_hd_key - sha256: c5c9f11a03f5789bf9dcd9ae88d641571c802640851f1cacdb13123f171b3a26 + sha256: "31e191ec97492873067e46dc9cc0c7d55170559c83a478400feffa0627acaccf" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" eip1559: dependency: transitive description: name: eip1559 - sha256: de454d6321bd753eb79116e9ec4f8df20895c2e97f9a3839a032f3a728985516 + sha256: c2b81ac85f3e0e71aaf558201dd9a4600f051ece7ebacd0c5d70065c9b458004 url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.6.2" eip55: dependency: transitive description: @@ -599,14 +696,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.9" - encrypt: - dependency: transitive - description: - name: encrypt - sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" - url: "https://pub.dev" - source: hosted - version: "5.0.3" equatable: dependency: "direct main" description: @@ -627,10 +716,10 @@ packages: dependency: "direct main" description: name: event_bus - sha256: "44baa799834f4c803921873e7446a2add0f3efa45e101a054b1f0ab9b95f8edc" + sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" fake_async: dependency: transitive description: @@ -668,10 +757,10 @@ packages: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" fixnum_nanodart: dependency: transitive description: @@ -702,10 +791,10 @@ packages: dependency: "direct main" description: name: flutter_hooks - sha256: "7c8db779c2d1010aa7f9ea3fbefe8f86524fcb87b69e8b0af31e1a4b55422dec" + sha256: cde36b12f7188c85286fba9b38cc5a902e7279f36dd676967106c041dc9dde70 url: "https://pub.dev" source: hosted - version: "0.20.3" + version: "0.20.5" flutter_launcher_icons: dependency: "direct dev" description: @@ -721,78 +810,63 @@ packages: relative: true source: path version: "0.0.1" - flutter_libmonero: - dependency: "direct main" - description: - path: "crypto_plugins/flutter_libmonero" - relative: true - source: path - version: "0.0.1" flutter_libsparkmobile: dependency: "direct main" description: path: "." - ref: "69e9a50715b89497951eba67f1313549708b7c6d" - resolved-ref: "69e9a50715b89497951eba67f1313549708b7c6d" - url: "https://github.com/mrcyjanek/flutter_libsparkmobile.git" + ref: cc7b43b731e4a7906dd25d4364a08e34554cee19 + resolved-ref: cc7b43b731e4a7906dd25d4364a08e34554cee19 + url: "https://github.com/cypherstack/flutter_libsparkmobile.git" source: git version: "0.0.1" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - sha256: f9a05409385b77b06c18f200a41c7c2711ebf7415669350bb0f8474c07bd40d1 + sha256: "674173fd3c9eda9d4c8528da2ce0ea69f161577495a9cc835a2a4ecd7eadeb35" url: "https://pub.dev" source: hosted - version: "17.0.0" + version: "17.2.4" flutter_local_notifications_linux: dependency: transitive description: name: flutter_local_notifications_linux - sha256: "33f741ef47b5f63cc7f78fe75eeeac7e19f171ff3c3df054d84c1e38bedb6a03" + sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af url: "https://pub.dev" source: hosted - version: "4.0.0+1" + version: "4.0.1" flutter_local_notifications_platform_interface: dependency: transitive description: name: flutter_local_notifications_platform_interface - sha256: "7cf643d6d5022f3baed0be777b0662cce5919c0a7b86e700299f22dc4ae660ef" + sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66" url: "https://pub.dev" source: hosted - version: "7.0.0+1" - flutter_mobx: - dependency: transitive - description: - name: flutter_mobx - sha256: "0da4add0016387a7bf309a0d0c41d36c6b3ae25ed7a176409267f166509e723e" - url: "https://pub.dev" - source: hosted - version: "2.0.6+5" + version: "7.2.0" flutter_native_splash: dependency: "direct main" description: name: flutter_native_splash - sha256: ecff62b3b893f2f665de7e4ad3de89f738941fcfcaaba8ee601e749efafa4698 + sha256: "17d9671396fb8ec45ad10f4a975eb8a0f70bedf0fdaf0720b31ea9de6da8c4da" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.7" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f" + sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398" url: "https://pub.dev" source: hosted - version: "2.0.19" + version: "2.0.23" flutter_riverpod: dependency: "direct main" description: @@ -813,34 +887,34 @@ packages: dependency: transitive description: name: flutter_secure_storage_linux - sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e" + sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" flutter_secure_storage_macos: dependency: transitive description: name: flutter_secure_storage_macos - sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c + sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.2" flutter_secure_storage_platform_interface: dependency: transitive description: name: flutter_secure_storage_platform_interface - sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e" + sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.2" flutter_secure_storage_web: dependency: transitive description: name: flutter_secure_storage_web - sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20" + sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.1" flutter_secure_storage_windows: dependency: transitive description: @@ -853,10 +927,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338" + sha256: "1b7723a814d84fb65869ea7115cdb3ee7c3be5a27a755c1ec60e049f6b9fcbb2" url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.0.11" flutter_test: dependency: "direct dev" description: flutter @@ -879,10 +953,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "4.0.0" frostdart: dependency: "direct main" description: @@ -899,8 +973,8 @@ packages: dependency: "direct main" description: path: "." - ref: "7dd8ff0dc9cb0caaac795fa44841a26437edfec3" - resolved-ref: "7dd8ff0dc9cb0caaac795fa44841a26437edfec3" + ref: "9dc883f4432c8db4ec44cb8cc836963295d63952" + resolved-ref: "9dc883f4432c8db4ec44cb8cc836963295d63952" url: "https://github.com/cypherstack/fusiondart.git" source: git version: "1.0.0" @@ -916,18 +990,18 @@ packages: dependency: "direct main" description: name: google_fonts - sha256: "6b6f10f0ce3c42f6552d1c70d2c28d764cf22bb487f50f66cca31dcd5194f4d6" + sha256: "2776c66b3e97c6cdd58d1bd3281548b074b64f1fd5c8f82391f7456e38849567" url: "https://pub.dev" source: hosted - version: "4.0.4" + version: "4.0.5" graphs: dependency: transitive description: name: graphs - sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" hex: dependency: "direct main" description: @@ -972,10 +1046,10 @@ packages: dependency: transitive description: name: html - sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec" url: "https://pub.dev" source: hosted - version: "0.15.4" + version: "0.15.5" http: dependency: "direct main" description: @@ -1000,14 +1074,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + ieee754: + dependency: transitive + description: + name: ieee754 + sha256: "7d87451c164a56c156180d34a4e93779372edd191d2c219206100b976203128c" + url: "https://pub.dev" + source: hosted + version: "1.0.3" image: dependency: transitive description: name: image - sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf + sha256: f31d52537dc417fdcde36088fdf11d191026fd5e4fae742491ebd40e5a8bea7d url: "https://pub.dev" source: hosted - version: "4.0.17" + version: "4.3.0" import_sorter: dependency: "direct dev" description: @@ -1041,26 +1123,26 @@ packages: dependency: "direct main" description: name: isar - sha256: "5be35dbc489880fccc535da3d1c4b3f5fdeee6ebfcacd4b149e39e803c4029cd" - url: "https://pub.dev" + sha256: e17a9555bc7f22ff26568b8c64d019b4ffa2dc6bd4cb1c8d9b269aefd32e53ad + url: "https://pub.isar-community.dev" source: hosted - version: "3.0.5" + version: "3.1.8" isar_flutter_libs: dependency: "direct main" description: name: isar_flutter_libs - sha256: "9794524734856a8a3629652f9f359b66e3fea3cebeec4dbdeb3e3a8fb253073e" - url: "https://pub.dev" + sha256: "78710781e658ce4bff59b3f38c5b2735e899e627f4e926e1221934e77b95231a" + url: "https://pub.isar-community.dev" source: hosted - version: "3.0.5" + version: "3.1.8" isar_generator: dependency: "direct dev" description: name: isar_generator - sha256: ee4ab5d5b251bc7e86e1257793b57af100065831f00f3a12404b177ae53c2d69 - url: "https://pub.dev" + sha256: "484e73d3b7e81dbd816852fe0b9497333118a9aeb646fd2d349a62cc8980ffe1" + url: "https://pub.isar-community.dev" source: hosted - version: "3.0.5" + version: "3.1.8" js: dependency: transitive description: @@ -1073,26 +1155,26 @@ packages: dependency: transitive description: name: json_annotation - sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted - version: "4.8.1" + version: "4.9.0" json_rpc_2: dependency: transitive description: name: json_rpc_2 - sha256: "5e469bffa23899edacb7b22787780068d650b106a21c76db3c49218ab7ca447e" + sha256: "246b321532f0e8e2ba474b4d757eaa558ae4fdd0688fdbc1e1ca9705f9b8ca0e" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" json_serializable: dependency: transitive description: name: json_serializable - sha256: aa1f5a8912615733e0fdc7a02af03308933c93235bdc8d50d0b0c8a8ccb0b969 + sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b url: "https://pub.dev" source: hosted - version: "6.7.1" + version: "6.8.0" keyboard_dismisser: dependency: "direct main" description: @@ -1144,26 +1226,74 @@ packages: dependency: "direct main" description: name: local_auth - sha256: d3fece0749101725b03206f84a7dab7aaafb702dbbd09131ff8d8173259a9b19 + sha256: "434d854cf478f17f12ab29a76a02b3067f86a63a6d6c4eb8fbfdcfe4879c1b7b" url: "https://pub.dev" source: hosted - version: "1.1.11" + version: "2.3.0" + local_auth_android: + dependency: transitive + description: + name: local_auth_android + sha256: "6763aaf8965f21822624cb2fd3c03d2a8b3791037b5efb0fe4b13e110f5afc92" + url: "https://pub.dev" + source: hosted + version: "1.0.46" + local_auth_darwin: + dependency: transitive + description: + name: local_auth_darwin + sha256: "6d2950da311d26d492a89aeb247c72b4653ddc93601ea36a84924a396806d49c" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + local_auth_platform_interface: + dependency: transitive + description: + name: local_auth_platform_interface + sha256: "1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a" + url: "https://pub.dev" + source: hosted + version: "1.0.10" + local_auth_windows: + dependency: transitive + description: + name: local_auth_windows + sha256: bc4e66a29b0fdf751aafbec923b5bed7ad6ed3614875d8151afe2578520b2ab5 + url: "https://pub.dev" + source: hosted + version: "1.0.11" + logger: + dependency: transitive + description: + name: logger + sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" + url: "https://pub.dev" + source: hosted + version: "2.4.0" logging: dependency: transitive description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" lottie: dependency: "direct main" description: name: lottie - sha256: b8bdd54b488c54068c57d41ae85d02808da09e2bee8b8dd1f59f441e7efa60cd + sha256: a93542cc2d60a7057255405f62252533f8e8956e7e06754955669fd32fb4b216 url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.7.0" + macros: + dependency: transitive + description: + name: macros + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + url: "https://pub.dev" + source: hosted + version: "0.1.2-main.4" matcher: dependency: transitive description: @@ -1200,18 +1330,10 @@ packages: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" url: "https://pub.dev" source: hosted - version: "1.0.4" - mobx: - dependency: transitive - description: - name: mobx - sha256: "0afcf88b3ee9d6819890bf16c11a727fc8c62cf736fda8e5d3b9b4eace4e62ea" - url: "https://pub.dev" - source: hosted - version: "2.2.0" + version: "1.0.6" mockingjay: dependency: "direct dev" description: @@ -1236,23 +1358,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.0" - monero: - dependency: "direct main" - description: - path: "." - ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5 - resolved-ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5 - url: "https://github.com/mrcyjanek/monero.dart" - source: git - version: "0.0.0" mutex: dependency: "direct main" description: name: mutex - sha256: "03116a4e46282a671b46c12de649d72c0ed18188ffe12a8d0fc63e83f4ad88f4" + sha256: "8827da25de792088eb33e572115a5eb0d61d61a3c01acbc8bcbe76ed78f1a1f2" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.0" nanodart: dependency: "direct main" description: @@ -1277,6 +1390,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.2" + on_chain: + dependency: "direct main" + description: + name: on_chain + sha256: "54d8117ff007b1f4a71ce8076c2a0bbfb592e5ce61ae397c68a67d70c9246a5d" + url: "https://pub.dev" + source: hosted + version: "4.3.0" package_config: dependency: transitive description: @@ -1289,18 +1410,18 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "6ff267fcd9d48cb61c8df74a82680e8b82e940231bb5f68356672fde0397334a" + sha256: df3eb3e0aed5c1107bb0fdb80a8e82e778114958b1c5ac5644fb1ac9cae8a998 url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "8.1.0" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" + sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" path: dependency: transitive description: @@ -1313,34 +1434,34 @@ packages: dependency: transitive description: name: path_parsing - sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + sha256: caa17e8f0b386eb190dd5b6a3b71211c76375aa8b6ffb4465b5863d019bdb334 url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.3" path_provider: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.5" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1" + sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.12" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -1353,58 +1474,66 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" permission_handler: dependency: "direct main" description: name: permission_handler - sha256: ad65ba9af42a3d067203641de3fd9f547ded1410bad3b84400c2b4899faede70 + sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb" url: "https://pub.dev" source: hosted - version: "11.0.0" + version: "11.3.1" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: f23cfe9af0d49c6b9fd8a8b09f7b3301ca7e346204939b5afef4404d36d2608f + sha256: "71bbecfee799e65aff7c744761a57e817e73b738fedf62ab7afd5593da21f9f1" url: "https://pub.dev" source: hosted - version: "11.0.1" + version: "12.0.13" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5" + sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0 url: "https://pub.dev" source: hosted - version: "9.1.4" + version: "9.4.5" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: af26edbbb1f2674af65a8f4b56e1a6f526156bc273d0e65dd8075fab51c78851 + url: "https://pub.dev" + source: hosted + version: "0.1.3+2" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface - sha256: f2343e9fa9c22ae4fd92d4732755bfe452214e7189afcc097380950cf567b4b2 + sha256: e9c8eadee926c4532d0305dff94b85bf961f16759c3af791486613152af4b4f9 url: "https://pub.dev" source: hosted - version: "3.11.5" + version: "4.2.3" permission_handler_windows: dependency: transitive description: name: permission_handler_windows - sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098 + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" url: "https://pub.dev" source: hosted - version: "0.1.3" + version: "0.2.1" petitparser: dependency: transitive description: @@ -1441,10 +1570,10 @@ packages: dependency: "direct main" description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.9.1" pool: dependency: transitive description: @@ -1457,10 +1586,10 @@ packages: dependency: transitive description: name: pretty_dio_logger - sha256: "00b80053063935cf9a6190da344c5373b9d0e92da4c944c878ff2fbef0ef6dc2" + sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.4.0" process: dependency: transitive description: @@ -1473,10 +1602,10 @@ packages: dependency: transitive description: name: protobuf - sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08" + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "3.1.0" pub_semver: dependency: transitive description: @@ -1489,18 +1618,18 @@ packages: dependency: transitive description: name: pubspec_parse - sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 url: "https://pub.dev" source: hosted - version: "1.2.3" + version: "1.3.0" qr: dependency: transitive description: name: qr - sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3" + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" qr_flutter: dependency: "direct main" description: @@ -1513,18 +1642,18 @@ packages: dependency: transitive description: name: quiver - sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 + sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" rational: dependency: transitive description: name: rational - sha256: ba58e9e18df9abde280e8b10051e4bce85091e41e8e7e411b6cde2e738d357cf + sha256: cb808fb6f1a839e6fc5f7d8cb3b0a10e1db48b3be102de73938c627f0b636336 url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.3" retry: dependency: transitive description: @@ -1561,18 +1690,18 @@ packages: dependency: "direct main" description: name: share_plus - sha256: "6cec740fa0943a826951223e76218df002804adb588235a8910dc3d6b0654e11" + sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900" url: "https://pub.dev" source: hosted - version: "7.1.0" + version: "7.2.2" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - sha256: "357412af4178d8e11d14f41723f80f12caea54cf0d5cd29af9dcdab85d58aea7" + sha256: "251eb156a8b5fa9ce033747d73535bf53911071f8d3b6f4f0b578505ce0d4496" url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.4.0" shelf: dependency: transitive description: @@ -1593,18 +1722,18 @@ packages: dependency: transitive description: name: shelf_static - sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.3" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "2.0.0" sky_engine: dependency: transitive description: flutter @@ -1614,36 +1743,36 @@ packages: dependency: "direct main" description: name: socks5_proxy - sha256: "1d21b5606169654bbf4cfb904e8e6ed897e9f763358709f87310c757096d909a" + sha256: e0cba6917cd374de6f6cb0ce081e50e6efc24c61644b8e9f20c8bf8b91bb0b75 url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.3+dev.3" socks_socket: dependency: transitive description: path: "." ref: master - resolved-ref: ac6d721fe655208a6d488a088a35bab0ddc25702 + resolved-ref: b1fa8ca505e7e488edb4c2859f0218d48b15dead url: "https://github.com/cypherstack/socks_socket.git" source: git - version: "0.1.0" + version: "1.0.0" solana: dependency: "direct main" description: path: "packages/solana" - ref: "706be5f166d31736c443cca4cd311b7fcfc2a9bf" - resolved-ref: "706be5f166d31736c443cca4cd311b7fcfc2a9bf" + ref: dea799c20bc917f72b18c916ca96bc99fb1bd1c5 + resolved-ref: dea799c20bc917f72b18c916ca96bc99fb1bd1c5 url: "https://github.com/cypherstack/espresso-cash-public.git" source: git - version: "0.30.4" + version: "0.31.0" source_gen: dependency: transitive description: name: source_gen - sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16 + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.5.0" source_helper: dependency: transitive description: @@ -1656,10 +1785,10 @@ packages: dependency: transitive description: name: source_map_stack_trace - sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" source_maps: dependency: transitive description: @@ -1704,8 +1833,8 @@ packages: dependency: "direct main" description: path: "." - ref: ee1da8a9ba1cbeb50c5b354ea1fd5a25b7c5a3ed - resolved-ref: ee1da8a9ba1cbeb50c5b354ea1fd5a25b7c5a3ed + ref: "5efe8f8f259317d32b6f037cf91f62e06125c040" + resolved-ref: "5efe8f8f259317d32b6f037cf91f62e06125c040" url: "https://github.com/cypherstack/stack_wallet_backup.git" source: git version: "0.0.1" @@ -1721,10 +1850,10 @@ packages: dependency: "direct main" description: name: stellar_flutter_sdk - sha256: "574e8f40a1a1a9b18a735272196c8d3c8168a669efc8460a4d5d6f45151e8dce" + sha256: "7d505963fe11d0f90b3f798964c485ed9fa64731c38f14c9b2fb76d5d5bd6cd8" url: "https://pub.dev" source: hosted - version: "1.7.8" + version: "1.8.1" stream_channel: dependency: "direct main" description: @@ -1810,18 +1939,18 @@ packages: dependency: transitive description: name: time - sha256: "83427e11d9072e038364a5e4da559e85869b227cf699a541be0da74f14140124" + sha256: ad8e018a6c9db36cb917a031853a1aae49467a93e0d464683e029537d848c221 url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" timezone: dependency: transitive description: name: timezone - sha256: "1cfd8ddc2d1cfd836bc93e67b9be88c3adaeca6f40a00ca999104c30693cdca0" + sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" url: "https://pub.dev" source: hosted - version: "0.9.2" + version: "0.9.4" timing: dependency: transitive description: @@ -1850,8 +1979,8 @@ packages: dependency: "direct main" description: path: "." - ref: "647cadc3c82c276dc07915b02d24538fd610f220" - resolved-ref: "647cadc3c82c276dc07915b02d24538fd610f220" + ref: "534ec251b339199446b723c01a25d324ae7bb974" + resolved-ref: "534ec251b339199446b723c01a25d324ae7bb974" url: "https://github.com/cypherstack/tor.git" source: git version: "0.0.1" @@ -1867,10 +1996,10 @@ packages: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" universal_io: dependency: transitive description: @@ -1891,66 +2020,66 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" + sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603" url: "https://pub.dev" source: hosted - version: "6.1.14" + version: "6.3.1" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330 + sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193" url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.3.14" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f" + sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e url: "https://pub.dev" source: hosted - version: "6.1.5" + version: "6.3.1" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e + sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.2.0" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88 + sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672" url: "https://pub.dev" source: hosted - version: "3.0.7" + version: "3.2.1" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618" + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.3.2" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2 + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" url: "https://pub.dev" source: hosted - version: "2.0.19" + version: "2.3.3" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069" + sha256: "44cf3aabcedde30f2dba119a9dea3b0f2672fbe6fa96e85536251d678216b3c4" url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.1.3" uuid: dependency: "direct main" description: @@ -1963,26 +2092,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "670f6e07aca990b4a2bcdc08a784193c4ccdd1932620244c3a86bb72a0eac67f" + sha256: "0b9149c6ddb013818075b072b9ddc1b89a5122fff1275d4648d297086b46c4f0" url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.12" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "7451721781d967db9933b63f5733b1c4533022c0ba373a01bdd79d1a5457f69f" + sha256: "2430b973a4ca3c4dbc9999b62b8c719a160100dcbae5c819bae0cacce32c9cdb" url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.12" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "80a13c613c8bde758b1464a1755a7b3a8f2b6cec61fbf0f5a53c94c30f03ba2e" + sha256: f3b9b6e4591c11394d4be4806c63e72d3a41778547b2c1e2a8a04fadcfd7d173 url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.12" vector_math: dependency: transitive description: @@ -1999,22 +2128,6 @@ packages: url: "https://pub.dev" source: hosted version: "14.2.5" - wakelock: - dependency: "direct main" - description: - name: wakelock - sha256: "769ecf42eb2d07128407b50cb93d7c10bd2ee48f0276ef0119db1d25cc2f87db" - url: "https://pub.dev" - source: hosted - version: "0.6.2" - wakelock_macos: - dependency: transitive - description: - name: wakelock_macos - sha256: "047c6be2f88cb6b76d02553bca5a3a3b95323b15d30867eca53a19a0a319d4cd" - url: "https://pub.dev" - source: hosted - version: "0.4.0" wakelock_platform_interface: dependency: transitive description: @@ -2023,14 +2136,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.0" - wakelock_web: - dependency: transitive + wakelock_plus: + dependency: "direct main" description: - name: wakelock_web - sha256: "1b256b811ee3f0834888efddfe03da8d18d0819317f20f6193e2922b41a501b5" + name: wakelock_plus + sha256: bf4ee6f17a2fa373ed3753ad0e602b7603f8c75af006d5b9bdade263928c0484 url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "1.2.8" + wakelock_plus_platform_interface: + dependency: transitive + description: + name: wakelock_plus_platform_interface + sha256: "422d1cdbb448079a8a62a5a770b69baa489f8f7ca21aef47800c726d404f9d16" + url: "https://pub.dev" + source: hosted + version: "1.2.1" wakelock_windows: dependency: "direct overridden" description: @@ -2044,10 +2165,10 @@ packages: dependency: transitive description: name: wallet - sha256: "569c91c2af13a9e1119c001f9c09218eccf3f383eb8d15ba13a5b558010c1bc0" + sha256: "687fd89a16557649b26189e597792962f405797fc64113e8758eabc2c2605c32" url: "https://pub.dev" source: hosted - version: "0.0.12+1" + version: "0.0.13" wasm_interop: dependency: transitive description: @@ -2108,24 +2229,24 @@ packages: dependency: "direct overridden" description: name: win32 - sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a" + sha256: "10169d3934549017f0ae278ccb07f828f9d6ea21573bab0fb77b0e1ef0fce454" url: "https://pub.dev" source: hosted - version: "5.5.4" + version: "5.7.2" win32_registry: dependency: transitive description: name: win32_registry - sha256: e4506d60b7244251bc59df15656a3093501c37fb5af02105a944d73eb95be4c9 + sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.5" window_size: dependency: "direct main" description: path: "plugins/window_size" ref: HEAD - resolved-ref: "6c66ad23ee79749f30a8eece542cf54eaf157ed8" + resolved-ref: eb3964990cf19629c89ff8cb4a37640c7b3d5601 url: "https://github.com/google/flutter-desktop-embedding.git" source: git version: "0.1.0" @@ -2133,10 +2254,10 @@ packages: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.1.0" xml: dependency: transitive description: @@ -2149,10 +2270,10 @@ packages: dependency: transitive description: name: xxh3 - sha256: a92b30944a9aeb4e3d4f3c3d4ddb3c7816ca73475cd603682c4f8149690f56d7 + sha256: cbeb0e1d10f4c6bf67b650f395eac0cc689425b5efc2ba0cc3d3e069a0beaeec url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.1.0" yaml: dependency: transitive description: @@ -2178,5 +2299,5 @@ packages: source: hosted version: "0.2.3" sdks: - dart: ">=3.5.2 <4.0.0" - flutter: ">=3.24.2" + dart: ">=3.5.3 <4.0.0" + flutter: ">=3.24.3" diff --git a/scripts/android/build_all.sh b/scripts/android/build_all.sh index 7cb2e083d..60aa13c6a 100755 --- a/scripts/android/build_all.sh +++ b/scripts/android/build_all.sh @@ -14,7 +14,6 @@ PLUGINS_DIR=../../crypto_plugins (cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh ) (cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh ) -(cd "${PLUGINS_DIR}"/flutter_libmonero/scripts/android/ && ./build_all.sh ) set_rust_to_1720 (cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh ) diff --git a/scripts/android/build_all_campfire.sh b/scripts/android/build_all_campfire.sh index 7cb2e083d..60aa13c6a 100755 --- a/scripts/android/build_all_campfire.sh +++ b/scripts/android/build_all_campfire.sh @@ -14,7 +14,6 @@ PLUGINS_DIR=../../crypto_plugins (cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh ) (cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh ) -(cd "${PLUGINS_DIR}"/flutter_libmonero/scripts/android/ && ./build_all.sh ) set_rust_to_1720 (cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh ) diff --git a/scripts/android/build_all_duo.sh b/scripts/android/build_all_duo.sh index aec2ebbb3..d67e700a8 100755 --- a/scripts/android/build_all_duo.sh +++ b/scripts/android/build_all_duo.sh @@ -16,7 +16,6 @@ PLUGINS_DIR=../../crypto_plugins (cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh ) (cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh ) -(cd "${PLUGINS_DIR}"/flutter_libmonero/scripts/android/ && ./build_all.sh ) set_rust_to_1720 (cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh ) diff --git a/scripts/app_config/configure_campfire.sh b/scripts/app_config/configure_campfire.sh index ae6bba36d..883d67fa0 100755 --- a/scripts/app_config/configure_campfire.sh +++ b/scripts/app_config/configure_campfire.sh @@ -49,7 +49,9 @@ const _appDataDirName = "campfire"; const _shortDescriptionText = "Your privacy. Your wallet. Your Firo."; const _commitHash = "$BUILT_COMMIT_HASH"; -const Set _features = {}; +const Set _features = { + AppFeature.swap +}; const ({String light, String dark})? _appIconAsset = ( light: "assets/in_app_logo_icons/campfire-icon_light.svg", @@ -60,4 +62,6 @@ final List _supportedCoins = List.unmodifiable([ Firo(CryptoCurrencyNetwork.main), ]); +final ({String from, String to}) _swapDefaults = (from: "BTC", to: "FIRO"); + EOF \ No newline at end of file diff --git a/scripts/app_config/configure_stack_duo.sh b/scripts/app_config/configure_stack_duo.sh index 143faf644..7d1a7665a 100755 --- a/scripts/app_config/configure_stack_duo.sh +++ b/scripts/app_config/configure_stack_duo.sh @@ -64,4 +64,6 @@ final List _supportedCoins = List.unmodifiable([ BitcoinFrost(CryptoCurrencyNetwork.test4), ]); +final ({String from, String to}) _swapDefaults = (from: "BTC", to: "XMR"); + EOF \ No newline at end of file diff --git a/scripts/app_config/configure_stack_wallet.sh b/scripts/app_config/configure_stack_wallet.sh index 7f7c51ab7..0fd8e5e8a 100755 --- a/scripts/app_config/configure_stack_wallet.sh +++ b/scripts/app_config/configure_stack_wallet.sh @@ -57,6 +57,7 @@ final List _supportedCoins = List.unmodifiable([ Banano(CryptoCurrencyNetwork.main), Bitcoincash(CryptoCurrencyNetwork.main), BitcoinFrost(CryptoCurrencyNetwork.main), + Cardano(CryptoCurrencyNetwork.main), Dash(CryptoCurrencyNetwork.main), Dogecoin(CryptoCurrencyNetwork.main), Ecash(CryptoCurrencyNetwork.main), @@ -84,4 +85,6 @@ final List _supportedCoins = List.unmodifiable([ Stellar(CryptoCurrencyNetwork.test), ]); +final ({String from, String to}) _swapDefaults = (from: "BTC", to: "XMR"); + EOF \ No newline at end of file diff --git a/scripts/app_config/templates/android/app/build.gradle b/scripts/app_config/templates/android/app/build.gradle index e440e9d0d..b9cebc7b4 100644 --- a/scripts/app_config/templates/android/app/build.gradle +++ b/scripts/app_config/templates/android/app/build.gradle @@ -1,30 +1,10 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } +plugins { + id "com.android.application" + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { @@ -32,47 +12,51 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdkVersion 34 + namespace "com.place.holder" + compileSdk flutter.compileSdkVersion +// ndkVersion flutter.ndkVersion + ndkVersion = "26.1.10909125" -// ndkVersion = "21.1.6352462" -// ndkVersion = "25.2.9519653" - ndkVersion = "23.1.7779620" - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - lintOptions { - disable 'InvalidPackage' - } packagingOptions { pickFirst 'lib/x86/libc++_shared.so' pickFirst 'lib/x86_64/libc++_shared.so' pickFirst 'lib/armeabi-v7a/libc++_shared.so' pickFirst 'lib/arm64-v8a/libc++_shared.so' } + defaultConfig { applicationId "com.place.holder" - minSdkVersion 23 - targetSdkVersion 33 -// ndkVersion = "21.1.6352462" -// ndkVersion = "25.2.9519653" - ndkVersion = "23.1.7779620" - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + minSdk flutter.minSdkVersion + targetSdk flutter.targetSdkVersion + versionCode flutter.versionCode + versionName flutter.versionName + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + coreLibraryDesugaringEnabled true + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17 + } + + dependencies { + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") + } + ndk { abiFilters "x86_64","armeabi-v7a", "arm64-v8a" } - externalNativeBuild { - cmake { - arguments "-DANDROID_STL=c++_shared", '-DBUILD_TESTING=OFF', "-DANDROID_TOOLCHAIN=clang -v" - cppFlags "-frtti -fexceptions -v -DANDROID -std=c++17" -// cppFlags "-std=c++11" - version "3.10.2" - } - } +// externalNativeBuild { +// cmake { +// arguments "-DANDROID_STL=c++_shared", '-DBUILD_TESTING=OFF', "-DANDROID_TOOLCHAIN=clang -v" +// cppFlags "-frtti -fexceptions -v -DANDROID -std=c++17" +//// cppFlags "-std=c++11" +// version "3.10.2" +// } +// } } signingConfigs { @@ -99,15 +83,18 @@ android { 'proguard-rules.pro' } } + + // not required. Just info + tasks.whenTaskAdded { task -> + if (task.name == 'assembleDebug') { + task.doFirst { + println "The compileSdkVersion is $flutter.compileSdkVersion" + println "The targetSdkVersion is $flutter.targetSdkVersion" + } + } + } } flutter { source '../..' -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' -} +} \ No newline at end of file diff --git a/scripts/app_config/templates/android/app/src/main/AndroidManifest.xml b/scripts/app_config/templates/android/app/src/main/AndroidManifest.xml index 2ae40734c..78a92aa5c 100644 --- a/scripts/app_config/templates/android/app/src/main/AndroidManifest.xml +++ b/scripts/app_config/templates/android/app/src/main/AndroidManifest.xml @@ -74,4 +74,14 @@ + + + + + + + \ No newline at end of file diff --git a/scripts/app_config/templates/ios/Runner.xcodeproj/project.pbxproj b/scripts/app_config/templates/ios/Runner.xcodeproj/project.pbxproj index 4b521cca2..c89885057 100644 --- a/scripts/app_config/templates/ios/Runner.xcodeproj/project.pbxproj +++ b/scripts/app_config/templates/ios/Runner.xcodeproj/project.pbxproj @@ -18,8 +18,6 @@ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; B49D91439948369648AB0603 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51604430FD0FD1FA5C4767A0 /* Pods_Runner.framework */; }; - CEFE41202C20387E00086DB4 /* WowneroWallet.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE4F88332C202CF4007A8C67 /* WowneroWallet.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - CEFE41212C20387E00086DB4 /* MoneroWallet.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE4F88302C202CEE007A8C67 /* MoneroWallet.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -34,17 +32,6 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; - CE6B5DEA2BF26A3300CF1F44 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - CEFE41202C20387E00086DB4 /* WowneroWallet.framework in CopyFiles */, - CEFE41212C20387E00086DB4 /* MoneroWallet.framework in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -192,9 +179,9 @@ 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, - CE6B5DEA2BF26A3300CF1F44 /* CopyFiles */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, FD1CA371131604E6658D4146 /* [CP] Embed Pods Frameworks */, + 4823D12ED8C268BC85F26ABD /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -271,6 +258,24 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; }; + 4823D12ED8C268BC85F26ABD /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/permission_handler_apple/permission_handler_apple_privacy.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/permission_handler_apple_privacy.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -325,10 +330,12 @@ "${BUILT_PRODUCTS_DIR}/barcode_scan2/barcode_scan2.framework", "${BUILT_PRODUCTS_DIR}/coinlib_flutter/secp256k1.framework", "${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework", + "${PODS_ROOT}/../.symlinks/plugins/cs_monero_flutter_libs/ios/Frameworks/MoneroWallet.framework", + "${PODS_ROOT}/../.symlinks/plugins/cs_monero_flutter_libs/ios/Frameworks/WowneroWallet.framework", + "${BUILT_PRODUCTS_DIR}/cs_monero_flutter_libs/cs_monero_flutter_libs.framework", "${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework", "${BUILT_PRODUCTS_DIR}/devicelocale/devicelocale.framework", "${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework", - "${BUILT_PRODUCTS_DIR}/flutter_libmonero/flutter_libmonero.framework", "${PODS_ROOT}/../.symlinks/plugins/flutter_libsparkmobile/ios/flutter_libsparkmobile.framework", "${BUILT_PRODUCTS_DIR}/flutter_local_notifications/flutter_local_notifications.framework", "${BUILT_PRODUCTS_DIR}/flutter_native_splash/flutter_native_splash.framework", @@ -337,7 +344,7 @@ "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", "${BUILT_PRODUCTS_DIR}/isar_flutter_libs/isar_flutter_libs.framework", "${BUILT_PRODUCTS_DIR}/lelantus/lelantus.framework", - "${BUILT_PRODUCTS_DIR}/local_auth/local_auth.framework", + "${BUILT_PRODUCTS_DIR}/local_auth_darwin/local_auth_darwin.framework", "${BUILT_PRODUCTS_DIR}/package_info_plus/package_info_plus.framework", "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", "${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework", @@ -346,7 +353,7 @@ "${BUILT_PRODUCTS_DIR}/stack_wallet_backup/stack_wallet_backup.framework", "${BUILT_PRODUCTS_DIR}/tor_ffi_plugin/tor_ffi_plugin.framework", "${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework", - "${BUILT_PRODUCTS_DIR}/wakelock/wakelock.framework", + "${BUILT_PRODUCTS_DIR}/wakelock_plus/wakelock_plus.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -360,10 +367,12 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/barcode_scan2.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MoneroWallet.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WowneroWallet.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cs_monero_flutter_libs.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/devicelocale.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_libmonero.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_libsparkmobile.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_local_notifications.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_native_splash.framework", @@ -372,7 +381,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/isar_flutter_libs.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/lelantus.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/local_auth.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/local_auth_darwin.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework", @@ -381,7 +390,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/stack_wallet_backup.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/tor_ffi_plugin.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/wakelock.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/wakelock_plus.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -489,7 +498,6 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/../crypto_plugins/flutter_liblelantus/scripts/ios/mobileliblelantus", - "$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios", "$(PROJECT_DIR)", ); HEADER_SEARCH_PATHS = ( @@ -501,8 +509,6 @@ "\"${PODS_CONFIGURATION_BUILD_DIR}/barcode_scan2/barcode_scan2.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/connectivity/connectivity.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/cryptography_flutter/cryptography_flutter.framework/Headers\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_monero/cw_monero.framework/Headers\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_shared_external/cw_shared_external.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/devicelocale/devicelocale.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_libepiccash/flutter_libepiccash.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_libmonero/flutter_libmonero.framework/Headers\"", @@ -520,12 +526,6 @@ "\"${PODS_CONFIGURATION_BUILD_DIR}/stack_wallet_backup/stack_wallet_backup.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/url_launcher_ios/url_launcher_ios.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/wakelock/wakelock.framework/Headers\"", - "${PODS_ROOT}/cw_monero/Classes/*.h", - "${PODS_ROOT}/cw_monero/Classes/*.h", - "${PODS_ROOT}/cw_monero/External/ios/include/**", - "${PODS_ROOT}/cw_monero/Classes/*.h", - "${PODS_ROOT}/cw_monero/External/ios/include", - "${PODS_ROOT}/cw_shared_external/External/ios/include/**", "$(PROJECT_DIR)/../crypto_plugins/flutter_libepiccash/ios/include", ); INFOPLIST_FILE = Runner/Info.plist; @@ -537,7 +537,6 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", - "$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios/**", "$(PROJECT_DIR)/../crypto_plugins/flutter_libepiccash/ios/libs", ); MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; @@ -681,7 +680,6 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/../crypto_plugins/flutter_liblelantus/scripts/ios/mobileliblelantus", - "$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios/**", "$(PROJECT_DIR)", ); HEADER_SEARCH_PATHS = ( @@ -693,8 +691,6 @@ "\"${PODS_CONFIGURATION_BUILD_DIR}/barcode_scan2/barcode_scan2.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/connectivity/connectivity.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/cryptography_flutter/cryptography_flutter.framework/Headers\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_monero/cw_monero.framework/Headers\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_shared_external/cw_shared_external.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/devicelocale/devicelocale.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_libepiccash/flutter_libepiccash.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_libmonero/flutter_libmonero.framework/Headers\"", @@ -712,12 +708,6 @@ "\"${PODS_CONFIGURATION_BUILD_DIR}/stack_wallet_backup/stack_wallet_backup.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/url_launcher_ios/url_launcher_ios.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/wakelock/wakelock.framework/Headers\"", - "${PODS_ROOT}/cw_monero/Classes/*.h", - "${PODS_ROOT}/cw_monero/Classes/*.h", - "${PODS_ROOT}/cw_monero/External/ios/include/**", - "${PODS_ROOT}/cw_monero/Classes/*.h", - "${PODS_ROOT}/cw_monero/External/ios/include", - "${PODS_ROOT}/cw_shared_external/External/ios/include/**", "$(PROJECT_DIR)/../crypto_plugins/flutter_libepiccash/ios/include", ); INFOPLIST_FILE = Runner/Info.plist; @@ -729,7 +719,6 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", - "$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios/**", "$(PROJECT_DIR)/../crypto_plugins/flutter_libepiccash/ios/libs", ); MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; @@ -765,7 +754,6 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/../crypto_plugins/flutter_liblelantus/scripts/ios/mobileliblelantus/**", - "$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios", "$(PROJECT_DIR)", ); HEADER_SEARCH_PATHS = ( @@ -777,8 +765,6 @@ "\"${PODS_CONFIGURATION_BUILD_DIR}/barcode_scan2/barcode_scan2.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/connectivity/connectivity.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/cryptography_flutter/cryptography_flutter.framework/Headers\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_monero/cw_monero.framework/Headers\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/cw_shared_external/cw_shared_external.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/devicelocale/devicelocale.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_libepiccash/flutter_libepiccash.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_libmonero/flutter_libmonero.framework/Headers\"", @@ -796,12 +782,6 @@ "\"${PODS_CONFIGURATION_BUILD_DIR}/stack_wallet_backup/stack_wallet_backup.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/url_launcher_ios/url_launcher_ios.framework/Headers\"", "\"${PODS_CONFIGURATION_BUILD_DIR}/wakelock/wakelock.framework/Headers\"", - "${PODS_ROOT}/cw_monero/Classes/*.h", - "${PODS_ROOT}/cw_monero/Classes/*.h", - "${PODS_ROOT}/cw_monero/External/ios/include/**", - "${PODS_ROOT}/cw_monero/Classes/*.h", - "${PODS_ROOT}/cw_monero/External/ios/include", - "${PODS_ROOT}/cw_shared_external/External/ios/include/**", "$(PROJECT_DIR)/../crypto_plugins/flutter_libepiccash/ios/include", ); INFOPLIST_FILE = Runner/Info.plist; @@ -813,7 +793,6 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", - "$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios/**", "$(PROJECT_DIR)/../crypto_plugins/flutter_libepiccash/ios/libs", ); MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"; diff --git a/scripts/app_config/templates/linux/CMakeLists.txt b/scripts/app_config/templates/linux/CMakeLists.txt index a13bec888..25750ef4f 100644 --- a/scripts/app_config/templates/linux/CMakeLists.txt +++ b/scripts/app_config/templates/linux/CMakeLists.txt @@ -134,12 +134,6 @@ install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR} install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/monero/x86_64-linux-gnu_libwallet2_api_c.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "monero_libwallet2_api_c.so" - COMPONENT Runtime) - -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-linux-gnu_libwallet2_api_c.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "wownero_libwallet2_api_c.so" - COMPONENT Runtime) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libepiccash/scripts/linux/build/rust/target/x86_64-unknown-linux-gnu/release/libepic_cash_wallet.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) diff --git a/scripts/app_config/templates/macos/Runner.xcodeproj/project.pbxproj b/scripts/app_config/templates/macos/Runner.xcodeproj/project.pbxproj index 7049193bb..b0e43be79 100644 --- a/scripts/app_config/templates/macos/Runner.xcodeproj/project.pbxproj +++ b/scripts/app_config/templates/macos/Runner.xcodeproj/project.pbxproj @@ -31,8 +31,6 @@ 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 */; }; - CEA2021D2BDD4D7100FE1D27 /* wownero_libwallet2_api_c.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = CEA2021C2BDD4D7100FE1D27 /* wownero_libwallet2_api_c.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - CEA202202BDD4F0B00FE1D27 /* monero_libwallet2_api_c.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = CEA2021F2BDD4F0B00FE1D27 /* monero_libwallet2_api_c.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; F1FA2C4E2BA4B49F00BDA1BB /* frostdart.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F1FA2C4D2BA4B49F00BDA1BB /* frostdart.dylib */; settings = {ATTRIBUTES = (Weak, ); }; }; F1FA2C502BA4B4CA00BDA1BB /* frostdart.dylib in Resources */ = {isa = PBXBuildFile; fileRef = F1FA2C4F2BA4B4CA00BDA1BB /* frostdart.dylib */; }; F1FA2C512BA4B51E00BDA1BB /* frostdart.dylib in Bundle Framework */ = {isa = PBXBuildFile; fileRef = F1FA2C4D2BA4B49F00BDA1BB /* frostdart.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; @@ -69,17 +67,6 @@ name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; }; - CEA202192BDD4C3500FE1D27 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 12; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - CEA202202BDD4F0B00FE1D27 /* monero_libwallet2_api_c.dylib in CopyFiles */, - CEA2021D2BDD4D7100FE1D27 /* wownero_libwallet2_api_c.dylib in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -276,7 +263,6 @@ 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, 529691D83C3BADE14E2EAC03 /* [CP] Embed Pods Frameworks */, - CEA202192BDD4C3500FE1D27 /* CopyFiles */, ); buildRules = ( ); diff --git a/scripts/app_config/templates/pubspec.template b/scripts/app_config/templates/pubspec.template index d9acb3782..09f01701d 100644 --- a/scripts/app_config/templates/pubspec.template +++ b/scripts/app_config/templates/pubspec.template @@ -14,15 +14,15 @@ description: PLACEHOLDER version: PLACEHOLDER_V+PLACEHOLDER_B environment: - sdk: ">=3.5.2 <4.0.0" - flutter: ^3.24.2 + sdk: ">=3.5.3 <4.0.0" + flutter: ^3.24.3 dependencies: flutter: sdk: flutter ffi: ^2.0.1 mutex: ^3.0.0 - web_socket_channel: ^2.4.5 + web_socket_channel: ^2.4.0 lelantus: path: ./crypto_plugins/flutter_liblelantus @@ -33,24 +33,14 @@ dependencies: flutter_libsparkmobile: git: url: https://github.com/cypherstack/flutter_libsparkmobile.git - ref: d88de9506fda95a3114134817d172a841d93947e + ref: cc7b43b731e4a7906dd25d4364a08e34554cee19 - flutter_libmonero: - path: ./crypto_plugins/flutter_libmonero - - cw_monero: - path: ./crypto_plugins/flutter_libmonero/cw_monero - - cw_wownero: - path: ./crypto_plugins/flutter_libmonero/cw_wownero - - cw_core: - path: ./crypto_plugins/flutter_libmonero/cw_core - - monero: + # cs_monero compat (unpublished) + compat: git: - url: https://github.com/mrcyjanek/monero.dart - ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5 + url: https://github.com/cypherstack/cs_monero + path: compat + ref: b2b12cfeaf15d057ea18b14c196e04f3002de2da flutter_libepiccash: path: ./crypto_plugins/flutter_libepiccash @@ -63,7 +53,7 @@ dependencies: stack_wallet_backup: git: url: https://github.com/cypherstack/stack_wallet_backup.git - ref: ee1da8a9ba1cbeb50c5b354ea1fd5a25b7c5a3ed + ref: 5efe8f8f259317d32b6f037cf91f62e06125c040 bip47: git: @@ -78,11 +68,11 @@ dependencies: fusiondart: git: url: https://github.com/cypherstack/fusiondart.git - ref: 7dd8ff0dc9cb0caaac795fa44841a26437edfec3 + ref: 9dc883f4432c8db4ec44cb8cc836963295d63952 # Utility plugins http: ^0.13.0 - local_auth: ^1.1.10 + local_auth: ^2.3.0 permission_handler: ^11.0.0 flutter_local_notifications: ^17.2.2 rxdart: ^0.27.3 @@ -130,10 +120,10 @@ dependencies: event_bus: ^2.0.0 uuid: ^3.0.5 crypto: ^3.0.2 - barcode_scan2: ^4.2.3 - wakelock: ^0.6.2 + barcode_scan2: ^4.3.3 + wakelock_plus: ^1.2.8 intl: ^0.17.0 - devicelocale: ^0.6.0 + devicelocale: ^0.7.1 device_info_plus: ^10.1.2 keyboard_dismisser: ^3.0.0 another_flushbar: ^1.10.28 @@ -143,12 +133,16 @@ dependencies: share_plus: ^7.0.2 emojis: ^0.9.9 pointycastle: ^3.6.0 - package_info_plus: ^4.0.2 + package_info_plus: ^8.0.2 lottie: ^2.3.2 file_picker: ^8.0.3 connectivity_plus: ^4.0.1 - isar: 3.0.5 - isar_flutter_libs: 3.0.5 # contains the binaries + isar: + version: 3.1.8 + hosted: https://pub.isar-community.dev/ + isar_flutter_libs: # contains Isar Core + version: 3.1.8 + hosted: https://pub.isar-community.dev/ dropdown_button2: ^2.1.3 string_validator: ^0.3.0 equatable: ^2.0.5 @@ -157,7 +151,7 @@ dependencies: dart_bs58check: ^3.0.2 hex: ^0.2.0 archive: ^3.6.1 - desktop_drop: ^0.4.1 + desktop_drop: ^0.4.4 nanodart: ^2.0.0 basic_utils: ^5.5.4 stellar_flutter_sdk: ^1.7.8 @@ -167,15 +161,15 @@ dependencies: git: url: https://github.com/cypherstack/tezart.git ref: d000cc245e51d3ff50e6467960fb3d9159d5b2a9 - socks5_proxy: ^1.0.3+dev.3 + socks5_proxy: 1.0.3+dev.3 convert: ^3.1.1 flutter_hooks: ^0.20.3 meta: ^1.9.1 # coinlib_flutter: ^2.1.0-rc.1 coinlib_flutter: git: - url: https://github.com/peercoin/coinlib.git - ref: b88e68e2e10ffe54d802deeed6b9e83da7721a1f + url: https://github.com/julian-CStack/coinlib.git + ref: 0acacfd17eacf72135c693a7b862bd9b7cc56739 path: coinlib_flutter electrum_adapter: git: @@ -185,11 +179,11 @@ dependencies: solana: git: # TODO [prio=low]: Revert to official package once Tor support is merged upstream. url: https://github.com/cypherstack/espresso-cash-public.git - ref: 706be5f166d31736c443cca4cd311b7fcfc2a9bf + ref: dea799c20bc917f72b18c916ca96bc99fb1bd1c5 path: packages/solana calendar_date_picker2: ^1.0.2 - sqlite3: ^2.4.3 - sqlite3_flutter_libs: ^0.5.22 + sqlite3: 2.4.3 + sqlite3_flutter_libs: 0.5.22 camera_linux: ^0.0.8 zxing2: ^0.2.3 camera_windows: @@ -198,6 +192,11 @@ dependencies: path: packages/camera/camera_windows camera_platform_interface: ^2.8.0 camera_macos: ^0.0.8 + blockchain_utils: ^3.3.0 + on_chain: ^4.0.1 + cbor: ^6.3.3 + cs_monero: 1.0.0-pre + cs_monero_flutter_libs: 1.0.0-pre.0 dev_dependencies: flutter_test: @@ -212,10 +211,12 @@ dev_dependencies: mockito: ^5.4.1 mockingjay: ^0.2.0 # lint: ^1.10.0 - analyzer: ^5.13.0 + analyzer: ^6.7.0 import_sorter: ^4.6.0 flutter_lints: ^3.0.1 - isar_generator: 3.0.5 + isar_generator: + version: 3.1.8 + hosted: https://pub.isar-community.dev/ flutter_native_splash: image: assets/icon/splash.png @@ -230,26 +231,21 @@ dependency_overrides: # coin lib git for testing while waiting for publishing coinlib: git: - url: https://github.com/peercoin/coinlib.git - ref: b88e68e2e10ffe54d802deeed6b9e83da7721a1f + url: https://github.com/julian-CStack/coinlib.git + ref: 0acacfd17eacf72135c693a7b862bd9b7cc56739 path: coinlib coinlib_flutter: git: - url: https://github.com/peercoin/coinlib.git - ref: b88e68e2e10ffe54d802deeed6b9e83da7721a1f + url: https://github.com/julian-CStack/coinlib.git + ref: 0acacfd17eacf72135c693a7b862bd9b7cc56739 path: coinlib_flutter # adding here due to pure laziness tor_ffi_plugin: git: url: https://github.com/cypherstack/tor.git - ref: 647cadc3c82c276dc07915b02d24538fd610f220 - - monero: - git: - url: https://github.com/mrcyjanek/monero.dart - ref: d46753eca865e9e56c2f0ef6fe485c42e11982c5 + ref: 534ec251b339199446b723c01a25d324ae7bb974 bip47: git: @@ -263,12 +259,6 @@ dependency_overrides: ref: 2a9bca63a540771f241d688562351482b2cf234c path: wakelock_windows - # required for libmonero - can remove once libmonero has been updated, PR has been merged in swb - stack_wallet_backup: - git: - url: https://github.com/cypherstack/stack_wallet_backup.git - ref: ee1da8a9ba1cbeb50c5b354ea1fd5a25b7c5a3ed - # required override for nanodart bip39: git: @@ -282,7 +272,7 @@ dependency_overrides: ref: 9abc0930081c9859884e073bd25ab88b2114d9e7 crypto: 3.0.2 - analyzer: ^5.2.0 + analyzer: ^6.7.0 pinenacl: ^0.6.0 http: ^0.13.0 @@ -333,30 +323,6 @@ flutter: # default themes_testing - assets/default_themes/ - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages - import_sorter: comments: false # Optional, defaults to true ignored_files: # Optional, defaults to [] diff --git a/scripts/app_config/templates/windows/CMakeLists.txt b/scripts/app_config/templates/windows/CMakeLists.txt index 795e592f2..b9add856d 100644 --- a/scripts/app_config/templates/windows/CMakeLists.txt +++ b/scripts/app_config/templates/windows/CMakeLists.txt @@ -86,27 +86,6 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libepiccash install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_liblelantus/scripts/windows/build/libmobileliblelantus.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/monero/x86_64-w64-mingw32_libwallet2_api_c.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "monero_libwallet2_api_c.dll" - COMPONENT Runtime) - -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libwallet2_api_c.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "wownero_libwallet2_api_c.dll" - COMPONENT Runtime) - -#install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libgcc_s_seh-1.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libgcc_s_seh-1.dll" -# COMPONENT Runtime) - -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libpolyseed.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libpolyseed.dll" - COMPONENT Runtime) - -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libssp-0.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libssp-0.dll" - COMPONENT Runtime) - -#install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libstdc++-6.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libstdc++-6.dll" -# COMPONENT Runtime) - -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../crypto_plugins/flutter_libmonero/scripts/monero_c/release/wownero/x86_64-w64-mingw32_libwinpthread-1.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" RENAME "libwinpthread-1.dll" - COMPONENT Runtime) - if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" diff --git a/scripts/ios/build_all.sh b/scripts/ios/build_all.sh index b34724561..bcb03e991 100755 --- a/scripts/ios/build_all.sh +++ b/scripts/ios/build_all.sh @@ -16,7 +16,6 @@ rustup target add x86_64-apple-ios (cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh ) -(cd ../../crypto_plugins/flutter_libmonero/scripts/ios/ && ./build_all.sh ) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh ) diff --git a/scripts/ios/build_all_campfire.sh b/scripts/ios/build_all_campfire.sh index b34724561..bcb03e991 100755 --- a/scripts/ios/build_all_campfire.sh +++ b/scripts/ios/build_all_campfire.sh @@ -16,7 +16,6 @@ rustup target add x86_64-apple-ios (cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh ) -(cd ../../crypto_plugins/flutter_libmonero/scripts/ios/ && ./build_all.sh ) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh ) diff --git a/scripts/ios/build_all_duo.sh b/scripts/ios/build_all_duo.sh index 387f85f81..89e6f4641 100755 --- a/scripts/ios/build_all_duo.sh +++ b/scripts/ios/build_all_duo.sh @@ -18,7 +18,6 @@ rustup target add x86_64-apple-ios (cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh ) -(cd ../../crypto_plugins/flutter_libmonero/scripts/ios/ && ./build_all.sh ) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh ) diff --git a/scripts/linux/build_all.sh b/scripts/linux/build_all.sh index c9542798e..423646185 100755 --- a/scripts/linux/build_all.sh +++ b/scripts/linux/build_all.sh @@ -14,7 +14,6 @@ mkdir -p build ./build_secure_storage_deps.sh (cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh ) -(cd ../../crypto_plugins/flutter_libmonero/scripts/linux && ./build_all.sh ) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh ) diff --git a/scripts/linux/build_all_campfire.sh b/scripts/linux/build_all_campfire.sh index c9542798e..423646185 100755 --- a/scripts/linux/build_all_campfire.sh +++ b/scripts/linux/build_all_campfire.sh @@ -14,7 +14,6 @@ mkdir -p build ./build_secure_storage_deps.sh (cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh ) -(cd ../../crypto_plugins/flutter_libmonero/scripts/linux && ./build_all.sh ) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh ) diff --git a/scripts/linux/build_all_duo.sh b/scripts/linux/build_all_duo.sh index e7397bdc5..78067b478 100755 --- a/scripts/linux/build_all_duo.sh +++ b/scripts/linux/build_all_duo.sh @@ -16,7 +16,6 @@ mkdir -p build ./build_secure_storage_deps.sh & (cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh ) -(cd ../../crypto_plugins/flutter_libmonero/scripts/linux && ./build_all.sh ) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh ) diff --git a/scripts/linux/build_secp256k1.sh b/scripts/linux/build_secp256k1.sh index e333b723c..f00b6b82b 100755 --- a/scripts/linux/build_secp256k1.sh +++ b/scripts/linux/build_secp256k1.sh @@ -1,10 +1,14 @@ mkdir -p build cd build -git clone https://github.com/bitcoin-core/secp256k1 +if [ ! -d "secp256k1" ]; then + git clone https://github.com/bitcoin-core/secp256k1 +fi cd secp256k1 +git checkout 68b55209f1ba3e6c0417789598f5f75649e9c14c +git reset --hard mkdir -p build && cd build cmake .. cmake --build . mkdir -p ../../../../../build -cp src/libsecp256k1.so.2.*.* "../../../../../build/libsecp256k1.so" +cp lib/libsecp256k1.so.2.2.2 "../../../../../build/libsecp256k1.so" cd ../../../ diff --git a/scripts/macos/build_all.sh b/scripts/macos/build_all.sh index e3a58b45f..af608846f 100755 --- a/scripts/macos/build_all.sh +++ b/scripts/macos/build_all.sh @@ -8,7 +8,6 @@ set_rust_to_1671 (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 ) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh ) diff --git a/scripts/macos/build_all_campfire.sh b/scripts/macos/build_all_campfire.sh index e3a58b45f..af608846f 100755 --- a/scripts/macos/build_all_campfire.sh +++ b/scripts/macos/build_all_campfire.sh @@ -8,7 +8,6 @@ set_rust_to_1671 (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 ) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh ) diff --git a/scripts/macos/build_all_duo.sh b/scripts/macos/build_all_duo.sh index 6f70f4371..8a53e5801 100755 --- a/scripts/macos/build_all_duo.sh +++ b/scripts/macos/build_all_duo.sh @@ -10,7 +10,6 @@ set_rust_to_1671 (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 ) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh ) diff --git a/scripts/windows/build_all.sh b/scripts/windows/build_all.sh index fc6ac37b1..191a46cc0 100755 --- a/scripts/windows/build_all.sh +++ b/scripts/windows/build_all.sh @@ -9,7 +9,6 @@ set_rust_to_1671 mkdir -p build (cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh ) (cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh ) -(cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh ) diff --git a/scripts/windows/build_all_campfire.sh b/scripts/windows/build_all_campfire.sh index fc6ac37b1..191a46cc0 100755 --- a/scripts/windows/build_all_campfire.sh +++ b/scripts/windows/build_all_campfire.sh @@ -9,7 +9,6 @@ set_rust_to_1671 mkdir -p build (cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh ) (cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh ) -(cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh ) diff --git a/scripts/windows/build_all_duo.sh b/scripts/windows/build_all_duo.sh index 80303f28b..3e27eff02 100755 --- a/scripts/windows/build_all_duo.sh +++ b/scripts/windows/build_all_duo.sh @@ -11,7 +11,6 @@ set_rust_to_1671 mkdir -p build (cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh ) (cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh ) -(cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh) set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh ) diff --git a/scripts/windows/build_secp256k1.bat b/scripts/windows/build_secp256k1.bat index 9e7433032..f5777b974 100644 --- a/scripts/windows/build_secp256k1.bat +++ b/scripts/windows/build_secp256k1.bat @@ -1,10 +1,12 @@ if not exist "build" mkdir "build" cd build -rem git clone https://github.com/bitcoin-core/secp256k1 +git clone https://github.com/bitcoin-core/secp256k1 cd secp256k1 -rem cmake -G "Visual Studio 17 2022" -A x64 -S . -B build +git checkout 68b55209f1ba3e6c0417789598f5f75649e9c14c +git reset --hard +cmake -G "Visual Studio 17 2022" -A x64 -S . -B build cd build -rem cmake --build . +cmake --build . if not exist "..\..\..\..\build\" mkdir "..\..\..\..\build\" -xcopy src\Debug\libsecp256k1-2.dll "..\..\..\..\build\secp256k1.dll" /Y +xcopy bin\Debug\libsecp256k1-2.dll "..\..\..\..\build\secp256k1.dll" /Y cd ..\..\..\ diff --git a/scripts/windows/build_secp256k1_wsl.sh b/scripts/windows/build_secp256k1_wsl.sh index b5d2e281f..a39cd3bee 100644 --- a/scripts/windows/build_secp256k1_wsl.sh +++ b/scripts/windows/build_secp256k1_wsl.sh @@ -1,10 +1,14 @@ mkdir -p build cd build -git clone https://github.com/bitcoin-core/secp256k1 +if [ ! -d "secp256k1" ]; then + git clone https://github.com/bitcoin-core/secp256k1 +fi cd secp256k1 +git checkout 68b55209f1ba3e6c0417789598f5f75649e9c14c +git reset --hard mkdir -p build && cd build cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-w64-mingw32.toolchain.cmake cmake --build . mkdir -p ../../../../../build -cp src/libsecp256k1-2.dll "../../../../../build/secp256k1.dll" +cp bin/libsecp256k1-2.dll "../../../../../build/secp256k1.dll" cd ../../../ diff --git a/test/address_utils_test.dart b/test/address_utils_test.dart index 560962256..599380c31 100644 --- a/test/address_utils_test.dart +++ b/test/address_utils_test.dart @@ -12,52 +12,49 @@ void main() { test("parse a valid uri string A", () { const uri = "dogecoin:$firoAddress?amount=50&label=eggs"; - final result = AddressUtils.parseUri(uri); - expect(result, { - "scheme": "dogecoin", - "address": firoAddress, - "amount": "50", - "label": "eggs", - }); + final result = AddressUtils.parsePaymentUri(uri); + expect(result, isNotNull); + expect(result!.scheme, "dogecoin"); + expect(result.address, firoAddress); + expect(result.amount, "50"); + expect(result.label, "eggs"); }); test("parse a valid uri string B", () { const uri = "firo:$firoAddress?amount=50&message=eggs+are+good"; - final result = AddressUtils.parseUri(uri); - expect(result, { - "scheme": "firo", - "address": firoAddress, - "amount": "50", - "message": "eggs are good", - }); + final result = AddressUtils.parsePaymentUri(uri); + expect(result, isNotNull); + expect(result!.scheme, "firo"); + expect(result.address, firoAddress); + expect(result.amount, "50"); + expect(result.message, "eggs are good"); }); test("parse a valid uri string C", () { const uri = "bitcoin:$firoAddress?amount=50.1&message=eggs%20are%20good%21"; - final result = AddressUtils.parseUri(uri); - expect(result, { - "scheme": "bitcoin", - "address": firoAddress, - "amount": "50.1", - "message": "eggs are good!", - }); + final result = AddressUtils.parsePaymentUri(uri); + expect(result, isNotNull); + expect(result!.scheme, "bitcoin"); + expect(result.address, firoAddress); + expect(result.amount, "50.1"); + expect(result.message, "eggs are good!"); }); test("parse an invalid uri string", () { const uri = "firo$firoAddress?amount=50&label=eggs"; - final result = AddressUtils.parseUri(uri); - expect(result, {}); + final result = AddressUtils.parsePaymentUri(uri); + expect(result, isNull); }); test("parse an invalid string", () { const uri = "$firoAddress?amount=50&label=eggs"; - final result = AddressUtils.parseUri(uri); - expect(result, {}); + final result = AddressUtils.parsePaymentUri(uri); + expect(result, isNull); }); test("parse an invalid uri string", () { const uri = "::: 8 \\ %23"; - expect(AddressUtils.parseUri(uri), {}); + expect(AddressUtils.parsePaymentUri(uri), isNull); }); test("encode a list of (mnemonic) words/strings as a json object", () { @@ -95,7 +92,7 @@ void main() { test("build a uri string with empty params", () { expect( AddressUtils.buildUriString( - Firo(CryptoCurrencyNetwork.main), firoAddress, {}), + Firo(CryptoCurrencyNetwork.main).uriScheme, firoAddress, {}), "firo:$firoAddress", ); }); @@ -103,7 +100,7 @@ void main() { test("build a uri string with one param", () { expect( AddressUtils.buildUriString( - Firo(CryptoCurrencyNetwork.main), + Firo(CryptoCurrencyNetwork.main).uriScheme, firoAddress, {"amount": "10.0123"}, ), @@ -114,7 +111,7 @@ void main() { test("build a uri string with some params", () { expect( AddressUtils.buildUriString( - Firo(CryptoCurrencyNetwork.main), + Firo(CryptoCurrencyNetwork.main).uriScheme, firoAddress, {"amount": "10.0123", "message": "Some kind of message!"}, ), diff --git a/test/cached_electrumx_test.mocks.dart b/test/cached_electrumx_test.mocks.dart index db289eae0..993f73f69 100644 --- a/test/cached_electrumx_test.mocks.dart +++ b/test/cached_electrumx_test.mocks.dart @@ -89,6 +89,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { Invocation.getter(#cryptoCurrency), ), ) as _i2.CryptoCurrency); + @override set failovers(List<_i5.ElectrumXNode>? _failovers) => super.noSuchMethod( Invocation.setter( @@ -97,11 +98,13 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override int get currentFailoverIndex => (super.noSuchMethod( Invocation.getter(#currentFailoverIndex), returnValue: 0, ) as int); + @override set currentFailoverIndex(int? _currentFailoverIndex) => super.noSuchMethod( Invocation.setter( @@ -110,6 +113,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override Duration get connectionTimeoutForSpecialCaseJsonRPCClients => (super.noSuchMethod( @@ -119,6 +123,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { Invocation.getter(#connectionTimeoutForSpecialCaseJsonRPCClients), ), ) as Duration); + @override String get host => (super.noSuchMethod( Invocation.getter(#host), @@ -127,16 +132,19 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { Invocation.getter(#host), ), ) as String); + @override int get port => (super.noSuchMethod( Invocation.getter(#port), returnValue: 0, ) as int); + @override bool get useSSL => (super.noSuchMethod( Invocation.getter(#useSSL), returnValue: false, ) as bool); + @override _i7.Future closeAdapter() => (super.noSuchMethod( Invocation.method( @@ -146,6 +154,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), ) as _i7.Future); + @override _i7.Future checkElectrumAdapter() => (super.noSuchMethod( Invocation.method( @@ -155,6 +164,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), ) as _i7.Future); + @override _i7.Future request({ required String? command, @@ -177,6 +187,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValue: _i7.Future.value(), ) as _i7.Future); + @override _i7.Future> batchRequest({ required String? command, @@ -197,6 +208,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValue: _i7.Future>.value([]), ) as _i7.Future>); + @override _i7.Future ping({ String? requestID, @@ -213,6 +225,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValue: _i7.Future.value(false), ) as _i7.Future); + @override _i7.Future> getBlockHeadTip({String? requestID}) => (super.noSuchMethod( @@ -224,6 +237,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>.value({}), ) as _i7.Future>); + @override _i7.Future> getServerFeatures({String? requestID}) => (super.noSuchMethod( @@ -235,6 +249,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>.value({}), ) as _i7.Future>); + @override _i7.Future broadcastTransaction({ required String? rawTx, @@ -261,6 +276,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), )), ) as _i7.Future); + @override _i7.Future> getBalance({ required String? scripthash, @@ -278,6 +294,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>.value({}), ) as _i7.Future>); + @override _i7.Future>> getHistory({ required String? scripthash, @@ -295,6 +312,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>>.value( >[]), ) as _i7.Future>>); + @override _i7.Future>>> getBatchHistory( {required List? args}) => @@ -307,6 +325,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>>>.value( >>[]), ) as _i7.Future>>>); + @override _i7.Future>> getUTXOs({ required String? scripthash, @@ -324,6 +343,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>>.value( >[]), ) as _i7.Future>>); + @override _i7.Future>>> getBatchUTXOs( {required List? args}) => @@ -336,6 +356,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>>>.value( >>[]), ) as _i7.Future>>>); + @override _i7.Future> getTransaction({ required String? txHash, @@ -355,6 +376,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>.value({}), ) as _i7.Future>); + @override _i7.Future> getLelantusAnonymitySet({ String? groupId = r'1', @@ -374,6 +396,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>.value({}), ) as _i7.Future>); + @override _i7.Future getLelantusMintData({ dynamic mints, @@ -390,6 +413,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValue: _i7.Future.value(), ) as _i7.Future); + @override _i7.Future> getLelantusUsedCoinSerials({ String? requestID, @@ -407,6 +431,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>.value({}), ) as _i7.Future>); + @override _i7.Future getLelantusLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -417,6 +442,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValue: _i7.Future.value(0), ) as _i7.Future); + @override _i7.Future> getSparkAnonymitySet({ String? coinGroupId = r'1', @@ -436,6 +462,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>.value({}), ) as _i7.Future>); + @override _i7.Future>> getSparkMintMetaData({ String? requestID, @@ -453,6 +480,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>>.value( >[]), ) as _i7.Future>>); + @override _i7.Future getSparkLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -463,6 +491,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValue: _i7.Future.value(0), ) as _i7.Future); + @override _i7.Future> getMempoolTxids({String? requestID}) => (super.noSuchMethod( @@ -473,6 +502,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValue: _i7.Future>.value({}), ) as _i7.Future>); + @override _i7.Future< List< @@ -515,6 +545,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { List serialContext, String txid })>>); + @override _i7.Future>> getSparkUnhashedUsedCoinsTagsWithTxHashes({ String? requestID, @@ -531,6 +562,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValue: _i7.Future>>.value(>[]), ) as _i7.Future>>); + @override _i7.Future isMasterNodeCollateral({ String? requestID, @@ -549,6 +581,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), returnValue: _i7.Future.value(false), ) as _i7.Future); + @override _i7.Future> getFeeRate({String? requestID}) => (super.noSuchMethod( @@ -560,6 +593,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { returnValue: _i7.Future>.value({}), ) as _i7.Future>); + @override _i7.Future<_i3.Decimal> estimateFee({ String? requestID, @@ -586,6 +620,7 @@ class MockElectrumXClient extends _i1.Mock implements _i5.ElectrumXClient { ), )), ) as _i7.Future<_i3.Decimal>); + @override _i7.Future<_i3.Decimal> relayFee({String? requestID}) => (super.noSuchMethod( Invocation.method( @@ -617,11 +652,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { Invocation.getter(#isInitialized), returnValue: false, ) as bool); + @override int get lastUnlockedTimeout => (super.noSuchMethod( Invocation.getter(#lastUnlockedTimeout), returnValue: 0, ) as int); + @override set lastUnlockedTimeout(int? lastUnlockedTimeout) => super.noSuchMethod( Invocation.setter( @@ -630,11 +667,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override int get lastUnlocked => (super.noSuchMethod( Invocation.getter(#lastUnlocked), returnValue: 0, ) as int); + @override set lastUnlocked(int? lastUnlocked) => super.noSuchMethod( Invocation.setter( @@ -643,16 +682,19 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override int get currentNotificationId => (super.noSuchMethod( Invocation.getter(#currentNotificationId), returnValue: 0, ) as int); + @override List get walletIdsSyncOnStartup => (super.noSuchMethod( Invocation.getter(#walletIdsSyncOnStartup), returnValue: [], ) as List); + @override set walletIdsSyncOnStartup(List? walletIdsSyncOnStartup) => super.noSuchMethod( @@ -662,11 +704,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override _i9.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), returnValue: _i9.SyncingType.currentWalletOnly, ) as _i9.SyncingType); + @override set syncType(_i9.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( @@ -675,11 +719,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get wifiOnly => (super.noSuchMethod( Invocation.getter(#wifiOnly), returnValue: false, ) as bool); + @override set wifiOnly(bool? wifiOnly) => super.noSuchMethod( Invocation.setter( @@ -688,11 +734,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showFavoriteWallets => (super.noSuchMethod( Invocation.getter(#showFavoriteWallets), returnValue: false, ) as bool); + @override set showFavoriteWallets(bool? showFavoriteWallets) => super.noSuchMethod( Invocation.setter( @@ -701,6 +749,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override String get language => (super.noSuchMethod( Invocation.getter(#language), @@ -709,6 +758,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { Invocation.getter(#language), ), ) as String); + @override set language(String? newLanguage) => super.noSuchMethod( Invocation.setter( @@ -717,6 +767,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override String get currency => (super.noSuchMethod( Invocation.getter(#currency), @@ -725,6 +776,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { Invocation.getter(#currency), ), ) as String); + @override set currency(String? newCurrency) => super.noSuchMethod( Invocation.setter( @@ -733,11 +785,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get randomizePIN => (super.noSuchMethod( Invocation.getter(#randomizePIN), returnValue: false, ) as bool); + @override set randomizePIN(bool? randomizePIN) => super.noSuchMethod( Invocation.setter( @@ -746,11 +800,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useBiometrics => (super.noSuchMethod( Invocation.getter(#useBiometrics), returnValue: false, ) as bool); + @override set useBiometrics(bool? useBiometrics) => super.noSuchMethod( Invocation.setter( @@ -759,11 +815,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hasPin => (super.noSuchMethod( Invocation.getter(#hasPin), returnValue: false, ) as bool); + @override set hasPin(bool? hasPin) => super.noSuchMethod( Invocation.setter( @@ -772,11 +830,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override int get familiarity => (super.noSuchMethod( Invocation.getter(#familiarity), returnValue: 0, ) as int); + @override set familiarity(int? familiarity) => super.noSuchMethod( Invocation.setter( @@ -785,11 +845,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get torKillSwitch => (super.noSuchMethod( Invocation.getter(#torKillSwitch), returnValue: false, ) as bool); + @override set torKillSwitch(bool? torKillswitch) => super.noSuchMethod( Invocation.setter( @@ -798,11 +860,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showTestNetCoins => (super.noSuchMethod( Invocation.getter(#showTestNetCoins), returnValue: false, ) as bool); + @override set showTestNetCoins(bool? showTestNetCoins) => super.noSuchMethod( Invocation.setter( @@ -811,11 +875,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get isAutoBackupEnabled => (super.noSuchMethod( Invocation.getter(#isAutoBackupEnabled), returnValue: false, ) as bool); + @override set isAutoBackupEnabled(bool? isAutoBackupEnabled) => super.noSuchMethod( Invocation.setter( @@ -824,6 +890,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override set autoBackupLocation(String? autoBackupLocation) => super.noSuchMethod( Invocation.setter( @@ -832,11 +899,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override _i10.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), returnValue: _i10.BackupFrequencyType.everyTenMinutes, ) as _i10.BackupFrequencyType); + @override set backupFrequencyType(_i10.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( @@ -846,6 +915,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override set lastAutoBackup(DateTime? lastAutoBackup) => super.noSuchMethod( Invocation.setter( @@ -854,11 +924,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hideBlockExplorerWarning => (super.noSuchMethod( Invocation.getter(#hideBlockExplorerWarning), returnValue: false, ) as bool); + @override set hideBlockExplorerWarning(bool? hideBlockExplorerWarning) => super.noSuchMethod( @@ -868,11 +940,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get gotoWalletOnStartup => (super.noSuchMethod( Invocation.getter(#gotoWalletOnStartup), returnValue: false, ) as bool); + @override set gotoWalletOnStartup(bool? gotoWalletOnStartup) => super.noSuchMethod( Invocation.setter( @@ -881,6 +955,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override set startupWalletId(String? startupWalletId) => super.noSuchMethod( Invocation.setter( @@ -889,11 +964,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get externalCalls => (super.noSuchMethod( Invocation.getter(#externalCalls), returnValue: false, ) as bool); + @override set externalCalls(bool? externalCalls) => super.noSuchMethod( Invocation.setter( @@ -902,11 +979,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableCoinControl => (super.noSuchMethod( Invocation.getter(#enableCoinControl), returnValue: false, ) as bool); + @override set enableCoinControl(bool? enableCoinControl) => super.noSuchMethod( Invocation.setter( @@ -915,11 +994,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableSystemBrightness => (super.noSuchMethod( Invocation.getter(#enableSystemBrightness), returnValue: false, ) as bool); + @override set enableSystemBrightness(bool? enableSystemBrightness) => super.noSuchMethod( @@ -929,6 +1010,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override String get themeId => (super.noSuchMethod( Invocation.getter(#themeId), @@ -937,6 +1019,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { Invocation.getter(#themeId), ), ) as String); + @override set themeId(String? themeId) => super.noSuchMethod( Invocation.setter( @@ -945,6 +1028,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessLightThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessLightThemeId), @@ -953,6 +1037,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { Invocation.getter(#systemBrightnessLightThemeId), ), ) as String); + @override set systemBrightnessLightThemeId(String? systemBrightnessLightThemeId) => super.noSuchMethod( @@ -962,6 +1047,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessDarkThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessDarkThemeId), @@ -970,6 +1056,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { Invocation.getter(#systemBrightnessDarkThemeId), ), ) as String); + @override set systemBrightnessDarkThemeId(String? systemBrightnessDarkThemeId) => super.noSuchMethod( @@ -979,11 +1066,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useTor => (super.noSuchMethod( Invocation.getter(#useTor), returnValue: false, ) as bool); + @override set useTor(bool? useTor) => super.noSuchMethod( Invocation.setter( @@ -992,11 +1081,13 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override bool get autoPin => (super.noSuchMethod( Invocation.getter(#autoPin), returnValue: false, ) as bool); + @override set autoPin(bool? autoPin) => super.noSuchMethod( Invocation.setter( @@ -1005,11 +1096,28 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + + @override + bool get enableExchange => (super.noSuchMethod( + Invocation.getter(#enableExchange), + returnValue: false, + ) as bool); + + @override + set enableExchange(bool? showExchange) => super.noSuchMethod( + Invocation.setter( + #enableExchange, + showExchange, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i7.Future init() => (super.noSuchMethod( Invocation.method( @@ -1019,6 +1127,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), ) as _i7.Future); + @override _i7.Future incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( @@ -1028,6 +1137,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), ) as _i7.Future); + @override _i7.Future isExternalCallsSet() => (super.noSuchMethod( Invocation.method( @@ -1036,6 +1146,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValue: _i7.Future.value(false), ) as _i7.Future); + @override _i7.Future saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( @@ -1045,6 +1156,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), ) as _i7.Future); + @override _i7.Future saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( @@ -1054,6 +1166,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { returnValue: _i7.Future.value(), returnValueForMissingStub: _i7.Future.value(), ) as _i7.Future); + @override _i11.AmountUnit amountUnit(_i2.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -1062,6 +1175,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValue: _i11.AmountUnit.normal, ) as _i11.AmountUnit); + @override void updateAmountUnit({ required _i2.CryptoCurrency? coin, @@ -1078,6 +1192,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override int maxDecimals(_i2.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -1086,6 +1201,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValue: 0, ) as int); + @override void updateMaxDecimals({ required _i2.CryptoCurrency? coin, @@ -1102,6 +1218,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override _i4.FusionInfo getFusionServerInfo(_i2.CryptoCurrency? coin) => (super.noSuchMethod( @@ -1117,6 +1234,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), ), ) as _i4.FusionInfo); + @override void setFusionServerInfo( _i2.CryptoCurrency? coin, @@ -1132,6 +1250,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override void addListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1140,6 +1259,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override void removeListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1148,6 +1268,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1156,6 +1277,7 @@ class MockPrefs extends _i1.Mock implements _i8.Prefs { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/flutter_secure_storage_interface_test.mocks.dart b/test/flutter_secure_storage_interface_test.mocks.dart index 8779d5147..e99c6b1a7 100644 --- a/test/flutter_secure_storage_interface_test.mocks.dart +++ b/test/flutter_secure_storage_interface_test.mocks.dart @@ -100,6 +100,7 @@ class MockFlutterSecureStorage extends _i1.Mock Invocation.getter(#iOptions), ), ) as _i2.IOSOptions); + @override _i2.AndroidOptions get aOptions => (super.noSuchMethod( Invocation.getter(#aOptions), @@ -108,6 +109,7 @@ class MockFlutterSecureStorage extends _i1.Mock Invocation.getter(#aOptions), ), ) as _i2.AndroidOptions); + @override _i2.LinuxOptions get lOptions => (super.noSuchMethod( Invocation.getter(#lOptions), @@ -116,6 +118,7 @@ class MockFlutterSecureStorage extends _i1.Mock Invocation.getter(#lOptions), ), ) as _i2.LinuxOptions); + @override _i2.WindowsOptions get wOptions => (super.noSuchMethod( Invocation.getter(#wOptions), @@ -124,6 +127,7 @@ class MockFlutterSecureStorage extends _i1.Mock Invocation.getter(#wOptions), ), ) as _i2.WindowsOptions); + @override _i2.WebOptions get webOptions => (super.noSuchMethod( Invocation.getter(#webOptions), @@ -132,6 +136,7 @@ class MockFlutterSecureStorage extends _i1.Mock Invocation.getter(#webOptions), ), ) as _i2.WebOptions); + @override _i2.MacOsOptions get mOptions => (super.noSuchMethod( Invocation.getter(#mOptions), @@ -140,6 +145,7 @@ class MockFlutterSecureStorage extends _i1.Mock Invocation.getter(#mOptions), ), ) as _i2.MacOsOptions); + @override _i3.Future write({ required String? key, @@ -169,6 +175,7 @@ class MockFlutterSecureStorage extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future read({ required String? key, @@ -195,6 +202,7 @@ class MockFlutterSecureStorage extends _i1.Mock ), returnValue: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future containsKey({ required String? key, @@ -221,6 +229,7 @@ class MockFlutterSecureStorage extends _i1.Mock ), returnValue: _i3.Future.value(false), ) as _i3.Future); + @override _i3.Future delete({ required String? key, @@ -248,6 +257,7 @@ class MockFlutterSecureStorage extends _i1.Mock returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override _i3.Future> readAll({ _i2.IOSOptions? iOptions, @@ -272,6 +282,7 @@ class MockFlutterSecureStorage extends _i1.Mock ), returnValue: _i3.Future>.value({}), ) as _i3.Future>); + @override _i3.Future deleteAll({ _i2.IOSOptions? iOptions, diff --git a/test/models/type_adapter_tests/lelantus_coin_adapter_test.mocks.dart b/test/models/type_adapter_tests/lelantus_coin_adapter_test.mocks.dart index 13aeb65c7..140c686d5 100644 --- a/test/models/type_adapter_tests/lelantus_coin_adapter_test.mocks.dart +++ b/test/models/type_adapter_tests/lelantus_coin_adapter_test.mocks.dart @@ -48,11 +48,13 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { Invocation.getter(#availableBytes), returnValue: 0, ) as int); + @override int get usedBytes => (super.noSuchMethod( Invocation.getter(#usedBytes), returnValue: 0, ) as int); + @override void skip(int? bytes) => super.noSuchMethod( Invocation.method( @@ -61,6 +63,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValueForMissingStub: null, ); + @override int readByte() => (super.noSuchMethod( Invocation.method( @@ -69,6 +72,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override _i4.Uint8List viewBytes(int? bytes) => (super.noSuchMethod( Invocation.method( @@ -77,6 +81,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: _i4.Uint8List(0), ) as _i4.Uint8List); + @override _i4.Uint8List peekBytes(int? bytes) => (super.noSuchMethod( Invocation.method( @@ -85,6 +90,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: _i4.Uint8List(0), ) as _i4.Uint8List); + @override int readWord() => (super.noSuchMethod( Invocation.method( @@ -93,6 +99,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override int readInt32() => (super.noSuchMethod( Invocation.method( @@ -101,6 +108,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override int readUint32() => (super.noSuchMethod( Invocation.method( @@ -109,6 +117,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override int readInt() => (super.noSuchMethod( Invocation.method( @@ -117,6 +126,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override double readDouble() => (super.noSuchMethod( Invocation.method( @@ -125,6 +135,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0.0, ) as double); + @override bool readBool() => (super.noSuchMethod( Invocation.method( @@ -133,6 +144,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: false, ) as bool); + @override String readString([ int? byteCount, @@ -157,6 +169,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), ), ) as String); + @override _i4.Uint8List readByteList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -165,6 +178,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: _i4.Uint8List(0), ) as _i4.Uint8List); + @override List readIntList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -173,6 +187,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readDoubleList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -181,6 +196,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readBoolList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -189,6 +205,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readStringList([ int? length, @@ -204,6 +221,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -212,6 +230,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override Map readMap([int? length]) => (super.noSuchMethod( Invocation.method( @@ -220,6 +239,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: {}, ) as Map); + @override _i3.HiveList<_i1.HiveObjectMixin> readHiveList([int? length]) => (super.noSuchMethod( @@ -253,6 +273,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeWord(int? value) => super.noSuchMethod( Invocation.method( @@ -261,6 +282,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeInt32(int? value) => super.noSuchMethod( Invocation.method( @@ -269,6 +291,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeUint32(int? value) => super.noSuchMethod( Invocation.method( @@ -277,6 +300,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeInt(int? value) => super.noSuchMethod( Invocation.method( @@ -285,6 +309,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeDouble(double? value) => super.noSuchMethod( Invocation.method( @@ -293,6 +318,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeBool(bool? value) => super.noSuchMethod( Invocation.method( @@ -301,6 +327,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeString( String? value, { @@ -318,6 +345,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeByteList( List? bytes, { @@ -331,6 +359,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeIntList( List? list, { @@ -344,6 +373,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeDoubleList( List? list, { @@ -357,6 +387,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeBoolList( List? list, { @@ -370,6 +401,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeStringList( List? list, { @@ -387,6 +419,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeList( List? list, { @@ -400,6 +433,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeMap( Map? map, { @@ -413,6 +447,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeHiveList( _i3.HiveList<_i1.HiveObjectMixin>? list, { @@ -426,6 +461,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void write( T? value, { diff --git a/test/models/type_adapter_tests/transactions_model_adapter_test.mocks.dart b/test/models/type_adapter_tests/transactions_model_adapter_test.mocks.dart index 53dd08255..ad9f995db 100644 --- a/test/models/type_adapter_tests/transactions_model_adapter_test.mocks.dart +++ b/test/models/type_adapter_tests/transactions_model_adapter_test.mocks.dart @@ -48,11 +48,13 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { Invocation.getter(#availableBytes), returnValue: 0, ) as int); + @override int get usedBytes => (super.noSuchMethod( Invocation.getter(#usedBytes), returnValue: 0, ) as int); + @override void skip(int? bytes) => super.noSuchMethod( Invocation.method( @@ -61,6 +63,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValueForMissingStub: null, ); + @override int readByte() => (super.noSuchMethod( Invocation.method( @@ -69,6 +72,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override _i4.Uint8List viewBytes(int? bytes) => (super.noSuchMethod( Invocation.method( @@ -77,6 +81,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: _i4.Uint8List(0), ) as _i4.Uint8List); + @override _i4.Uint8List peekBytes(int? bytes) => (super.noSuchMethod( Invocation.method( @@ -85,6 +90,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: _i4.Uint8List(0), ) as _i4.Uint8List); + @override int readWord() => (super.noSuchMethod( Invocation.method( @@ -93,6 +99,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override int readInt32() => (super.noSuchMethod( Invocation.method( @@ -101,6 +108,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override int readUint32() => (super.noSuchMethod( Invocation.method( @@ -109,6 +117,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override int readInt() => (super.noSuchMethod( Invocation.method( @@ -117,6 +126,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override double readDouble() => (super.noSuchMethod( Invocation.method( @@ -125,6 +135,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0.0, ) as double); + @override bool readBool() => (super.noSuchMethod( Invocation.method( @@ -133,6 +144,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: false, ) as bool); + @override String readString([ int? byteCount, @@ -157,6 +169,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), ), ) as String); + @override _i4.Uint8List readByteList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -165,6 +178,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: _i4.Uint8List(0), ) as _i4.Uint8List); + @override List readIntList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -173,6 +187,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readDoubleList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -181,6 +196,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readBoolList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -189,6 +205,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readStringList([ int? length, @@ -204,6 +221,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -212,6 +230,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override Map readMap([int? length]) => (super.noSuchMethod( Invocation.method( @@ -220,6 +239,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: {}, ) as Map); + @override _i3.HiveList<_i1.HiveObjectMixin> readHiveList([int? length]) => (super.noSuchMethod( @@ -253,6 +273,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeWord(int? value) => super.noSuchMethod( Invocation.method( @@ -261,6 +282,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeInt32(int? value) => super.noSuchMethod( Invocation.method( @@ -269,6 +291,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeUint32(int? value) => super.noSuchMethod( Invocation.method( @@ -277,6 +300,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeInt(int? value) => super.noSuchMethod( Invocation.method( @@ -285,6 +309,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeDouble(double? value) => super.noSuchMethod( Invocation.method( @@ -293,6 +318,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeBool(bool? value) => super.noSuchMethod( Invocation.method( @@ -301,6 +327,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeString( String? value, { @@ -318,6 +345,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeByteList( List? bytes, { @@ -331,6 +359,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeIntList( List? list, { @@ -344,6 +373,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeDoubleList( List? list, { @@ -357,6 +387,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeBoolList( List? list, { @@ -370,6 +401,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeStringList( List? list, { @@ -387,6 +419,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeList( List? list, { @@ -400,6 +433,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeMap( Map? map, { @@ -413,6 +447,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeHiveList( _i3.HiveList<_i1.HiveObjectMixin>? list, { @@ -426,6 +461,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void write( T? value, { diff --git a/test/models/type_adapter_tests/utxo_model_adapter_test.mocks.dart b/test/models/type_adapter_tests/utxo_model_adapter_test.mocks.dart index f2750cf2a..983ffb136 100644 --- a/test/models/type_adapter_tests/utxo_model_adapter_test.mocks.dart +++ b/test/models/type_adapter_tests/utxo_model_adapter_test.mocks.dart @@ -48,11 +48,13 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { Invocation.getter(#availableBytes), returnValue: 0, ) as int); + @override int get usedBytes => (super.noSuchMethod( Invocation.getter(#usedBytes), returnValue: 0, ) as int); + @override void skip(int? bytes) => super.noSuchMethod( Invocation.method( @@ -61,6 +63,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValueForMissingStub: null, ); + @override int readByte() => (super.noSuchMethod( Invocation.method( @@ -69,6 +72,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override _i4.Uint8List viewBytes(int? bytes) => (super.noSuchMethod( Invocation.method( @@ -77,6 +81,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: _i4.Uint8List(0), ) as _i4.Uint8List); + @override _i4.Uint8List peekBytes(int? bytes) => (super.noSuchMethod( Invocation.method( @@ -85,6 +90,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: _i4.Uint8List(0), ) as _i4.Uint8List); + @override int readWord() => (super.noSuchMethod( Invocation.method( @@ -93,6 +99,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override int readInt32() => (super.noSuchMethod( Invocation.method( @@ -101,6 +108,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override int readUint32() => (super.noSuchMethod( Invocation.method( @@ -109,6 +117,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override int readInt() => (super.noSuchMethod( Invocation.method( @@ -117,6 +126,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0, ) as int); + @override double readDouble() => (super.noSuchMethod( Invocation.method( @@ -125,6 +135,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: 0.0, ) as double); + @override bool readBool() => (super.noSuchMethod( Invocation.method( @@ -133,6 +144,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: false, ) as bool); + @override String readString([ int? byteCount, @@ -157,6 +169,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), ), ) as String); + @override _i4.Uint8List readByteList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -165,6 +178,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: _i4.Uint8List(0), ) as _i4.Uint8List); + @override List readIntList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -173,6 +187,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readDoubleList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -181,6 +196,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readBoolList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -189,6 +205,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readStringList([ int? length, @@ -204,6 +221,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override List readList([int? length]) => (super.noSuchMethod( Invocation.method( @@ -212,6 +230,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: [], ) as List); + @override Map readMap([int? length]) => (super.noSuchMethod( Invocation.method( @@ -220,6 +239,7 @@ class MockBinaryReader extends _i2.Mock implements _i3.BinaryReader { ), returnValue: {}, ) as Map); + @override _i3.HiveList<_i1.HiveObjectMixin> readHiveList([int? length]) => (super.noSuchMethod( @@ -253,6 +273,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeWord(int? value) => super.noSuchMethod( Invocation.method( @@ -261,6 +282,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeInt32(int? value) => super.noSuchMethod( Invocation.method( @@ -269,6 +291,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeUint32(int? value) => super.noSuchMethod( Invocation.method( @@ -277,6 +300,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeInt(int? value) => super.noSuchMethod( Invocation.method( @@ -285,6 +309,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeDouble(double? value) => super.noSuchMethod( Invocation.method( @@ -293,6 +318,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeBool(bool? value) => super.noSuchMethod( Invocation.method( @@ -301,6 +327,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeString( String? value, { @@ -318,6 +345,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeByteList( List? bytes, { @@ -331,6 +359,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeIntList( List? list, { @@ -344,6 +373,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeDoubleList( List? list, { @@ -357,6 +387,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeBoolList( List? list, { @@ -370,6 +401,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeStringList( List? list, { @@ -387,6 +419,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeList( List? list, { @@ -400,6 +433,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeMap( Map? map, { @@ -413,6 +447,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void writeHiveList( _i3.HiveList<_i1.HiveObjectMixin>? list, { @@ -426,6 +461,7 @@ class MockBinaryWriter extends _i2.Mock implements _i3.BinaryWriter { ), returnValueForMissingStub: null, ); + @override void write( T? value, { diff --git a/test/notifications/notification_card_test.mocks.dart b/test/notifications/notification_card_test.mocks.dart index 52f5ee6db..edff5e5f4 100644 --- a/test/notifications/notification_card_test.mocks.dart +++ b/test/notifications/notification_card_test.mocks.dart @@ -61,6 +61,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#client), ), ) as _i2.HTTP); + @override set client(_i2.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -69,6 +70,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -77,11 +79,13 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i5.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i5.StackTheme>[], ) as List<_i5.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -90,6 +94,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i6.Future install({required _i7.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -101,6 +106,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -111,6 +117,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -120,6 +127,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -130,6 +138,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> fetchThemes() => (super.noSuchMethod( Invocation.method( @@ -139,6 +148,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future>.value( <_i4.StackThemeMetaData>[]), ) as _i6.Future>); + @override _i6.Future<_i7.Uint8List> fetchTheme( {required _i4.StackThemeMetaData? themeMetaData}) => @@ -150,6 +160,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future<_i7.Uint8List>.value(_i7.Uint8List(0)), ) as _i6.Future<_i7.Uint8List>); + @override _i5.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( diff --git a/test/pages/send_view/send_view_test.mocks.dart b/test/pages/send_view/send_view_test.mocks.dart index 17887db35..fee6a0d7f 100644 --- a/test/pages/send_view/send_view_test.mocks.dart +++ b/test/pages/send_view/send_view_test.mocks.dart @@ -121,6 +121,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { Invocation.getter(#nodeService), ), ) as _i2.NodeService); + @override set nodeService(_i2.NodeService? _nodeService) => super.noSuchMethod( Invocation.setter( @@ -129,6 +130,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get mainDB => (super.noSuchMethod( Invocation.getter(#mainDB), @@ -137,6 +139,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { Invocation.getter(#mainDB), ), ) as _i3.MainDB); + @override set mainDB(_i3.MainDB? _mainDB) => super.noSuchMethod( Invocation.setter( @@ -145,11 +148,13 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), returnValueForMissingStub: null, ); + @override List<_i5.Wallet<_i4.CryptoCurrency>> get wallets => (super.noSuchMethod( Invocation.getter(#wallets), returnValue: <_i5.Wallet<_i4.CryptoCurrency>>[], ) as List<_i5.Wallet<_i4.CryptoCurrency>>); + @override _i5.Wallet<_i4.CryptoCurrency> getWallet(String? walletId) => (super.noSuchMethod( @@ -165,6 +170,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), ), ) as _i5.Wallet<_i4.CryptoCurrency>); + @override void addWallet(_i5.Wallet<_i4.CryptoCurrency>? wallet) => super.noSuchMethod( Invocation.method( @@ -173,6 +179,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), returnValueForMissingStub: null, ); + @override _i10.Future deleteWallet( _i11.WalletInfo? info, @@ -189,6 +196,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future load( _i12.Prefs? prefs, @@ -205,6 +213,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future loadAfterStackRestore( _i12.Prefs? prefs, @@ -241,21 +250,25 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i6.SecureStorageInterface); + @override List<_i13.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i13.NodeModel>[], ) as List<_i13.NodeModel>); + @override List<_i13.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i13.NodeModel>[], ) as List<_i13.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i10.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -265,6 +278,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future setPrimaryNodeFor({ required _i4.CryptoCurrency? coin, @@ -284,6 +298,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i13.NodeModel? getPrimaryNodeFor({required _i4.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -291,6 +306,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#currency: currency}, )) as _i13.NodeModel?); + @override List<_i13.NodeModel> getNodesFor(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -300,6 +316,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i13.NodeModel>[], ) as List<_i13.NodeModel>); + @override _i13.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -307,6 +324,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#id: id}, )) as _i13.NodeModel?); + @override List<_i13.NodeModel> failoverNodesFor( {required _i4.CryptoCurrency? currency}) => @@ -318,6 +336,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i13.NodeModel>[], ) as List<_i13.NodeModel>); + @override _i10.Future add( _i13.NodeModel? node, @@ -336,6 +355,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future delete( String? id, @@ -352,6 +372,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future setEnabledState( String? id, @@ -370,6 +391,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future edit( _i13.NodeModel? editedNode, @@ -388,6 +410,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -397,6 +420,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -405,6 +429,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -413,6 +438,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -421,6 +447,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -447,11 +474,13 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i10.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -462,6 +491,7 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -470,6 +500,7 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -478,6 +509,7 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -486,6 +518,7 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -512,6 +545,7 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { Invocation.getter(#client), ), ) as _i7.HTTP); + @override set client(_i7.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -520,6 +554,7 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -528,11 +563,13 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i18.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i18.StackTheme>[], ) as List<_i18.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -541,6 +578,7 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { ), returnValueForMissingStub: null, ); + @override _i10.Future install({required _i19.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -552,6 +590,7 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -562,6 +601,7 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -571,6 +611,7 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -581,6 +622,7 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { ), returnValue: _i10.Future.value(false), ) as _i10.Future); + @override _i10.Future> fetchThemes() => (super.noSuchMethod( @@ -591,6 +633,7 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { returnValue: _i10.Future>.value( <_i17.StackThemeMetaData>[]), ) as _i10.Future>); + @override _i10.Future<_i19.Uint8List> fetchTheme( {required _i17.StackThemeMetaData? themeMetaData}) => @@ -602,6 +645,7 @@ class MockThemeService extends _i1.Mock implements _i17.ThemeService { ), returnValue: _i10.Future<_i19.Uint8List>.value(_i19.Uint8List(0)), ) as _i10.Future<_i19.Uint8List>); + @override _i18.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( @@ -624,11 +668,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#isInitialized), returnValue: false, ) as bool); + @override int get lastUnlockedTimeout => (super.noSuchMethod( Invocation.getter(#lastUnlockedTimeout), returnValue: 0, ) as int); + @override set lastUnlockedTimeout(int? lastUnlockedTimeout) => super.noSuchMethod( Invocation.setter( @@ -637,11 +683,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int get lastUnlocked => (super.noSuchMethod( Invocation.getter(#lastUnlocked), returnValue: 0, ) as int); + @override set lastUnlocked(int? lastUnlocked) => super.noSuchMethod( Invocation.setter( @@ -650,16 +698,19 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int get currentNotificationId => (super.noSuchMethod( Invocation.getter(#currentNotificationId), returnValue: 0, ) as int); + @override List get walletIdsSyncOnStartup => (super.noSuchMethod( Invocation.getter(#walletIdsSyncOnStartup), returnValue: [], ) as List); + @override set walletIdsSyncOnStartup(List? walletIdsSyncOnStartup) => super.noSuchMethod( @@ -669,11 +720,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override _i20.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), returnValue: _i20.SyncingType.currentWalletOnly, ) as _i20.SyncingType); + @override set syncType(_i20.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( @@ -682,11 +735,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get wifiOnly => (super.noSuchMethod( Invocation.getter(#wifiOnly), returnValue: false, ) as bool); + @override set wifiOnly(bool? wifiOnly) => super.noSuchMethod( Invocation.setter( @@ -695,11 +750,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showFavoriteWallets => (super.noSuchMethod( Invocation.getter(#showFavoriteWallets), returnValue: false, ) as bool); + @override set showFavoriteWallets(bool? showFavoriteWallets) => super.noSuchMethod( Invocation.setter( @@ -708,6 +765,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get language => (super.noSuchMethod( Invocation.getter(#language), @@ -716,6 +774,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#language), ), ) as String); + @override set language(String? newLanguage) => super.noSuchMethod( Invocation.setter( @@ -724,6 +783,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get currency => (super.noSuchMethod( Invocation.getter(#currency), @@ -732,6 +792,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#currency), ), ) as String); + @override set currency(String? newCurrency) => super.noSuchMethod( Invocation.setter( @@ -740,11 +801,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get randomizePIN => (super.noSuchMethod( Invocation.getter(#randomizePIN), returnValue: false, ) as bool); + @override set randomizePIN(bool? randomizePIN) => super.noSuchMethod( Invocation.setter( @@ -753,11 +816,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useBiometrics => (super.noSuchMethod( Invocation.getter(#useBiometrics), returnValue: false, ) as bool); + @override set useBiometrics(bool? useBiometrics) => super.noSuchMethod( Invocation.setter( @@ -766,11 +831,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hasPin => (super.noSuchMethod( Invocation.getter(#hasPin), returnValue: false, ) as bool); + @override set hasPin(bool? hasPin) => super.noSuchMethod( Invocation.setter( @@ -779,11 +846,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int get familiarity => (super.noSuchMethod( Invocation.getter(#familiarity), returnValue: 0, ) as int); + @override set familiarity(int? familiarity) => super.noSuchMethod( Invocation.setter( @@ -792,11 +861,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get torKillSwitch => (super.noSuchMethod( Invocation.getter(#torKillSwitch), returnValue: false, ) as bool); + @override set torKillSwitch(bool? torKillswitch) => super.noSuchMethod( Invocation.setter( @@ -805,11 +876,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showTestNetCoins => (super.noSuchMethod( Invocation.getter(#showTestNetCoins), returnValue: false, ) as bool); + @override set showTestNetCoins(bool? showTestNetCoins) => super.noSuchMethod( Invocation.setter( @@ -818,11 +891,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get isAutoBackupEnabled => (super.noSuchMethod( Invocation.getter(#isAutoBackupEnabled), returnValue: false, ) as bool); + @override set isAutoBackupEnabled(bool? isAutoBackupEnabled) => super.noSuchMethod( Invocation.setter( @@ -831,6 +906,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override set autoBackupLocation(String? autoBackupLocation) => super.noSuchMethod( Invocation.setter( @@ -839,11 +915,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override _i21.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), returnValue: _i21.BackupFrequencyType.everyTenMinutes, ) as _i21.BackupFrequencyType); + @override set backupFrequencyType(_i21.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( @@ -853,6 +931,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override set lastAutoBackup(DateTime? lastAutoBackup) => super.noSuchMethod( Invocation.setter( @@ -861,11 +940,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hideBlockExplorerWarning => (super.noSuchMethod( Invocation.getter(#hideBlockExplorerWarning), returnValue: false, ) as bool); + @override set hideBlockExplorerWarning(bool? hideBlockExplorerWarning) => super.noSuchMethod( @@ -875,11 +956,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get gotoWalletOnStartup => (super.noSuchMethod( Invocation.getter(#gotoWalletOnStartup), returnValue: false, ) as bool); + @override set gotoWalletOnStartup(bool? gotoWalletOnStartup) => super.noSuchMethod( Invocation.setter( @@ -888,6 +971,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override set startupWalletId(String? startupWalletId) => super.noSuchMethod( Invocation.setter( @@ -896,11 +980,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get externalCalls => (super.noSuchMethod( Invocation.getter(#externalCalls), returnValue: false, ) as bool); + @override set externalCalls(bool? externalCalls) => super.noSuchMethod( Invocation.setter( @@ -909,11 +995,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableCoinControl => (super.noSuchMethod( Invocation.getter(#enableCoinControl), returnValue: false, ) as bool); + @override set enableCoinControl(bool? enableCoinControl) => super.noSuchMethod( Invocation.setter( @@ -922,11 +1010,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableSystemBrightness => (super.noSuchMethod( Invocation.getter(#enableSystemBrightness), returnValue: false, ) as bool); + @override set enableSystemBrightness(bool? enableSystemBrightness) => super.noSuchMethod( @@ -936,6 +1026,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get themeId => (super.noSuchMethod( Invocation.getter(#themeId), @@ -944,6 +1035,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#themeId), ), ) as String); + @override set themeId(String? themeId) => super.noSuchMethod( Invocation.setter( @@ -952,6 +1044,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessLightThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessLightThemeId), @@ -960,6 +1053,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#systemBrightnessLightThemeId), ), ) as String); + @override set systemBrightnessLightThemeId(String? systemBrightnessLightThemeId) => super.noSuchMethod( @@ -969,6 +1063,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessDarkThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessDarkThemeId), @@ -977,6 +1072,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#systemBrightnessDarkThemeId), ), ) as String); + @override set systemBrightnessDarkThemeId(String? systemBrightnessDarkThemeId) => super.noSuchMethod( @@ -986,11 +1082,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useTor => (super.noSuchMethod( Invocation.getter(#useTor), returnValue: false, ) as bool); + @override set useTor(bool? useTor) => super.noSuchMethod( Invocation.setter( @@ -999,11 +1097,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get autoPin => (super.noSuchMethod( Invocation.getter(#autoPin), returnValue: false, ) as bool); + @override set autoPin(bool? autoPin) => super.noSuchMethod( Invocation.setter( @@ -1012,11 +1112,28 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + + @override + bool get enableExchange => (super.noSuchMethod( + Invocation.getter(#enableExchange), + returnValue: false, + ) as bool); + + @override + set enableExchange(bool? showExchange) => super.noSuchMethod( + Invocation.setter( + #enableExchange, + showExchange, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i10.Future init() => (super.noSuchMethod( Invocation.method( @@ -1026,6 +1143,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( @@ -1035,6 +1153,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future isExternalCallsSet() => (super.noSuchMethod( Invocation.method( @@ -1043,6 +1162,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValue: _i10.Future.value(false), ) as _i10.Future); + @override _i10.Future saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( @@ -1052,6 +1172,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( @@ -1061,6 +1182,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i22.AmountUnit amountUnit(_i4.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -1069,6 +1191,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValue: _i22.AmountUnit.normal, ) as _i22.AmountUnit); + @override void updateAmountUnit({ required _i4.CryptoCurrency? coin, @@ -1085,6 +1208,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int maxDecimals(_i4.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -1093,6 +1217,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValue: 0, ) as int); + @override void updateMaxDecimals({ required _i4.CryptoCurrency? coin, @@ -1109,6 +1234,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override _i8.FusionInfo getFusionServerInfo(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -1124,6 +1250,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), ), ) as _i8.FusionInfo); + @override void setFusionServerInfo( _i4.CryptoCurrency? coin, @@ -1139,6 +1266,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1147,6 +1275,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1155,6 +1284,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1163,6 +1293,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/price_test.mocks.dart b/test/price_test.mocks.dart index 8ba8c6d26..3689ebb89 100644 --- a/test/price_test.mocks.dart +++ b/test/price_test.mocks.dart @@ -70,6 +70,7 @@ class MockHTTP extends _i1.Mock implements _i2.HTTP { ), )), ) as _i3.Future<_i2.Response>); + @override _i3.Future<_i2.Response> post({ required Uri? url, diff --git a/test/screen_tests/address_book_view/address_book_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/address_book_view_screen_test.mocks.dart index b7a88864d..dbbc39497 100644 --- a/test/screen_tests/address_book_view/address_book_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/address_book_view_screen_test.mocks.dart @@ -47,11 +47,13 @@ class MockAddressBookService extends _i1.Mock Invocation.getter(#contacts), returnValue: <_i2.ContactEntry>[], ) as List<_i2.ContactEntry>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i2.ContactEntry getContactById(String? id) => (super.noSuchMethod( Invocation.method( @@ -66,6 +68,7 @@ class MockAddressBookService extends _i1.Mock ), ), ) as _i2.ContactEntry); + @override _i4.Future> search(String? text) => (super.noSuchMethod( @@ -76,6 +79,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future>.value(<_i2.ContactEntry>[]), ) as _i4.Future>); + @override bool matches( String? term, @@ -91,6 +95,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: false, ) as bool); + @override _i4.Future addContact(_i2.ContactEntry? contact) => (super.noSuchMethod( Invocation.method( @@ -99,6 +104,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future editContact(_i2.ContactEntry? editedContact) => (super.noSuchMethod( @@ -108,6 +114,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future removeContact(String? id) => (super.noSuchMethod( Invocation.method( @@ -117,6 +124,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -125,6 +133,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -133,6 +142,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -141,6 +151,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart index 63bbc41c5..25bfa08e4 100644 --- a/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart @@ -88,11 +88,13 @@ class MockAddressBookService extends _i1.Mock Invocation.getter(#contacts), returnValue: <_i3.ContactEntry>[], ) as List<_i3.ContactEntry>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i3.ContactEntry getContactById(String? id) => (super.noSuchMethod( Invocation.method( @@ -107,6 +109,7 @@ class MockAddressBookService extends _i1.Mock ), ), ) as _i3.ContactEntry); + @override _i5.Future> search(String? text) => (super.noSuchMethod( @@ -117,6 +120,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i5.Future>.value(<_i3.ContactEntry>[]), ) as _i5.Future>); + @override bool matches( String? term, @@ -132,6 +136,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: false, ) as bool); + @override _i5.Future addContact(_i3.ContactEntry? contact) => (super.noSuchMethod( Invocation.method( @@ -140,6 +145,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i5.Future.value(false), ) as _i5.Future); + @override _i5.Future editContact(_i3.ContactEntry? editedContact) => (super.noSuchMethod( @@ -149,6 +155,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i5.Future.value(false), ) as _i5.Future); + @override _i5.Future removeContact(String? id) => (super.noSuchMethod( Invocation.method( @@ -158,6 +165,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override void addListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -166,6 +174,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -174,6 +183,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -182,6 +192,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart index 97a359919..b2f02c854 100644 --- a/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart @@ -49,11 +49,13 @@ class MockAddressBookService extends _i1.Mock Invocation.getter(#contacts), returnValue: <_i2.ContactEntry>[], ) as List<_i2.ContactEntry>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i2.ContactEntry getContactById(String? id) => (super.noSuchMethod( Invocation.method( @@ -68,6 +70,7 @@ class MockAddressBookService extends _i1.Mock ), ), ) as _i2.ContactEntry); + @override _i4.Future> search(String? text) => (super.noSuchMethod( @@ -78,6 +81,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future>.value(<_i2.ContactEntry>[]), ) as _i4.Future>); + @override bool matches( String? term, @@ -93,6 +97,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: false, ) as bool); + @override _i4.Future addContact(_i2.ContactEntry? contact) => (super.noSuchMethod( Invocation.method( @@ -101,6 +106,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future editContact(_i2.ContactEntry? editedContact) => (super.noSuchMethod( @@ -110,6 +116,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future removeContact(String? id) => (super.noSuchMethod( Invocation.method( @@ -119,6 +126,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -127,6 +135,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -135,6 +144,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -143,6 +153,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -169,11 +180,13 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i4.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -184,6 +197,7 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -192,6 +206,7 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -200,6 +215,7 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -208,6 +224,7 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart index 1f195d5c3..2c93e063c 100644 --- a/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart @@ -47,11 +47,13 @@ class MockAddressBookService extends _i1.Mock Invocation.getter(#contacts), returnValue: <_i2.ContactEntry>[], ) as List<_i2.ContactEntry>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i2.ContactEntry getContactById(String? id) => (super.noSuchMethod( Invocation.method( @@ -66,6 +68,7 @@ class MockAddressBookService extends _i1.Mock ), ), ) as _i2.ContactEntry); + @override _i4.Future> search(String? text) => (super.noSuchMethod( @@ -76,6 +79,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future>.value(<_i2.ContactEntry>[]), ) as _i4.Future>); + @override bool matches( String? term, @@ -91,6 +95,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: false, ) as bool); + @override _i4.Future addContact(_i2.ContactEntry? contact) => (super.noSuchMethod( Invocation.method( @@ -99,6 +104,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future editContact(_i2.ContactEntry? editedContact) => (super.noSuchMethod( @@ -108,6 +114,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future removeContact(String? id) => (super.noSuchMethod( Invocation.method( @@ -117,6 +124,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -125,6 +133,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -133,6 +142,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -141,6 +151,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/exchange/exchange_view_test.mocks.dart b/test/screen_tests/exchange/exchange_view_test.mocks.dart index d883616bf..b7a8d49d5 100644 --- a/test/screen_tests/exchange/exchange_view_test.mocks.dart +++ b/test/screen_tests/exchange/exchange_view_test.mocks.dart @@ -97,11 +97,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { Invocation.getter(#isInitialized), returnValue: false, ) as bool); + @override int get lastUnlockedTimeout => (super.noSuchMethod( Invocation.getter(#lastUnlockedTimeout), returnValue: 0, ) as int); + @override set lastUnlockedTimeout(int? lastUnlockedTimeout) => super.noSuchMethod( Invocation.setter( @@ -110,11 +112,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override int get lastUnlocked => (super.noSuchMethod( Invocation.getter(#lastUnlocked), returnValue: 0, ) as int); + @override set lastUnlocked(int? lastUnlocked) => super.noSuchMethod( Invocation.setter( @@ -123,16 +127,19 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override int get currentNotificationId => (super.noSuchMethod( Invocation.getter(#currentNotificationId), returnValue: 0, ) as int); + @override List get walletIdsSyncOnStartup => (super.noSuchMethod( Invocation.getter(#walletIdsSyncOnStartup), returnValue: [], ) as List); + @override set walletIdsSyncOnStartup(List? walletIdsSyncOnStartup) => super.noSuchMethod( @@ -142,11 +149,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override _i6.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), returnValue: _i6.SyncingType.currentWalletOnly, ) as _i6.SyncingType); + @override set syncType(_i6.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( @@ -155,11 +164,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get wifiOnly => (super.noSuchMethod( Invocation.getter(#wifiOnly), returnValue: false, ) as bool); + @override set wifiOnly(bool? wifiOnly) => super.noSuchMethod( Invocation.setter( @@ -168,11 +179,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showFavoriteWallets => (super.noSuchMethod( Invocation.getter(#showFavoriteWallets), returnValue: false, ) as bool); + @override set showFavoriteWallets(bool? showFavoriteWallets) => super.noSuchMethod( Invocation.setter( @@ -181,6 +194,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override String get language => (super.noSuchMethod( Invocation.getter(#language), @@ -189,6 +203,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { Invocation.getter(#language), ), ) as String); + @override set language(String? newLanguage) => super.noSuchMethod( Invocation.setter( @@ -197,6 +212,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override String get currency => (super.noSuchMethod( Invocation.getter(#currency), @@ -205,6 +221,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { Invocation.getter(#currency), ), ) as String); + @override set currency(String? newCurrency) => super.noSuchMethod( Invocation.setter( @@ -213,11 +230,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get randomizePIN => (super.noSuchMethod( Invocation.getter(#randomizePIN), returnValue: false, ) as bool); + @override set randomizePIN(bool? randomizePIN) => super.noSuchMethod( Invocation.setter( @@ -226,11 +245,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useBiometrics => (super.noSuchMethod( Invocation.getter(#useBiometrics), returnValue: false, ) as bool); + @override set useBiometrics(bool? useBiometrics) => super.noSuchMethod( Invocation.setter( @@ -239,11 +260,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hasPin => (super.noSuchMethod( Invocation.getter(#hasPin), returnValue: false, ) as bool); + @override set hasPin(bool? hasPin) => super.noSuchMethod( Invocation.setter( @@ -252,11 +275,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override int get familiarity => (super.noSuchMethod( Invocation.getter(#familiarity), returnValue: 0, ) as int); + @override set familiarity(int? familiarity) => super.noSuchMethod( Invocation.setter( @@ -265,11 +290,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get torKillSwitch => (super.noSuchMethod( Invocation.getter(#torKillSwitch), returnValue: false, ) as bool); + @override set torKillSwitch(bool? torKillswitch) => super.noSuchMethod( Invocation.setter( @@ -278,11 +305,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showTestNetCoins => (super.noSuchMethod( Invocation.getter(#showTestNetCoins), returnValue: false, ) as bool); + @override set showTestNetCoins(bool? showTestNetCoins) => super.noSuchMethod( Invocation.setter( @@ -291,11 +320,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get isAutoBackupEnabled => (super.noSuchMethod( Invocation.getter(#isAutoBackupEnabled), returnValue: false, ) as bool); + @override set isAutoBackupEnabled(bool? isAutoBackupEnabled) => super.noSuchMethod( Invocation.setter( @@ -304,6 +335,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override set autoBackupLocation(String? autoBackupLocation) => super.noSuchMethod( Invocation.setter( @@ -312,11 +344,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override _i8.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), returnValue: _i8.BackupFrequencyType.everyTenMinutes, ) as _i8.BackupFrequencyType); + @override set backupFrequencyType(_i8.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( @@ -326,6 +360,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override set lastAutoBackup(DateTime? lastAutoBackup) => super.noSuchMethod( Invocation.setter( @@ -334,11 +369,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hideBlockExplorerWarning => (super.noSuchMethod( Invocation.getter(#hideBlockExplorerWarning), returnValue: false, ) as bool); + @override set hideBlockExplorerWarning(bool? hideBlockExplorerWarning) => super.noSuchMethod( @@ -348,11 +385,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get gotoWalletOnStartup => (super.noSuchMethod( Invocation.getter(#gotoWalletOnStartup), returnValue: false, ) as bool); + @override set gotoWalletOnStartup(bool? gotoWalletOnStartup) => super.noSuchMethod( Invocation.setter( @@ -361,6 +400,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override set startupWalletId(String? startupWalletId) => super.noSuchMethod( Invocation.setter( @@ -369,11 +409,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get externalCalls => (super.noSuchMethod( Invocation.getter(#externalCalls), returnValue: false, ) as bool); + @override set externalCalls(bool? externalCalls) => super.noSuchMethod( Invocation.setter( @@ -382,11 +424,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableCoinControl => (super.noSuchMethod( Invocation.getter(#enableCoinControl), returnValue: false, ) as bool); + @override set enableCoinControl(bool? enableCoinControl) => super.noSuchMethod( Invocation.setter( @@ -395,11 +439,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableSystemBrightness => (super.noSuchMethod( Invocation.getter(#enableSystemBrightness), returnValue: false, ) as bool); + @override set enableSystemBrightness(bool? enableSystemBrightness) => super.noSuchMethod( @@ -409,6 +455,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override String get themeId => (super.noSuchMethod( Invocation.getter(#themeId), @@ -417,6 +464,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { Invocation.getter(#themeId), ), ) as String); + @override set themeId(String? themeId) => super.noSuchMethod( Invocation.setter( @@ -425,6 +473,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessLightThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessLightThemeId), @@ -433,6 +482,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { Invocation.getter(#systemBrightnessLightThemeId), ), ) as String); + @override set systemBrightnessLightThemeId(String? systemBrightnessLightThemeId) => super.noSuchMethod( @@ -442,6 +492,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessDarkThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessDarkThemeId), @@ -450,6 +501,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { Invocation.getter(#systemBrightnessDarkThemeId), ), ) as String); + @override set systemBrightnessDarkThemeId(String? systemBrightnessDarkThemeId) => super.noSuchMethod( @@ -459,11 +511,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useTor => (super.noSuchMethod( Invocation.getter(#useTor), returnValue: false, ) as bool); + @override set useTor(bool? useTor) => super.noSuchMethod( Invocation.setter( @@ -472,11 +526,13 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override bool get autoPin => (super.noSuchMethod( Invocation.getter(#autoPin), returnValue: false, ) as bool); + @override set autoPin(bool? autoPin) => super.noSuchMethod( Invocation.setter( @@ -485,11 +541,28 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + + @override + bool get enableExchange => (super.noSuchMethod( + Invocation.getter(#enableExchange), + returnValue: false, + ) as bool); + + @override + set enableExchange(bool? showExchange) => super.noSuchMethod( + Invocation.setter( + #enableExchange, + showExchange, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i9.Future init() => (super.noSuchMethod( Invocation.method( @@ -499,6 +572,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( @@ -508,6 +582,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future isExternalCallsSet() => (super.noSuchMethod( Invocation.method( @@ -516,6 +591,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValue: _i9.Future.value(false), ) as _i9.Future); + @override _i9.Future saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( @@ -525,6 +601,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( @@ -534,6 +611,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i10.AmountUnit amountUnit(_i11.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -542,6 +620,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValue: _i10.AmountUnit.normal, ) as _i10.AmountUnit); + @override void updateAmountUnit({ required _i11.CryptoCurrency? coin, @@ -558,6 +637,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override int maxDecimals(_i11.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -566,6 +646,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValue: 0, ) as int); + @override void updateMaxDecimals({ required _i11.CryptoCurrency? coin, @@ -582,6 +663,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override _i2.FusionInfo getFusionServerInfo(_i11.CryptoCurrency? coin) => (super.noSuchMethod( @@ -597,6 +679,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), ), ) as _i2.FusionInfo); + @override void setFusionServerInfo( _i11.CryptoCurrency? coin, @@ -612,6 +695,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override void addListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -620,6 +704,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override void removeListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -628,6 +713,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -636,6 +722,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -659,16 +746,19 @@ class MockTradesService extends _i1.Mock implements _i13.TradesService { Invocation.getter(#trades), returnValue: <_i14.Trade>[], ) as List<_i14.Trade>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i14.Trade? get(String? tradeId) => (super.noSuchMethod(Invocation.method( #get, [tradeId], )) as _i14.Trade?); + @override _i9.Future add({ required _i14.Trade? trade, @@ -686,6 +776,7 @@ class MockTradesService extends _i1.Mock implements _i13.TradesService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future edit({ required _i14.Trade? trade, @@ -703,6 +794,7 @@ class MockTradesService extends _i1.Mock implements _i13.TradesService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future delete({ required _i14.Trade? trade, @@ -720,6 +812,7 @@ class MockTradesService extends _i1.Mock implements _i13.TradesService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future deleteByUuid({ required String? uuid, @@ -737,6 +830,7 @@ class MockTradesService extends _i1.Mock implements _i13.TradesService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override void addListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -745,6 +839,7 @@ class MockTradesService extends _i1.Mock implements _i13.TradesService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -753,6 +848,7 @@ class MockTradesService extends _i1.Mock implements _i13.TradesService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -761,6 +857,7 @@ class MockTradesService extends _i1.Mock implements _i13.TradesService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -784,11 +881,13 @@ class MockTradeNotesService extends _i1.Mock implements _i15.TradeNotesService { Invocation.getter(#all), returnValue: {}, ) as Map); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override String getNote({required String? tradeId}) => (super.noSuchMethod( Invocation.method( @@ -805,6 +904,7 @@ class MockTradeNotesService extends _i1.Mock implements _i15.TradeNotesService { ), ), ) as String); + @override _i9.Future set({ required String? tradeId, @@ -822,6 +922,7 @@ class MockTradeNotesService extends _i1.Mock implements _i15.TradeNotesService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future delete({required String? tradeId}) => (super.noSuchMethod( Invocation.method( @@ -832,6 +933,7 @@ class MockTradeNotesService extends _i1.Mock implements _i15.TradeNotesService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override void addListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -840,6 +942,7 @@ class MockTradeNotesService extends _i1.Mock implements _i15.TradeNotesService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -848,6 +951,7 @@ class MockTradeNotesService extends _i1.Mock implements _i15.TradeNotesService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -856,6 +960,7 @@ class MockTradeNotesService extends _i1.Mock implements _i15.TradeNotesService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -882,6 +987,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { Invocation.getter(#client), ), ) as _i3.HTTP); + @override _i9.Future<_i4.ExchangeResponse>> getAvailableCurrencies({ bool? fixedRate, @@ -910,6 +1016,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse>>); + @override _i9.Future<_i4.ExchangeResponse>> getCurrenciesV2() => (super.noSuchMethod( @@ -927,6 +1034,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse>>); + @override _i9.Future<_i4.ExchangeResponse>> getPairedCurrencies({ required String? ticker, @@ -955,6 +1063,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse>>); + @override _i9.Future<_i4.ExchangeResponse<_i18.Decimal>> getMinimalExchangeAmount({ required String? fromTicker, @@ -985,6 +1094,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse<_i18.Decimal>>); + @override _i9.Future<_i4.ExchangeResponse<_i19.Range>> getRange({ required String? fromTicker, @@ -1018,6 +1128,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse<_i19.Range>>); + @override _i9.Future<_i4.ExchangeResponse<_i20.Estimate>> getEstimatedExchangeAmount({ required String? fromTicker, @@ -1051,6 +1162,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse<_i20.Estimate>>); + @override _i9.Future<_i4.ExchangeResponse<_i20.Estimate>> getEstimatedExchangeAmountFixedRate({ @@ -1091,6 +1203,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse<_i20.Estimate>>); + @override _i9.Future<_i4.ExchangeResponse<_i21.CNExchangeEstimate>> getEstimatedExchangeAmountV2({ @@ -1138,6 +1251,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse<_i21.CNExchangeEstimate>>); + @override _i9.Future<_i4.ExchangeResponse>> getAvailableFixedRateMarkets({String? apiKey}) => (super.noSuchMethod( @@ -1157,6 +1271,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse>>); + @override _i9.Future<_i4.ExchangeResponse<_i23.ExchangeTransaction>> createStandardExchangeTransaction({ @@ -1210,6 +1325,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse<_i23.ExchangeTransaction>>); + @override _i9.Future<_i4.ExchangeResponse<_i23.ExchangeTransaction>> createFixedRateExchangeTransaction({ @@ -1269,6 +1385,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse<_i23.ExchangeTransaction>>); + @override _i9.Future< _i4 @@ -1299,6 +1416,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i16.ChangeNowAPI { ), )), ) as _i9.Future<_i4.ExchangeResponse<_i24.ExchangeTransactionStatus>>); + @override _i9.Future<_i4.ExchangeResponse>> getAvailableFloatingRatePairs({bool? includePartners = false}) => diff --git a/test/screen_tests/lockscreen_view_screen_test.mocks.dart b/test/screen_tests/lockscreen_view_screen_test.mocks.dart index 2a0844351..a3523a093 100644 --- a/test/screen_tests/lockscreen_view_screen_test.mocks.dart +++ b/test/screen_tests/lockscreen_view_screen_test.mocks.dart @@ -54,11 +54,13 @@ class MockWalletsService extends _i1.Mock implements _i3.WalletsService { returnValue: _i4.Future>.value( {}), ) as _i4.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -67,6 +69,7 @@ class MockWalletsService extends _i1.Mock implements _i3.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -75,6 +78,7 @@ class MockWalletsService extends _i1.Mock implements _i3.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -83,6 +87,7 @@ class MockWalletsService extends _i1.Mock implements _i3.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -109,21 +114,25 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i2.SecureStorageInterface); + @override List<_i7.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i7.NodeModel>[], ) as List<_i7.NodeModel>); + @override List<_i7.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i7.NodeModel>[], ) as List<_i7.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i4.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -133,6 +142,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future setPrimaryNodeFor({ required _i8.CryptoCurrency? coin, @@ -152,6 +162,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i7.NodeModel? getPrimaryNodeFor({required _i8.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -159,6 +170,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { [], {#currency: currency}, )) as _i7.NodeModel?); + @override List<_i7.NodeModel> getNodesFor(_i8.CryptoCurrency? coin) => (super.noSuchMethod( @@ -168,6 +180,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValue: <_i7.NodeModel>[], ) as List<_i7.NodeModel>); + @override _i7.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -175,6 +188,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { [], {#id: id}, )) as _i7.NodeModel?); + @override List<_i7.NodeModel> failoverNodesFor( {required _i8.CryptoCurrency? currency}) => @@ -186,6 +200,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValue: <_i7.NodeModel>[], ) as List<_i7.NodeModel>); + @override _i4.Future add( _i7.NodeModel? node, @@ -204,6 +219,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future delete( String? id, @@ -220,6 +236,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future setEnabledState( String? id, @@ -238,6 +255,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future edit( _i7.NodeModel? editedNode, @@ -256,6 +274,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -265,6 +284,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -273,6 +293,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -281,6 +302,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -289,6 +311,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart index 9860ea5e7..3d96a2dcf 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart @@ -39,11 +39,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: _i3.Future>.value( {}), ) as _i3.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -52,6 +54,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -60,6 +63,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -68,6 +72,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -94,11 +99,13 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i3.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -109,6 +116,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -117,6 +125,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -125,6 +134,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -133,6 +143,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart index 2cc8ad83e..7cccdb73e 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart @@ -39,11 +39,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: _i3.Future>.value( {}), ) as _i3.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -52,6 +54,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -60,6 +63,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -68,6 +72,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -94,11 +99,13 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i3.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -109,6 +116,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -117,6 +125,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -125,6 +134,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -133,6 +143,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart index 2da39262c..9362ee778 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart @@ -39,11 +39,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: _i3.Future>.value( {}), ) as _i3.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -52,6 +54,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -60,6 +63,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -68,6 +72,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -94,11 +99,13 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i3.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -109,6 +116,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), ) as _i3.Future); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -117,6 +125,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -125,6 +134,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -133,6 +143,7 @@ class MockLocaleService extends _i1.Mock implements _i5.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart b/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart index 7544b767c..951e5306d 100644 --- a/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart @@ -37,11 +37,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: _i3.Future>.value( {}), ) as _i3.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -50,6 +52,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -58,6 +61,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -66,6 +70,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart b/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart index 5aed33644..4f9addbc7 100644 --- a/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart @@ -54,11 +54,13 @@ class MockWalletsService extends _i1.Mock implements _i3.WalletsService { returnValue: _i4.Future>.value( {}), ) as _i4.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -67,6 +69,7 @@ class MockWalletsService extends _i1.Mock implements _i3.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -75,6 +78,7 @@ class MockWalletsService extends _i1.Mock implements _i3.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -83,6 +87,7 @@ class MockWalletsService extends _i1.Mock implements _i3.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -109,21 +114,25 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i2.SecureStorageInterface); + @override List<_i7.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i7.NodeModel>[], ) as List<_i7.NodeModel>); + @override List<_i7.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i7.NodeModel>[], ) as List<_i7.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i4.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -133,6 +142,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future setPrimaryNodeFor({ required _i8.CryptoCurrency? coin, @@ -152,6 +162,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i7.NodeModel? getPrimaryNodeFor({required _i8.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -159,6 +170,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { [], {#currency: currency}, )) as _i7.NodeModel?); + @override List<_i7.NodeModel> getNodesFor(_i8.CryptoCurrency? coin) => (super.noSuchMethod( @@ -168,6 +180,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValue: <_i7.NodeModel>[], ) as List<_i7.NodeModel>); + @override _i7.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -175,6 +188,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { [], {#id: id}, )) as _i7.NodeModel?); + @override List<_i7.NodeModel> failoverNodesFor( {required _i8.CryptoCurrency? currency}) => @@ -186,6 +200,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValue: <_i7.NodeModel>[], ) as List<_i7.NodeModel>); + @override _i4.Future add( _i7.NodeModel? node, @@ -204,6 +219,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future delete( String? id, @@ -220,6 +236,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future setEnabledState( String? id, @@ -238,6 +255,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future edit( _i7.NodeModel? editedNode, @@ -256,6 +274,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override _i4.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -265,6 +284,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -273,6 +293,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -281,6 +302,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -289,6 +311,7 @@ class MockNodeService extends _i1.Mock implements _i6.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/onboarding/name_your_wallet_view_screen_test.mocks.dart b/test/screen_tests/onboarding/name_your_wallet_view_screen_test.mocks.dart index ea7cadff1..5983f2f41 100644 --- a/test/screen_tests/onboarding/name_your_wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/name_your_wallet_view_screen_test.mocks.dart @@ -37,11 +37,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: _i3.Future>.value( {}), ) as _i3.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -50,6 +52,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -58,6 +61,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -66,6 +70,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart b/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart index 7ce8c0b95..0603d61be 100644 --- a/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart @@ -95,11 +95,13 @@ class MockWalletsService extends _i1.Mock implements _i6.WalletsService { returnValue: _i5.Future>.value( {}), ) as _i5.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -108,6 +110,7 @@ class MockWalletsService extends _i1.Mock implements _i6.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -116,6 +119,7 @@ class MockWalletsService extends _i1.Mock implements _i6.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -124,6 +128,7 @@ class MockWalletsService extends _i1.Mock implements _i6.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -150,21 +155,25 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i3.SecureStorageInterface); + @override List<_i9.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i9.NodeModel>[], ) as List<_i9.NodeModel>); + @override List<_i9.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i9.NodeModel>[], ) as List<_i9.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i5.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -174,6 +183,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setPrimaryNodeFor({ required _i10.CryptoCurrency? coin, @@ -193,6 +203,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i9.NodeModel? getPrimaryNodeFor({required _i10.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -200,6 +211,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { [], {#currency: currency}, )) as _i9.NodeModel?); + @override List<_i9.NodeModel> getNodesFor(_i10.CryptoCurrency? coin) => (super.noSuchMethod( @@ -209,6 +221,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { ), returnValue: <_i9.NodeModel>[], ) as List<_i9.NodeModel>); + @override _i9.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -216,6 +229,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { [], {#id: id}, )) as _i9.NodeModel?); + @override List<_i9.NodeModel> failoverNodesFor( {required _i10.CryptoCurrency? currency}) => @@ -227,6 +241,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { ), returnValue: <_i9.NodeModel>[], ) as List<_i9.NodeModel>); + @override _i5.Future add( _i9.NodeModel? node, @@ -245,6 +260,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future delete( String? id, @@ -261,6 +277,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setEnabledState( String? id, @@ -279,6 +296,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future edit( _i9.NodeModel? editedNode, @@ -297,6 +315,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -306,6 +325,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override void addListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -314,6 +334,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -322,6 +343,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -330,6 +352,7 @@ class MockNodeService extends _i1.Mock implements _i8.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart index 6216d4e86..75a10f43e 100644 --- a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart @@ -54,21 +54,25 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i2.SecureStorageInterface); + @override List<_i4.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override List<_i4.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i5.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -78,6 +82,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setPrimaryNodeFor({ required _i6.CryptoCurrency? coin, @@ -97,6 +102,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i4.NodeModel? getPrimaryNodeFor({required _i6.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -104,6 +110,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { [], {#currency: currency}, )) as _i4.NodeModel?); + @override List<_i4.NodeModel> getNodesFor(_i6.CryptoCurrency? coin) => (super.noSuchMethod( @@ -113,6 +120,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override _i4.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -120,6 +128,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { [], {#id: id}, )) as _i4.NodeModel?); + @override List<_i4.NodeModel> failoverNodesFor( {required _i6.CryptoCurrency? currency}) => @@ -131,6 +140,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override _i5.Future add( _i4.NodeModel? node, @@ -149,6 +159,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future delete( String? id, @@ -165,6 +176,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setEnabledState( String? id, @@ -183,6 +195,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future edit( _i4.NodeModel? editedNode, @@ -201,6 +214,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -210,6 +224,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override void addListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -218,6 +233,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -226,6 +242,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -234,6 +251,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart index f1948fa9a..fb159cea3 100644 --- a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart @@ -54,21 +54,25 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i2.SecureStorageInterface); + @override List<_i4.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override List<_i4.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i5.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -78,6 +82,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setPrimaryNodeFor({ required _i6.CryptoCurrency? coin, @@ -97,6 +102,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i4.NodeModel? getPrimaryNodeFor({required _i6.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -104,6 +110,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { [], {#currency: currency}, )) as _i4.NodeModel?); + @override List<_i4.NodeModel> getNodesFor(_i6.CryptoCurrency? coin) => (super.noSuchMethod( @@ -113,6 +120,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override _i4.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -120,6 +128,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { [], {#id: id}, )) as _i4.NodeModel?); + @override List<_i4.NodeModel> failoverNodesFor( {required _i6.CryptoCurrency? currency}) => @@ -131,6 +140,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override _i5.Future add( _i4.NodeModel? node, @@ -149,6 +159,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future delete( String? id, @@ -165,6 +176,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setEnabledState( String? id, @@ -183,6 +195,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future edit( _i4.NodeModel? editedNode, @@ -201,6 +214,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -210,6 +224,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override void addListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -218,6 +233,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -226,6 +242,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -234,6 +251,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_view_screen_test.mocks.dart index 4adf647f0..c60df280d 100644 --- a/test/screen_tests/settings_view/settings_subviews/network_settings_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/network_settings_view_screen_test.mocks.dart @@ -54,21 +54,25 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i2.SecureStorageInterface); + @override List<_i4.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override List<_i4.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i5.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -78,6 +82,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setPrimaryNodeFor({ required _i6.CryptoCurrency? coin, @@ -97,6 +102,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i4.NodeModel? getPrimaryNodeFor({required _i6.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -104,6 +110,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { [], {#currency: currency}, )) as _i4.NodeModel?); + @override List<_i4.NodeModel> getNodesFor(_i6.CryptoCurrency? coin) => (super.noSuchMethod( @@ -113,6 +120,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override _i4.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -120,6 +128,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { [], {#id: id}, )) as _i4.NodeModel?); + @override List<_i4.NodeModel> failoverNodesFor( {required _i6.CryptoCurrency? currency}) => @@ -131,6 +140,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override _i5.Future add( _i4.NodeModel? node, @@ -149,6 +159,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future delete( String? id, @@ -165,6 +176,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setEnabledState( String? id, @@ -183,6 +195,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future edit( _i4.NodeModel? editedNode, @@ -201,6 +214,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -210,6 +224,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override void addListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -218,6 +233,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -226,6 +242,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -234,6 +251,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/change_pin_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/change_pin_view_screen_test.mocks.dart index b9014e5fe..93c8ef6ec 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/change_pin_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/change_pin_view_screen_test.mocks.dart @@ -37,11 +37,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: _i3.Future>.value( {}), ) as _i3.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -50,6 +52,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -58,6 +61,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -66,6 +70,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rename_wallet_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rename_wallet_view_screen_test.mocks.dart index e35762cce..2803819b6 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rename_wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rename_wallet_view_screen_test.mocks.dart @@ -37,11 +37,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: _i3.Future>.value( {}), ) as _i3.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -50,6 +52,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -58,6 +61,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -66,6 +70,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart index 7855c17d8..63ddd796c 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart @@ -37,11 +37,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: _i3.Future>.value( {}), ) as _i3.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -50,6 +52,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -58,6 +61,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -66,6 +70,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart index e4c45b863..40a295640 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart @@ -4,16 +4,18 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i4; -import 'dart:ui' as _i11; +import 'dart:ui' as _i13; -import 'package:local_auth/auth_strings.dart' as _i8; import 'package:local_auth/local_auth.dart' as _i7; +import 'package:local_auth_android/local_auth_android.dart' as _i8; +import 'package:local_auth_darwin/local_auth_darwin.dart' as _i9; +import 'package:local_auth_windows/local_auth_windows.dart' as _i10; import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/src/dummies.dart' as _i6; import 'package:stackwallet/electrumx_rpc/cached_electrumx_client.dart' as _i3; import 'package:stackwallet/electrumx_rpc/electrumx_client.dart' as _i2; -import 'package:stackwallet/services/wallets_service.dart' as _i10; -import 'package:stackwallet/utilities/biometrics.dart' as _i9; +import 'package:stackwallet/services/wallets_service.dart' as _i12; +import 'package:stackwallet/utilities/biometrics.dart' as _i11; import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart' as _i5; @@ -58,6 +60,7 @@ class MockCachedElectrumXClient extends _i1.Mock Invocation.getter(#electrumXClient), ), ) as _i2.ElectrumXClient); + @override _i4.Future> getAnonymitySet({ required String? groupId, @@ -77,6 +80,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i4.Future>.value({}), ) as _i4.Future>); + @override String base64ToHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -91,6 +95,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override String base64ToReverseHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -105,6 +110,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override _i4.Future> getTransaction({ required String? txHash, @@ -124,6 +130,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i4.Future>.value({}), ) as _i4.Future>); + @override _i4.Future> getUsedCoinSerials({ required _i5.CryptoCurrency? cryptoCurrency, @@ -140,6 +147,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), returnValue: _i4.Future>.value([]), ) as _i4.Future>); + @override _i4.Future clearSharedTransactionCache( {required _i5.CryptoCurrency? cryptoCurrency}) => @@ -168,41 +176,16 @@ class MockLocalAuthentication extends _i1.Mock Invocation.getter(#canCheckBiometrics), returnValue: _i4.Future.value(false), ) as _i4.Future); - @override - _i4.Future authenticateWithBiometrics({ - required String? localizedReason, - bool? useErrorDialogs = true, - bool? stickyAuth = false, - _i8.AndroidAuthMessages? androidAuthStrings = - const _i8.AndroidAuthMessages(), - _i8.IOSAuthMessages? iOSAuthStrings = const _i8.IOSAuthMessages(), - bool? sensitiveTransaction = true, - }) => - (super.noSuchMethod( - Invocation.method( - #authenticateWithBiometrics, - [], - { - #localizedReason: localizedReason, - #useErrorDialogs: useErrorDialogs, - #stickyAuth: stickyAuth, - #androidAuthStrings: androidAuthStrings, - #iOSAuthStrings: iOSAuthStrings, - #sensitiveTransaction: sensitiveTransaction, - }, - ), - returnValue: _i4.Future.value(false), - ) as _i4.Future); + @override _i4.Future authenticate({ required String? localizedReason, - bool? useErrorDialogs = true, - bool? stickyAuth = false, - _i8.AndroidAuthMessages? androidAuthStrings = - const _i8.AndroidAuthMessages(), - _i8.IOSAuthMessages? iOSAuthStrings = const _i8.IOSAuthMessages(), - bool? sensitiveTransaction = true, - bool? biometricOnly = false, + Iterable<_i8.AuthMessages>? authMessages = const [ + _i9.IOSAuthMessages(), + _i8.AndroidAuthMessages(), + _i10.WindowsAuthMessages(), + ], + _i8.AuthenticationOptions? options = const _i8.AuthenticationOptions(), }) => (super.noSuchMethod( Invocation.method( @@ -210,16 +193,13 @@ class MockLocalAuthentication extends _i1.Mock [], { #localizedReason: localizedReason, - #useErrorDialogs: useErrorDialogs, - #stickyAuth: stickyAuth, - #androidAuthStrings: androidAuthStrings, - #iOSAuthStrings: iOSAuthStrings, - #sensitiveTransaction: sensitiveTransaction, - #biometricOnly: biometricOnly, + #authMessages: authMessages, + #options: options, }, ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future stopAuthentication() => (super.noSuchMethod( Invocation.method( @@ -228,6 +208,7 @@ class MockLocalAuthentication extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future isDeviceSupported() => (super.noSuchMethod( Invocation.method( @@ -236,22 +217,23 @@ class MockLocalAuthentication extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override - _i4.Future> getAvailableBiometrics() => + _i4.Future> getAvailableBiometrics() => (super.noSuchMethod( Invocation.method( #getAvailableBiometrics, [], ), returnValue: - _i4.Future>.value(<_i7.BiometricType>[]), - ) as _i4.Future>); + _i4.Future>.value(<_i8.BiometricType>[]), + ) as _i4.Future>); } /// A class which mocks [Biometrics]. /// /// See the documentation for Mockito's code generation for more information. -class MockBiometrics extends _i1.Mock implements _i9.Biometrics { +class MockBiometrics extends _i1.Mock implements _i11.Biometrics { MockBiometrics() { _i1.throwOnMissingStub(this); } @@ -279,39 +261,43 @@ class MockBiometrics extends _i1.Mock implements _i9.Biometrics { /// A class which mocks [WalletsService]. /// /// See the documentation for Mockito's code generation for more information. -class MockWalletsService extends _i1.Mock implements _i10.WalletsService { +class MockWalletsService extends _i1.Mock implements _i12.WalletsService { MockWalletsService() { _i1.throwOnMissingStub(this); } @override - _i4.Future> get walletNames => + _i4.Future> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i4.Future>.value( - {}), - ) as _i4.Future>); + returnValue: _i4.Future>.value( + {}), + ) as _i4.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override - void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i13.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], ), returnValueForMissingStub: null, ); + @override - void removeListener(_i11.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i13.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -320,6 +306,7 @@ class MockWalletsService extends _i1.Mock implements _i10.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart index 21c907eb7..2f8346004 100644 --- a/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart @@ -37,11 +37,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: _i3.Future>.value( {}), ) as _i3.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override void addListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -50,6 +52,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i4.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -58,6 +61,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -66,6 +70,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/transaction_subviews/transaction_details_view_screen_test.mocks.dart b/test/screen_tests/transaction_subviews/transaction_details_view_screen_test.mocks.dart index 7c8355a96..531417e9d 100644 --- a/test/screen_tests/transaction_subviews/transaction_details_view_screen_test.mocks.dart +++ b/test/screen_tests/transaction_subviews/transaction_details_view_screen_test.mocks.dart @@ -49,11 +49,13 @@ class MockAddressBookService extends _i1.Mock Invocation.getter(#contacts), returnValue: <_i2.ContactEntry>[], ) as List<_i2.ContactEntry>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i2.ContactEntry getContactById(String? id) => (super.noSuchMethod( Invocation.method( @@ -68,6 +70,7 @@ class MockAddressBookService extends _i1.Mock ), ), ) as _i2.ContactEntry); + @override _i4.Future> search(String? text) => (super.noSuchMethod( @@ -78,6 +81,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future>.value(<_i2.ContactEntry>[]), ) as _i4.Future>); + @override bool matches( String? term, @@ -93,6 +97,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: false, ) as bool); + @override _i4.Future addContact(_i2.ContactEntry? contact) => (super.noSuchMethod( Invocation.method( @@ -101,6 +106,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future editContact(_i2.ContactEntry? editedContact) => (super.noSuchMethod( @@ -110,6 +116,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future removeContact(String? id) => (super.noSuchMethod( Invocation.method( @@ -119,6 +126,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -127,6 +135,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -135,6 +144,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -143,6 +153,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -169,11 +180,13 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i4.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -184,6 +197,7 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -192,6 +206,7 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -200,6 +215,7 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -208,6 +224,7 @@ class MockLocaleService extends _i1.Mock implements _i6.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart b/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart index c4aad0a14..ff1557434 100644 --- a/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart +++ b/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart @@ -39,11 +39,13 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i4.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -54,6 +56,7 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -62,6 +65,7 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -70,6 +74,7 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -78,6 +83,7 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/transaction_subviews/transaction_search_view_screen_test.mocks.dart b/test/screen_tests/transaction_subviews/transaction_search_view_screen_test.mocks.dart index 6fd708af7..a236a0b41 100644 --- a/test/screen_tests/transaction_subviews/transaction_search_view_screen_test.mocks.dart +++ b/test/screen_tests/transaction_subviews/transaction_search_view_screen_test.mocks.dart @@ -47,11 +47,13 @@ class MockAddressBookService extends _i1.Mock Invocation.getter(#contacts), returnValue: <_i2.ContactEntry>[], ) as List<_i2.ContactEntry>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i2.ContactEntry getContactById(String? id) => (super.noSuchMethod( Invocation.method( @@ -66,6 +68,7 @@ class MockAddressBookService extends _i1.Mock ), ), ) as _i2.ContactEntry); + @override _i4.Future> search(String? text) => (super.noSuchMethod( @@ -76,6 +79,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future>.value(<_i2.ContactEntry>[]), ) as _i4.Future>); + @override bool matches( String? term, @@ -91,6 +95,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: false, ) as bool); + @override _i4.Future addContact(_i2.ContactEntry? contact) => (super.noSuchMethod( Invocation.method( @@ -99,6 +104,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future editContact(_i2.ContactEntry? editedContact) => (super.noSuchMethod( @@ -108,6 +114,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future removeContact(String? id) => (super.noSuchMethod( Invocation.method( @@ -117,6 +124,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -125,6 +133,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -133,6 +142,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -141,6 +151,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart index b85201783..cf011b7c6 100644 --- a/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart @@ -39,11 +39,13 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i4.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -54,6 +56,7 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -62,6 +65,7 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -70,6 +74,7 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -78,6 +83,7 @@ class MockLocaleService extends _i1.Mock implements _i2.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/services/change_now/change_now_test.mocks.dart b/test/services/change_now/change_now_test.mocks.dart index 1ee496d32..8134b6449 100644 --- a/test/services/change_now/change_now_test.mocks.dart +++ b/test/services/change_now/change_now_test.mocks.dart @@ -70,6 +70,7 @@ class MockHTTP extends _i1.Mock implements _i2.HTTP { ), )), ) as _i3.Future<_i2.Response>); + @override _i3.Future<_i2.Response> post({ required Uri? url, diff --git a/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart b/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart index 474c6e622..e38af7ce9 100644 --- a/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart +++ b/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart @@ -86,6 +86,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#cryptoCurrency), ), ) as _i2.CryptoCurrency); + @override set failovers(List<_i4.ElectrumXNode>? _failovers) => super.noSuchMethod( Invocation.setter( @@ -94,11 +95,13 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override int get currentFailoverIndex => (super.noSuchMethod( Invocation.getter(#currentFailoverIndex), returnValue: 0, ) as int); + @override set currentFailoverIndex(int? _currentFailoverIndex) => super.noSuchMethod( Invocation.setter( @@ -107,6 +110,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override Duration get connectionTimeoutForSpecialCaseJsonRPCClients => (super.noSuchMethod( @@ -116,6 +120,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#connectionTimeoutForSpecialCaseJsonRPCClients), ), ) as Duration); + @override String get host => (super.noSuchMethod( Invocation.getter(#host), @@ -124,16 +129,19 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#host), ), ) as String); + @override int get port => (super.noSuchMethod( Invocation.getter(#port), returnValue: 0, ) as int); + @override bool get useSSL => (super.noSuchMethod( Invocation.getter(#useSSL), returnValue: false, ) as bool); + @override _i6.Future closeAdapter() => (super.noSuchMethod( Invocation.method( @@ -143,6 +151,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkElectrumAdapter() => (super.noSuchMethod( Invocation.method( @@ -152,6 +161,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future request({ required String? command, @@ -174,6 +184,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> batchRequest({ required String? command, @@ -194,6 +205,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future ping({ String? requestID, @@ -210,6 +222,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getBlockHeadTip({String? requestID}) => (super.noSuchMethod( @@ -221,6 +234,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getServerFeatures({String? requestID}) => (super.noSuchMethod( @@ -232,6 +246,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future broadcastTransaction({ required String? rawTx, @@ -258,6 +273,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future); + @override _i6.Future> getBalance({ required String? scripthash, @@ -275,6 +291,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getHistory({ required String? scripthash, @@ -292,6 +309,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchHistory( {required List? args}) => @@ -304,6 +322,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future>> getUTXOs({ required String? scripthash, @@ -321,6 +340,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchUTXOs( {required List? args}) => @@ -333,6 +353,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future> getTransaction({ required String? txHash, @@ -352,6 +373,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getLelantusAnonymitySet({ String? groupId = r'1', @@ -371,6 +393,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusMintData({ dynamic mints, @@ -387,6 +410,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> getLelantusUsedCoinSerials({ String? requestID, @@ -404,6 +428,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -414,6 +439,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getSparkAnonymitySet({ String? coinGroupId = r'1', @@ -433,6 +459,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getSparkMintMetaData({ String? requestID, @@ -450,6 +477,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future getSparkLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -460,6 +488,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getMempoolTxids({String? requestID}) => (super.noSuchMethod( @@ -470,6 +499,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future< List< @@ -512,6 +542,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { List serialContext, String txid })>>); + @override _i6.Future>> getSparkUnhashedUsedCoinsTagsWithTxHashes({ String? requestID, @@ -528,6 +559,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>>.value(>[]), ) as _i6.Future>>); + @override _i6.Future isMasterNodeCollateral({ String? requestID, @@ -546,6 +578,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getFeeRate({String? requestID}) => (super.noSuchMethod( @@ -557,6 +590,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future<_i3.Decimal> estimateFee({ String? requestID, @@ -583,6 +617,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future<_i3.Decimal>); + @override _i6.Future<_i3.Decimal> relayFee({String? requestID}) => (super.noSuchMethod( Invocation.method( @@ -618,6 +653,7 @@ class MockCachedElectrumXClient extends _i1.Mock Invocation.getter(#electrumXClient), ), ) as _i4.ElectrumXClient); + @override _i6.Future> getAnonymitySet({ required String? groupId, @@ -637,6 +673,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override String base64ToHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -651,6 +688,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override String base64ToReverseHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -665,6 +703,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override _i6.Future> getTransaction({ required String? txHash, @@ -684,6 +723,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getUsedCoinSerials({ required _i2.CryptoCurrency? cryptoCurrency, @@ -700,6 +740,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future clearSharedTransactionCache( {required _i2.CryptoCurrency? cryptoCurrency}) => @@ -731,16 +772,19 @@ class MockTransactionNotificationTracker extends _i1.Mock Invocation.getter(#walletId), ), ) as String); + @override List get pendings => (super.noSuchMethod( Invocation.getter(#pendings), returnValue: [], ) as List); + @override List get confirmeds => (super.noSuchMethod( Invocation.getter(#confirmeds), returnValue: [], ) as List); + @override bool wasNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -749,6 +793,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -758,6 +803,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override bool wasNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -766,6 +812,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -775,6 +822,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future deleteTransaction(String? txid) => (super.noSuchMethod( Invocation.method( diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart index 00b2be75f..edbb3c632 100644 --- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart @@ -86,6 +86,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#cryptoCurrency), ), ) as _i2.CryptoCurrency); + @override set failovers(List<_i4.ElectrumXNode>? _failovers) => super.noSuchMethod( Invocation.setter( @@ -94,11 +95,13 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override int get currentFailoverIndex => (super.noSuchMethod( Invocation.getter(#currentFailoverIndex), returnValue: 0, ) as int); + @override set currentFailoverIndex(int? _currentFailoverIndex) => super.noSuchMethod( Invocation.setter( @@ -107,6 +110,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override Duration get connectionTimeoutForSpecialCaseJsonRPCClients => (super.noSuchMethod( @@ -116,6 +120,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#connectionTimeoutForSpecialCaseJsonRPCClients), ), ) as Duration); + @override String get host => (super.noSuchMethod( Invocation.getter(#host), @@ -124,16 +129,19 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#host), ), ) as String); + @override int get port => (super.noSuchMethod( Invocation.getter(#port), returnValue: 0, ) as int); + @override bool get useSSL => (super.noSuchMethod( Invocation.getter(#useSSL), returnValue: false, ) as bool); + @override _i6.Future closeAdapter() => (super.noSuchMethod( Invocation.method( @@ -143,6 +151,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkElectrumAdapter() => (super.noSuchMethod( Invocation.method( @@ -152,6 +161,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future request({ required String? command, @@ -174,6 +184,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> batchRequest({ required String? command, @@ -194,6 +205,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future ping({ String? requestID, @@ -210,6 +222,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getBlockHeadTip({String? requestID}) => (super.noSuchMethod( @@ -221,6 +234,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getServerFeatures({String? requestID}) => (super.noSuchMethod( @@ -232,6 +246,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future broadcastTransaction({ required String? rawTx, @@ -258,6 +273,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future); + @override _i6.Future> getBalance({ required String? scripthash, @@ -275,6 +291,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getHistory({ required String? scripthash, @@ -292,6 +309,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchHistory( {required List? args}) => @@ -304,6 +322,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future>> getUTXOs({ required String? scripthash, @@ -321,6 +340,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchUTXOs( {required List? args}) => @@ -333,6 +353,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future> getTransaction({ required String? txHash, @@ -352,6 +373,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getLelantusAnonymitySet({ String? groupId = r'1', @@ -371,6 +393,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusMintData({ dynamic mints, @@ -387,6 +410,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> getLelantusUsedCoinSerials({ String? requestID, @@ -404,6 +428,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -414,6 +439,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getSparkAnonymitySet({ String? coinGroupId = r'1', @@ -433,6 +459,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getSparkMintMetaData({ String? requestID, @@ -450,6 +477,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future getSparkLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -460,6 +488,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getMempoolTxids({String? requestID}) => (super.noSuchMethod( @@ -470,6 +499,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future< List< @@ -512,6 +542,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { List serialContext, String txid })>>); + @override _i6.Future>> getSparkUnhashedUsedCoinsTagsWithTxHashes({ String? requestID, @@ -528,6 +559,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>>.value(>[]), ) as _i6.Future>>); + @override _i6.Future isMasterNodeCollateral({ String? requestID, @@ -546,6 +578,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getFeeRate({String? requestID}) => (super.noSuchMethod( @@ -557,6 +590,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future<_i3.Decimal> estimateFee({ String? requestID, @@ -583,6 +617,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future<_i3.Decimal>); + @override _i6.Future<_i3.Decimal> relayFee({String? requestID}) => (super.noSuchMethod( Invocation.method( @@ -618,6 +653,7 @@ class MockCachedElectrumXClient extends _i1.Mock Invocation.getter(#electrumXClient), ), ) as _i4.ElectrumXClient); + @override _i6.Future> getAnonymitySet({ required String? groupId, @@ -637,6 +673,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override String base64ToHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -651,6 +688,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override String base64ToReverseHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -665,6 +703,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override _i6.Future> getTransaction({ required String? txHash, @@ -684,6 +723,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getUsedCoinSerials({ required _i2.CryptoCurrency? cryptoCurrency, @@ -700,6 +740,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future clearSharedTransactionCache( {required _i2.CryptoCurrency? cryptoCurrency}) => @@ -731,16 +772,19 @@ class MockTransactionNotificationTracker extends _i1.Mock Invocation.getter(#walletId), ), ) as String); + @override List get pendings => (super.noSuchMethod( Invocation.getter(#pendings), returnValue: [], ) as List); + @override List get confirmeds => (super.noSuchMethod( Invocation.getter(#confirmeds), returnValue: [], ) as List); + @override bool wasNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -749,6 +793,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -758,6 +803,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override bool wasNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -766,6 +812,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -775,6 +822,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future deleteTransaction(String? txid) => (super.noSuchMethod( Invocation.method( diff --git a/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart b/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart index 45316c474..c5c167366 100644 --- a/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart +++ b/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart @@ -86,6 +86,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#cryptoCurrency), ), ) as _i2.CryptoCurrency); + @override set failovers(List<_i4.ElectrumXNode>? _failovers) => super.noSuchMethod( Invocation.setter( @@ -94,11 +95,13 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override int get currentFailoverIndex => (super.noSuchMethod( Invocation.getter(#currentFailoverIndex), returnValue: 0, ) as int); + @override set currentFailoverIndex(int? _currentFailoverIndex) => super.noSuchMethod( Invocation.setter( @@ -107,6 +110,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override Duration get connectionTimeoutForSpecialCaseJsonRPCClients => (super.noSuchMethod( @@ -116,6 +120,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#connectionTimeoutForSpecialCaseJsonRPCClients), ), ) as Duration); + @override String get host => (super.noSuchMethod( Invocation.getter(#host), @@ -124,16 +129,19 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#host), ), ) as String); + @override int get port => (super.noSuchMethod( Invocation.getter(#port), returnValue: 0, ) as int); + @override bool get useSSL => (super.noSuchMethod( Invocation.getter(#useSSL), returnValue: false, ) as bool); + @override _i6.Future closeAdapter() => (super.noSuchMethod( Invocation.method( @@ -143,6 +151,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkElectrumAdapter() => (super.noSuchMethod( Invocation.method( @@ -152,6 +161,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future request({ required String? command, @@ -174,6 +184,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> batchRequest({ required String? command, @@ -194,6 +205,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future ping({ String? requestID, @@ -210,6 +222,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getBlockHeadTip({String? requestID}) => (super.noSuchMethod( @@ -221,6 +234,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getServerFeatures({String? requestID}) => (super.noSuchMethod( @@ -232,6 +246,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future broadcastTransaction({ required String? rawTx, @@ -258,6 +273,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future); + @override _i6.Future> getBalance({ required String? scripthash, @@ -275,6 +291,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getHistory({ required String? scripthash, @@ -292,6 +309,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchHistory( {required List? args}) => @@ -304,6 +322,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future>> getUTXOs({ required String? scripthash, @@ -321,6 +340,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchUTXOs( {required List? args}) => @@ -333,6 +353,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future> getTransaction({ required String? txHash, @@ -352,6 +373,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getLelantusAnonymitySet({ String? groupId = r'1', @@ -371,6 +393,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusMintData({ dynamic mints, @@ -387,6 +410,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> getLelantusUsedCoinSerials({ String? requestID, @@ -404,6 +428,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -414,6 +439,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getSparkAnonymitySet({ String? coinGroupId = r'1', @@ -433,6 +459,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getSparkMintMetaData({ String? requestID, @@ -450,6 +477,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future getSparkLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -460,6 +488,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getMempoolTxids({String? requestID}) => (super.noSuchMethod( @@ -470,6 +499,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future< List< @@ -512,6 +542,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { List serialContext, String txid })>>); + @override _i6.Future>> getSparkUnhashedUsedCoinsTagsWithTxHashes({ String? requestID, @@ -528,6 +559,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>>.value(>[]), ) as _i6.Future>>); + @override _i6.Future isMasterNodeCollateral({ String? requestID, @@ -546,6 +578,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getFeeRate({String? requestID}) => (super.noSuchMethod( @@ -557,6 +590,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future<_i3.Decimal> estimateFee({ String? requestID, @@ -583,6 +617,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future<_i3.Decimal>); + @override _i6.Future<_i3.Decimal> relayFee({String? requestID}) => (super.noSuchMethod( Invocation.method( @@ -618,6 +653,7 @@ class MockCachedElectrumXClient extends _i1.Mock Invocation.getter(#electrumXClient), ), ) as _i4.ElectrumXClient); + @override _i6.Future> getAnonymitySet({ required String? groupId, @@ -637,6 +673,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override String base64ToHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -651,6 +688,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override String base64ToReverseHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -665,6 +703,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override _i6.Future> getTransaction({ required String? txHash, @@ -684,6 +723,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getUsedCoinSerials({ required _i2.CryptoCurrency? cryptoCurrency, @@ -700,6 +740,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future clearSharedTransactionCache( {required _i2.CryptoCurrency? cryptoCurrency}) => @@ -731,16 +772,19 @@ class MockTransactionNotificationTracker extends _i1.Mock Invocation.getter(#walletId), ), ) as String); + @override List get pendings => (super.noSuchMethod( Invocation.getter(#pendings), returnValue: [], ) as List); + @override List get confirmeds => (super.noSuchMethod( Invocation.getter(#confirmeds), returnValue: [], ) as List); + @override bool wasNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -749,6 +793,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -758,6 +803,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override bool wasNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -766,6 +812,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -775,6 +822,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future deleteTransaction(String? txid) => (super.noSuchMethod( Invocation.method( diff --git a/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart b/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart index 163972e97..80e8c8922 100644 --- a/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart +++ b/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart @@ -86,6 +86,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#cryptoCurrency), ), ) as _i2.CryptoCurrency); + @override set failovers(List<_i4.ElectrumXNode>? _failovers) => super.noSuchMethod( Invocation.setter( @@ -94,11 +95,13 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override int get currentFailoverIndex => (super.noSuchMethod( Invocation.getter(#currentFailoverIndex), returnValue: 0, ) as int); + @override set currentFailoverIndex(int? _currentFailoverIndex) => super.noSuchMethod( Invocation.setter( @@ -107,6 +110,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override Duration get connectionTimeoutForSpecialCaseJsonRPCClients => (super.noSuchMethod( @@ -116,6 +120,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#connectionTimeoutForSpecialCaseJsonRPCClients), ), ) as Duration); + @override String get host => (super.noSuchMethod( Invocation.getter(#host), @@ -124,16 +129,19 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#host), ), ) as String); + @override int get port => (super.noSuchMethod( Invocation.getter(#port), returnValue: 0, ) as int); + @override bool get useSSL => (super.noSuchMethod( Invocation.getter(#useSSL), returnValue: false, ) as bool); + @override _i6.Future closeAdapter() => (super.noSuchMethod( Invocation.method( @@ -143,6 +151,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkElectrumAdapter() => (super.noSuchMethod( Invocation.method( @@ -152,6 +161,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future request({ required String? command, @@ -174,6 +184,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> batchRequest({ required String? command, @@ -194,6 +205,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future ping({ String? requestID, @@ -210,6 +222,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getBlockHeadTip({String? requestID}) => (super.noSuchMethod( @@ -221,6 +234,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getServerFeatures({String? requestID}) => (super.noSuchMethod( @@ -232,6 +246,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future broadcastTransaction({ required String? rawTx, @@ -258,6 +273,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future); + @override _i6.Future> getBalance({ required String? scripthash, @@ -275,6 +291,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getHistory({ required String? scripthash, @@ -292,6 +309,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchHistory( {required List? args}) => @@ -304,6 +322,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future>> getUTXOs({ required String? scripthash, @@ -321,6 +340,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchUTXOs( {required List? args}) => @@ -333,6 +353,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future> getTransaction({ required String? txHash, @@ -352,6 +373,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getLelantusAnonymitySet({ String? groupId = r'1', @@ -371,6 +393,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusMintData({ dynamic mints, @@ -387,6 +410,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> getLelantusUsedCoinSerials({ String? requestID, @@ -404,6 +428,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -414,6 +439,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getSparkAnonymitySet({ String? coinGroupId = r'1', @@ -433,6 +459,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getSparkMintMetaData({ String? requestID, @@ -450,6 +477,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future getSparkLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -460,6 +488,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getMempoolTxids({String? requestID}) => (super.noSuchMethod( @@ -470,6 +499,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future< List< @@ -512,6 +542,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { List serialContext, String txid })>>); + @override _i6.Future>> getSparkUnhashedUsedCoinsTagsWithTxHashes({ String? requestID, @@ -528,6 +559,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>>.value(>[]), ) as _i6.Future>>); + @override _i6.Future isMasterNodeCollateral({ String? requestID, @@ -546,6 +578,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getFeeRate({String? requestID}) => (super.noSuchMethod( @@ -557,6 +590,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future<_i3.Decimal> estimateFee({ String? requestID, @@ -583,6 +617,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future<_i3.Decimal>); + @override _i6.Future<_i3.Decimal> relayFee({String? requestID}) => (super.noSuchMethod( Invocation.method( @@ -618,6 +653,7 @@ class MockCachedElectrumXClient extends _i1.Mock Invocation.getter(#electrumXClient), ), ) as _i4.ElectrumXClient); + @override _i6.Future> getAnonymitySet({ required String? groupId, @@ -637,6 +673,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override String base64ToHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -651,6 +688,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override String base64ToReverseHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -665,6 +703,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override _i6.Future> getTransaction({ required String? txHash, @@ -684,6 +723,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getUsedCoinSerials({ required _i2.CryptoCurrency? cryptoCurrency, @@ -700,6 +740,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future clearSharedTransactionCache( {required _i2.CryptoCurrency? cryptoCurrency}) => @@ -731,16 +772,19 @@ class MockTransactionNotificationTracker extends _i1.Mock Invocation.getter(#walletId), ), ) as String); + @override List get pendings => (super.noSuchMethod( Invocation.getter(#pendings), returnValue: [], ) as List); + @override List get confirmeds => (super.noSuchMethod( Invocation.getter(#confirmeds), returnValue: [], ) as List); + @override bool wasNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -749,6 +793,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -758,6 +803,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override bool wasNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -766,6 +812,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -775,6 +822,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future deleteTransaction(String? txid) => (super.noSuchMethod( Invocation.method( diff --git a/test/services/coins/particl/particl_wallet_test.mocks.dart b/test/services/coins/particl/particl_wallet_test.mocks.dart index 44f0da5ad..0fde0b645 100644 --- a/test/services/coins/particl/particl_wallet_test.mocks.dart +++ b/test/services/coins/particl/particl_wallet_test.mocks.dart @@ -86,6 +86,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#cryptoCurrency), ), ) as _i2.CryptoCurrency); + @override set failovers(List<_i4.ElectrumXNode>? _failovers) => super.noSuchMethod( Invocation.setter( @@ -94,11 +95,13 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override int get currentFailoverIndex => (super.noSuchMethod( Invocation.getter(#currentFailoverIndex), returnValue: 0, ) as int); + @override set currentFailoverIndex(int? _currentFailoverIndex) => super.noSuchMethod( Invocation.setter( @@ -107,6 +110,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValueForMissingStub: null, ); + @override Duration get connectionTimeoutForSpecialCaseJsonRPCClients => (super.noSuchMethod( @@ -116,6 +120,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#connectionTimeoutForSpecialCaseJsonRPCClients), ), ) as Duration); + @override String get host => (super.noSuchMethod( Invocation.getter(#host), @@ -124,16 +129,19 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { Invocation.getter(#host), ), ) as String); + @override int get port => (super.noSuchMethod( Invocation.getter(#port), returnValue: 0, ) as int); + @override bool get useSSL => (super.noSuchMethod( Invocation.getter(#useSSL), returnValue: false, ) as bool); + @override _i6.Future closeAdapter() => (super.noSuchMethod( Invocation.method( @@ -143,6 +151,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkElectrumAdapter() => (super.noSuchMethod( Invocation.method( @@ -152,6 +161,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future request({ required String? command, @@ -174,6 +184,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> batchRequest({ required String? command, @@ -194,6 +205,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future ping({ String? requestID, @@ -210,6 +222,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getBlockHeadTip({String? requestID}) => (super.noSuchMethod( @@ -221,6 +234,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getServerFeatures({String? requestID}) => (super.noSuchMethod( @@ -232,6 +246,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future broadcastTransaction({ required String? rawTx, @@ -258,6 +273,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future); + @override _i6.Future> getBalance({ required String? scripthash, @@ -275,6 +291,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getHistory({ required String? scripthash, @@ -292,6 +309,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchHistory( {required List? args}) => @@ -304,6 +322,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future>> getUTXOs({ required String? scripthash, @@ -321,6 +340,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future>>> getBatchUTXOs( {required List? args}) => @@ -333,6 +353,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>>.value( >>[]), ) as _i6.Future>>>); + @override _i6.Future> getTransaction({ required String? txHash, @@ -352,6 +373,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getLelantusAnonymitySet({ String? groupId = r'1', @@ -371,6 +393,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusMintData({ dynamic mints, @@ -387,6 +410,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future> getLelantusUsedCoinSerials({ String? requestID, @@ -404,6 +428,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future getLelantusLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -414,6 +439,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getSparkAnonymitySet({ String? coinGroupId = r'1', @@ -433,6 +459,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future>> getSparkMintMetaData({ String? requestID, @@ -450,6 +477,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>>.value( >[]), ) as _i6.Future>>); + @override _i6.Future getSparkLatestCoinId({String? requestID}) => (super.noSuchMethod( @@ -460,6 +488,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(0), ) as _i6.Future); + @override _i6.Future> getMempoolTxids({String? requestID}) => (super.noSuchMethod( @@ -470,6 +499,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future< List< @@ -512,6 +542,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { List serialContext, String txid })>>); + @override _i6.Future>> getSparkUnhashedUsedCoinsTagsWithTxHashes({ String? requestID, @@ -528,6 +559,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future>>.value(>[]), ) as _i6.Future>>); + @override _i6.Future isMasterNodeCollateral({ String? requestID, @@ -546,6 +578,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> getFeeRate({String? requestID}) => (super.noSuchMethod( @@ -557,6 +590,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future<_i3.Decimal> estimateFee({ String? requestID, @@ -583,6 +617,7 @@ class MockElectrumXClient extends _i1.Mock implements _i4.ElectrumXClient { ), )), ) as _i6.Future<_i3.Decimal>); + @override _i6.Future<_i3.Decimal> relayFee({String? requestID}) => (super.noSuchMethod( Invocation.method( @@ -618,6 +653,7 @@ class MockCachedElectrumXClient extends _i1.Mock Invocation.getter(#electrumXClient), ), ) as _i4.ElectrumXClient); + @override _i6.Future> getAnonymitySet({ required String? groupId, @@ -637,6 +673,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override String base64ToHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -651,6 +688,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override String base64ToReverseHex(String? source) => (super.noSuchMethod( Invocation.method( @@ -665,6 +703,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), ), ) as String); + @override _i6.Future> getTransaction({ required String? txHash, @@ -684,6 +723,7 @@ class MockCachedElectrumXClient extends _i1.Mock returnValue: _i6.Future>.value({}), ) as _i6.Future>); + @override _i6.Future> getUsedCoinSerials({ required _i2.CryptoCurrency? cryptoCurrency, @@ -700,6 +740,7 @@ class MockCachedElectrumXClient extends _i1.Mock ), returnValue: _i6.Future>.value([]), ) as _i6.Future>); + @override _i6.Future clearSharedTransactionCache( {required _i2.CryptoCurrency? cryptoCurrency}) => @@ -731,16 +772,19 @@ class MockTransactionNotificationTracker extends _i1.Mock Invocation.getter(#walletId), ), ) as String); + @override List get pendings => (super.noSuchMethod( Invocation.getter(#pendings), returnValue: [], ) as List); + @override List get confirmeds => (super.noSuchMethod( Invocation.getter(#confirmeds), returnValue: [], ) as List); + @override bool wasNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -749,6 +793,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedPending(String? txid) => (super.noSuchMethod( Invocation.method( @@ -758,6 +803,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override bool wasNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -766,6 +812,7 @@ class MockTransactionNotificationTracker extends _i1.Mock ), returnValue: false, ) as bool); + @override _i6.Future addNotifiedConfirmed(String? txid) => (super.noSuchMethod( Invocation.method( @@ -775,6 +822,7 @@ class MockTransactionNotificationTracker extends _i1.Mock returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future deleteTransaction(String? txid) => (super.noSuchMethod( Invocation.method( diff --git a/test/widget_tests/address_book_card_test.mocks.dart b/test/widget_tests/address_book_card_test.mocks.dart index cfb056577..220d5cd66 100644 --- a/test/widget_tests/address_book_card_test.mocks.dart +++ b/test/widget_tests/address_book_card_test.mocks.dart @@ -47,11 +47,13 @@ class MockAddressBookService extends _i1.Mock Invocation.getter(#contacts), returnValue: <_i2.ContactEntry>[], ) as List<_i2.ContactEntry>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i2.ContactEntry getContactById(String? id) => (super.noSuchMethod( Invocation.method( @@ -66,6 +68,7 @@ class MockAddressBookService extends _i1.Mock ), ), ) as _i2.ContactEntry); + @override _i4.Future> search(String? text) => (super.noSuchMethod( @@ -76,6 +79,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future>.value(<_i2.ContactEntry>[]), ) as _i4.Future>); + @override bool matches( String? term, @@ -91,6 +95,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: false, ) as bool); + @override _i4.Future addContact(_i2.ContactEntry? contact) => (super.noSuchMethod( Invocation.method( @@ -99,6 +104,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future editContact(_i2.ContactEntry? editedContact) => (super.noSuchMethod( @@ -108,6 +114,7 @@ class MockAddressBookService extends _i1.Mock ), returnValue: _i4.Future.value(false), ) as _i4.Future); + @override _i4.Future removeContact(String? id) => (super.noSuchMethod( Invocation.method( @@ -117,6 +124,7 @@ class MockAddressBookService extends _i1.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -125,6 +133,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -133,6 +142,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -141,6 +151,7 @@ class MockAddressBookService extends _i1.Mock ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/widget_tests/custom_buttons/favorite_toggle_test.mocks.dart b/test/widget_tests/custom_buttons/favorite_toggle_test.mocks.dart index 9463dccb8..a7d302709 100644 --- a/test/widget_tests/custom_buttons/favorite_toggle_test.mocks.dart +++ b/test/widget_tests/custom_buttons/favorite_toggle_test.mocks.dart @@ -61,6 +61,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#client), ), ) as _i2.HTTP); + @override set client(_i2.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -69,6 +70,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -77,11 +79,13 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i5.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i5.StackTheme>[], ) as List<_i5.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -90,6 +94,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i6.Future install({required _i7.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -101,6 +106,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -111,6 +117,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -120,6 +127,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -130,6 +138,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> fetchThemes() => (super.noSuchMethod( Invocation.method( @@ -139,6 +148,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future>.value( <_i4.StackThemeMetaData>[]), ) as _i6.Future>); + @override _i6.Future<_i7.Uint8List> fetchTheme( {required _i4.StackThemeMetaData? themeMetaData}) => @@ -150,6 +160,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future<_i7.Uint8List>.value(_i7.Uint8List(0)), ) as _i6.Future<_i7.Uint8List>); + @override _i5.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( diff --git a/test/widget_tests/custom_loading_overlay_test.mocks.dart b/test/widget_tests/custom_loading_overlay_test.mocks.dart index 6848da7ee..996bcf94c 100644 --- a/test/widget_tests/custom_loading_overlay_test.mocks.dart +++ b/test/widget_tests/custom_loading_overlay_test.mocks.dart @@ -61,6 +61,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#client), ), ) as _i2.HTTP); + @override set client(_i2.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -69,6 +70,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -77,11 +79,13 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i5.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i5.StackTheme>[], ) as List<_i5.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -90,6 +94,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i6.Future install({required _i7.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -101,6 +106,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -111,6 +117,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -120,6 +127,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -130,6 +138,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> fetchThemes() => (super.noSuchMethod( Invocation.method( @@ -139,6 +148,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future>.value( <_i4.StackThemeMetaData>[]), ) as _i6.Future>); + @override _i6.Future<_i7.Uint8List> fetchTheme( {required _i4.StackThemeMetaData? themeMetaData}) => @@ -150,6 +160,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future<_i7.Uint8List>.value(_i7.Uint8List(0)), ) as _i6.Future<_i7.Uint8List>); + @override _i5.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( diff --git a/test/widget_tests/desktop/desktop_scaffold_test.mocks.dart b/test/widget_tests/desktop/desktop_scaffold_test.mocks.dart index 046da5ebf..802731670 100644 --- a/test/widget_tests/desktop/desktop_scaffold_test.mocks.dart +++ b/test/widget_tests/desktop/desktop_scaffold_test.mocks.dart @@ -61,6 +61,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#client), ), ) as _i2.HTTP); + @override set client(_i2.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -69,6 +70,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -77,11 +79,13 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i5.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i5.StackTheme>[], ) as List<_i5.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -90,6 +94,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i6.Future install({required _i7.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -101,6 +106,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -111,6 +117,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -120,6 +127,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -130,6 +138,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> fetchThemes() => (super.noSuchMethod( Invocation.method( @@ -139,6 +148,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future>.value( <_i4.StackThemeMetaData>[]), ) as _i6.Future>); + @override _i6.Future<_i7.Uint8List> fetchTheme( {required _i4.StackThemeMetaData? themeMetaData}) => @@ -150,6 +160,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future<_i7.Uint8List>.value(_i7.Uint8List(0)), ) as _i6.Future<_i7.Uint8List>); + @override _i5.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( diff --git a/test/widget_tests/managed_favorite_test.mocks.dart b/test/widget_tests/managed_favorite_test.mocks.dart index 42529c1a4..c2bc00d2c 100644 --- a/test/widget_tests/managed_favorite_test.mocks.dart +++ b/test/widget_tests/managed_favorite_test.mocks.dart @@ -121,6 +121,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { Invocation.getter(#nodeService), ), ) as _i2.NodeService); + @override set nodeService(_i2.NodeService? _nodeService) => super.noSuchMethod( Invocation.setter( @@ -129,6 +130,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get mainDB => (super.noSuchMethod( Invocation.getter(#mainDB), @@ -137,6 +139,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { Invocation.getter(#mainDB), ), ) as _i3.MainDB); + @override set mainDB(_i3.MainDB? _mainDB) => super.noSuchMethod( Invocation.setter( @@ -145,11 +148,13 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), returnValueForMissingStub: null, ); + @override List<_i5.Wallet<_i4.CryptoCurrency>> get wallets => (super.noSuchMethod( Invocation.getter(#wallets), returnValue: <_i5.Wallet<_i4.CryptoCurrency>>[], ) as List<_i5.Wallet<_i4.CryptoCurrency>>); + @override _i5.Wallet<_i4.CryptoCurrency> getWallet(String? walletId) => (super.noSuchMethod( @@ -165,6 +170,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), ), ) as _i5.Wallet<_i4.CryptoCurrency>); + @override void addWallet(_i5.Wallet<_i4.CryptoCurrency>? wallet) => super.noSuchMethod( Invocation.method( @@ -173,6 +179,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), returnValueForMissingStub: null, ); + @override _i10.Future deleteWallet( _i11.WalletInfo? info, @@ -189,6 +196,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future load( _i12.Prefs? prefs, @@ -205,6 +213,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future loadAfterStackRestore( _i12.Prefs? prefs, @@ -241,6 +250,7 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { Invocation.getter(#client), ), ) as _i6.HTTP); + @override set client(_i6.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -249,6 +259,7 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -257,11 +268,13 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i14.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i14.StackTheme>[], ) as List<_i14.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -270,6 +283,7 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { ), returnValueForMissingStub: null, ); + @override _i10.Future install({required _i15.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -281,6 +295,7 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -291,6 +306,7 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -300,6 +316,7 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -310,6 +327,7 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { ), returnValue: _i10.Future.value(false), ) as _i10.Future); + @override _i10.Future> fetchThemes() => (super.noSuchMethod( @@ -320,6 +338,7 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { returnValue: _i10.Future>.value( <_i13.StackThemeMetaData>[]), ) as _i10.Future>); + @override _i10.Future<_i15.Uint8List> fetchTheme( {required _i13.StackThemeMetaData? themeMetaData}) => @@ -331,6 +350,7 @@ class MockThemeService extends _i1.Mock implements _i13.ThemeService { ), returnValue: _i10.Future<_i15.Uint8List>.value(_i15.Uint8List(0)), ) as _i10.Future<_i15.Uint8List>); + @override _i14.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( @@ -353,11 +373,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#isInitialized), returnValue: false, ) as bool); + @override int get lastUnlockedTimeout => (super.noSuchMethod( Invocation.getter(#lastUnlockedTimeout), returnValue: 0, ) as int); + @override set lastUnlockedTimeout(int? lastUnlockedTimeout) => super.noSuchMethod( Invocation.setter( @@ -366,11 +388,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int get lastUnlocked => (super.noSuchMethod( Invocation.getter(#lastUnlocked), returnValue: 0, ) as int); + @override set lastUnlocked(int? lastUnlocked) => super.noSuchMethod( Invocation.setter( @@ -379,16 +403,19 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int get currentNotificationId => (super.noSuchMethod( Invocation.getter(#currentNotificationId), returnValue: 0, ) as int); + @override List get walletIdsSyncOnStartup => (super.noSuchMethod( Invocation.getter(#walletIdsSyncOnStartup), returnValue: [], ) as List); + @override set walletIdsSyncOnStartup(List? walletIdsSyncOnStartup) => super.noSuchMethod( @@ -398,11 +425,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override _i16.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), returnValue: _i16.SyncingType.currentWalletOnly, ) as _i16.SyncingType); + @override set syncType(_i16.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( @@ -411,11 +440,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get wifiOnly => (super.noSuchMethod( Invocation.getter(#wifiOnly), returnValue: false, ) as bool); + @override set wifiOnly(bool? wifiOnly) => super.noSuchMethod( Invocation.setter( @@ -424,11 +455,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showFavoriteWallets => (super.noSuchMethod( Invocation.getter(#showFavoriteWallets), returnValue: false, ) as bool); + @override set showFavoriteWallets(bool? showFavoriteWallets) => super.noSuchMethod( Invocation.setter( @@ -437,6 +470,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get language => (super.noSuchMethod( Invocation.getter(#language), @@ -445,6 +479,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#language), ), ) as String); + @override set language(String? newLanguage) => super.noSuchMethod( Invocation.setter( @@ -453,6 +488,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get currency => (super.noSuchMethod( Invocation.getter(#currency), @@ -461,6 +497,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#currency), ), ) as String); + @override set currency(String? newCurrency) => super.noSuchMethod( Invocation.setter( @@ -469,11 +506,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get randomizePIN => (super.noSuchMethod( Invocation.getter(#randomizePIN), returnValue: false, ) as bool); + @override set randomizePIN(bool? randomizePIN) => super.noSuchMethod( Invocation.setter( @@ -482,11 +521,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useBiometrics => (super.noSuchMethod( Invocation.getter(#useBiometrics), returnValue: false, ) as bool); + @override set useBiometrics(bool? useBiometrics) => super.noSuchMethod( Invocation.setter( @@ -495,11 +536,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hasPin => (super.noSuchMethod( Invocation.getter(#hasPin), returnValue: false, ) as bool); + @override set hasPin(bool? hasPin) => super.noSuchMethod( Invocation.setter( @@ -508,11 +551,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int get familiarity => (super.noSuchMethod( Invocation.getter(#familiarity), returnValue: 0, ) as int); + @override set familiarity(int? familiarity) => super.noSuchMethod( Invocation.setter( @@ -521,11 +566,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get torKillSwitch => (super.noSuchMethod( Invocation.getter(#torKillSwitch), returnValue: false, ) as bool); + @override set torKillSwitch(bool? torKillswitch) => super.noSuchMethod( Invocation.setter( @@ -534,11 +581,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showTestNetCoins => (super.noSuchMethod( Invocation.getter(#showTestNetCoins), returnValue: false, ) as bool); + @override set showTestNetCoins(bool? showTestNetCoins) => super.noSuchMethod( Invocation.setter( @@ -547,11 +596,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get isAutoBackupEnabled => (super.noSuchMethod( Invocation.getter(#isAutoBackupEnabled), returnValue: false, ) as bool); + @override set isAutoBackupEnabled(bool? isAutoBackupEnabled) => super.noSuchMethod( Invocation.setter( @@ -560,6 +611,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override set autoBackupLocation(String? autoBackupLocation) => super.noSuchMethod( Invocation.setter( @@ -568,11 +620,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override _i18.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), returnValue: _i18.BackupFrequencyType.everyTenMinutes, ) as _i18.BackupFrequencyType); + @override set backupFrequencyType(_i18.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( @@ -582,6 +636,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override set lastAutoBackup(DateTime? lastAutoBackup) => super.noSuchMethod( Invocation.setter( @@ -590,11 +645,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hideBlockExplorerWarning => (super.noSuchMethod( Invocation.getter(#hideBlockExplorerWarning), returnValue: false, ) as bool); + @override set hideBlockExplorerWarning(bool? hideBlockExplorerWarning) => super.noSuchMethod( @@ -604,11 +661,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get gotoWalletOnStartup => (super.noSuchMethod( Invocation.getter(#gotoWalletOnStartup), returnValue: false, ) as bool); + @override set gotoWalletOnStartup(bool? gotoWalletOnStartup) => super.noSuchMethod( Invocation.setter( @@ -617,6 +676,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override set startupWalletId(String? startupWalletId) => super.noSuchMethod( Invocation.setter( @@ -625,11 +685,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get externalCalls => (super.noSuchMethod( Invocation.getter(#externalCalls), returnValue: false, ) as bool); + @override set externalCalls(bool? externalCalls) => super.noSuchMethod( Invocation.setter( @@ -638,11 +700,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableCoinControl => (super.noSuchMethod( Invocation.getter(#enableCoinControl), returnValue: false, ) as bool); + @override set enableCoinControl(bool? enableCoinControl) => super.noSuchMethod( Invocation.setter( @@ -651,11 +715,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableSystemBrightness => (super.noSuchMethod( Invocation.getter(#enableSystemBrightness), returnValue: false, ) as bool); + @override set enableSystemBrightness(bool? enableSystemBrightness) => super.noSuchMethod( @@ -665,6 +731,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get themeId => (super.noSuchMethod( Invocation.getter(#themeId), @@ -673,6 +740,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#themeId), ), ) as String); + @override set themeId(String? themeId) => super.noSuchMethod( Invocation.setter( @@ -681,6 +749,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessLightThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessLightThemeId), @@ -689,6 +758,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#systemBrightnessLightThemeId), ), ) as String); + @override set systemBrightnessLightThemeId(String? systemBrightnessLightThemeId) => super.noSuchMethod( @@ -698,6 +768,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessDarkThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessDarkThemeId), @@ -706,6 +777,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#systemBrightnessDarkThemeId), ), ) as String); + @override set systemBrightnessDarkThemeId(String? systemBrightnessDarkThemeId) => super.noSuchMethod( @@ -715,11 +787,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useTor => (super.noSuchMethod( Invocation.getter(#useTor), returnValue: false, ) as bool); + @override set useTor(bool? useTor) => super.noSuchMethod( Invocation.setter( @@ -728,11 +802,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get autoPin => (super.noSuchMethod( Invocation.getter(#autoPin), returnValue: false, ) as bool); + @override set autoPin(bool? autoPin) => super.noSuchMethod( Invocation.setter( @@ -741,11 +817,28 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + + @override + bool get enableExchange => (super.noSuchMethod( + Invocation.getter(#enableExchange), + returnValue: false, + ) as bool); + + @override + set enableExchange(bool? showExchange) => super.noSuchMethod( + Invocation.setter( + #enableExchange, + showExchange, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i10.Future init() => (super.noSuchMethod( Invocation.method( @@ -755,6 +848,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( @@ -764,6 +858,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future isExternalCallsSet() => (super.noSuchMethod( Invocation.method( @@ -772,6 +867,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValue: _i10.Future.value(false), ) as _i10.Future); + @override _i10.Future saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( @@ -781,6 +877,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( @@ -790,6 +887,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i19.AmountUnit amountUnit(_i4.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -798,6 +896,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValue: _i19.AmountUnit.normal, ) as _i19.AmountUnit); + @override void updateAmountUnit({ required _i4.CryptoCurrency? coin, @@ -814,6 +913,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int maxDecimals(_i4.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -822,6 +922,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValue: 0, ) as int); + @override void updateMaxDecimals({ required _i4.CryptoCurrency? coin, @@ -838,6 +939,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override _i7.FusionInfo getFusionServerInfo(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -853,6 +955,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), ), ) as _i7.FusionInfo); + @override void setFusionServerInfo( _i4.CryptoCurrency? coin, @@ -868,6 +971,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -876,6 +980,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -884,6 +989,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -892,6 +998,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -918,11 +1025,13 @@ class MockLocaleService extends _i1.Mock implements _i21.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i10.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -933,6 +1042,7 @@ class MockLocaleService extends _i1.Mock implements _i21.LocaleService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -941,6 +1051,7 @@ class MockLocaleService extends _i1.Mock implements _i21.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -949,6 +1060,7 @@ class MockLocaleService extends _i1.Mock implements _i21.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -957,6 +1069,7 @@ class MockLocaleService extends _i1.Mock implements _i21.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -983,21 +1096,25 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i8.SecureStorageInterface); + @override List<_i22.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i22.NodeModel>[], ) as List<_i22.NodeModel>); + @override List<_i22.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i22.NodeModel>[], ) as List<_i22.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i10.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -1007,6 +1124,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future setPrimaryNodeFor({ required _i4.CryptoCurrency? coin, @@ -1026,6 +1144,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i22.NodeModel? getPrimaryNodeFor({required _i4.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -1033,6 +1152,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#currency: currency}, )) as _i22.NodeModel?); + @override List<_i22.NodeModel> getNodesFor(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -1042,6 +1162,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i22.NodeModel>[], ) as List<_i22.NodeModel>); + @override _i22.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -1049,6 +1170,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#id: id}, )) as _i22.NodeModel?); + @override List<_i22.NodeModel> failoverNodesFor( {required _i4.CryptoCurrency? currency}) => @@ -1060,6 +1182,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i22.NodeModel>[], ) as List<_i22.NodeModel>); + @override _i10.Future add( _i22.NodeModel? node, @@ -1078,6 +1201,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future delete( String? id, @@ -1094,6 +1218,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future setEnabledState( String? id, @@ -1112,6 +1237,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future edit( _i22.NodeModel? editedNode, @@ -1130,6 +1256,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -1139,6 +1266,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1147,6 +1275,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1155,6 +1284,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1163,6 +1293,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/widget_tests/node_card_test.mocks.dart b/test/widget_tests/node_card_test.mocks.dart index c34b5b77f..441edcdbf 100644 --- a/test/widget_tests/node_card_test.mocks.dart +++ b/test/widget_tests/node_card_test.mocks.dart @@ -54,21 +54,25 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i2.SecureStorageInterface); + @override List<_i4.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override List<_i4.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i5.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -78,6 +82,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setPrimaryNodeFor({ required _i6.CryptoCurrency? coin, @@ -97,6 +102,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i4.NodeModel? getPrimaryNodeFor({required _i6.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -104,6 +110,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { [], {#currency: currency}, )) as _i4.NodeModel?); + @override List<_i4.NodeModel> getNodesFor(_i6.CryptoCurrency? coin) => (super.noSuchMethod( @@ -113,6 +120,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override _i4.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -120,6 +128,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { [], {#id: id}, )) as _i4.NodeModel?); + @override List<_i4.NodeModel> failoverNodesFor( {required _i6.CryptoCurrency? currency}) => @@ -131,6 +140,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValue: <_i4.NodeModel>[], ) as List<_i4.NodeModel>); + @override _i5.Future add( _i4.NodeModel? node, @@ -149,6 +159,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future delete( String? id, @@ -165,6 +176,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future setEnabledState( String? id, @@ -183,6 +195,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future edit( _i4.NodeModel? editedNode, @@ -201,6 +214,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override _i5.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -210,6 +224,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValue: _i5.Future.value(), returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override void addListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -218,6 +233,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -226,6 +242,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -234,6 +251,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/widget_tests/node_options_sheet_test.mocks.dart b/test/widget_tests/node_options_sheet_test.mocks.dart index 46678d619..5e878015f 100644 --- a/test/widget_tests/node_options_sheet_test.mocks.dart +++ b/test/widget_tests/node_options_sheet_test.mocks.dart @@ -122,6 +122,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { Invocation.getter(#nodeService), ), ) as _i2.NodeService); + @override set nodeService(_i2.NodeService? _nodeService) => super.noSuchMethod( Invocation.setter( @@ -130,6 +131,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get mainDB => (super.noSuchMethod( Invocation.getter(#mainDB), @@ -138,6 +140,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { Invocation.getter(#mainDB), ), ) as _i3.MainDB); + @override set mainDB(_i3.MainDB? _mainDB) => super.noSuchMethod( Invocation.setter( @@ -146,11 +149,13 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), returnValueForMissingStub: null, ); + @override List<_i5.Wallet<_i4.CryptoCurrency>> get wallets => (super.noSuchMethod( Invocation.getter(#wallets), returnValue: <_i5.Wallet<_i4.CryptoCurrency>>[], ) as List<_i5.Wallet<_i4.CryptoCurrency>>); + @override _i5.Wallet<_i4.CryptoCurrency> getWallet(String? walletId) => (super.noSuchMethod( @@ -166,6 +171,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), ), ) as _i5.Wallet<_i4.CryptoCurrency>); + @override void addWallet(_i5.Wallet<_i4.CryptoCurrency>? wallet) => super.noSuchMethod( Invocation.method( @@ -174,6 +180,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { ), returnValueForMissingStub: null, ); + @override _i10.Future deleteWallet( _i11.WalletInfo? info, @@ -190,6 +197,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future load( _i12.Prefs? prefs, @@ -206,6 +214,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future loadAfterStackRestore( _i12.Prefs? prefs, @@ -239,11 +248,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#isInitialized), returnValue: false, ) as bool); + @override int get lastUnlockedTimeout => (super.noSuchMethod( Invocation.getter(#lastUnlockedTimeout), returnValue: 0, ) as int); + @override set lastUnlockedTimeout(int? lastUnlockedTimeout) => super.noSuchMethod( Invocation.setter( @@ -252,11 +263,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int get lastUnlocked => (super.noSuchMethod( Invocation.getter(#lastUnlocked), returnValue: 0, ) as int); + @override set lastUnlocked(int? lastUnlocked) => super.noSuchMethod( Invocation.setter( @@ -265,16 +278,19 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int get currentNotificationId => (super.noSuchMethod( Invocation.getter(#currentNotificationId), returnValue: 0, ) as int); + @override List get walletIdsSyncOnStartup => (super.noSuchMethod( Invocation.getter(#walletIdsSyncOnStartup), returnValue: [], ) as List); + @override set walletIdsSyncOnStartup(List? walletIdsSyncOnStartup) => super.noSuchMethod( @@ -284,11 +300,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override _i13.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), returnValue: _i13.SyncingType.currentWalletOnly, ) as _i13.SyncingType); + @override set syncType(_i13.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( @@ -297,11 +315,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get wifiOnly => (super.noSuchMethod( Invocation.getter(#wifiOnly), returnValue: false, ) as bool); + @override set wifiOnly(bool? wifiOnly) => super.noSuchMethod( Invocation.setter( @@ -310,11 +330,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showFavoriteWallets => (super.noSuchMethod( Invocation.getter(#showFavoriteWallets), returnValue: false, ) as bool); + @override set showFavoriteWallets(bool? showFavoriteWallets) => super.noSuchMethod( Invocation.setter( @@ -323,6 +345,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get language => (super.noSuchMethod( Invocation.getter(#language), @@ -331,6 +354,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#language), ), ) as String); + @override set language(String? newLanguage) => super.noSuchMethod( Invocation.setter( @@ -339,6 +363,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get currency => (super.noSuchMethod( Invocation.getter(#currency), @@ -347,6 +372,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#currency), ), ) as String); + @override set currency(String? newCurrency) => super.noSuchMethod( Invocation.setter( @@ -355,11 +381,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get randomizePIN => (super.noSuchMethod( Invocation.getter(#randomizePIN), returnValue: false, ) as bool); + @override set randomizePIN(bool? randomizePIN) => super.noSuchMethod( Invocation.setter( @@ -368,11 +396,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useBiometrics => (super.noSuchMethod( Invocation.getter(#useBiometrics), returnValue: false, ) as bool); + @override set useBiometrics(bool? useBiometrics) => super.noSuchMethod( Invocation.setter( @@ -381,11 +411,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hasPin => (super.noSuchMethod( Invocation.getter(#hasPin), returnValue: false, ) as bool); + @override set hasPin(bool? hasPin) => super.noSuchMethod( Invocation.setter( @@ -394,11 +426,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int get familiarity => (super.noSuchMethod( Invocation.getter(#familiarity), returnValue: 0, ) as int); + @override set familiarity(int? familiarity) => super.noSuchMethod( Invocation.setter( @@ -407,11 +441,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get torKillSwitch => (super.noSuchMethod( Invocation.getter(#torKillSwitch), returnValue: false, ) as bool); + @override set torKillSwitch(bool? torKillswitch) => super.noSuchMethod( Invocation.setter( @@ -420,11 +456,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showTestNetCoins => (super.noSuchMethod( Invocation.getter(#showTestNetCoins), returnValue: false, ) as bool); + @override set showTestNetCoins(bool? showTestNetCoins) => super.noSuchMethod( Invocation.setter( @@ -433,11 +471,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get isAutoBackupEnabled => (super.noSuchMethod( Invocation.getter(#isAutoBackupEnabled), returnValue: false, ) as bool); + @override set isAutoBackupEnabled(bool? isAutoBackupEnabled) => super.noSuchMethod( Invocation.setter( @@ -446,6 +486,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override set autoBackupLocation(String? autoBackupLocation) => super.noSuchMethod( Invocation.setter( @@ -454,11 +495,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override _i15.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), returnValue: _i15.BackupFrequencyType.everyTenMinutes, ) as _i15.BackupFrequencyType); + @override set backupFrequencyType(_i15.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( @@ -468,6 +511,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override set lastAutoBackup(DateTime? lastAutoBackup) => super.noSuchMethod( Invocation.setter( @@ -476,11 +520,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hideBlockExplorerWarning => (super.noSuchMethod( Invocation.getter(#hideBlockExplorerWarning), returnValue: false, ) as bool); + @override set hideBlockExplorerWarning(bool? hideBlockExplorerWarning) => super.noSuchMethod( @@ -490,11 +536,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get gotoWalletOnStartup => (super.noSuchMethod( Invocation.getter(#gotoWalletOnStartup), returnValue: false, ) as bool); + @override set gotoWalletOnStartup(bool? gotoWalletOnStartup) => super.noSuchMethod( Invocation.setter( @@ -503,6 +551,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override set startupWalletId(String? startupWalletId) => super.noSuchMethod( Invocation.setter( @@ -511,11 +560,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get externalCalls => (super.noSuchMethod( Invocation.getter(#externalCalls), returnValue: false, ) as bool); + @override set externalCalls(bool? externalCalls) => super.noSuchMethod( Invocation.setter( @@ -524,11 +575,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableCoinControl => (super.noSuchMethod( Invocation.getter(#enableCoinControl), returnValue: false, ) as bool); + @override set enableCoinControl(bool? enableCoinControl) => super.noSuchMethod( Invocation.setter( @@ -537,11 +590,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableSystemBrightness => (super.noSuchMethod( Invocation.getter(#enableSystemBrightness), returnValue: false, ) as bool); + @override set enableSystemBrightness(bool? enableSystemBrightness) => super.noSuchMethod( @@ -551,6 +606,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get themeId => (super.noSuchMethod( Invocation.getter(#themeId), @@ -559,6 +615,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#themeId), ), ) as String); + @override set themeId(String? themeId) => super.noSuchMethod( Invocation.setter( @@ -567,6 +624,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessLightThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessLightThemeId), @@ -575,6 +633,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#systemBrightnessLightThemeId), ), ) as String); + @override set systemBrightnessLightThemeId(String? systemBrightnessLightThemeId) => super.noSuchMethod( @@ -584,6 +643,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessDarkThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessDarkThemeId), @@ -592,6 +652,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { Invocation.getter(#systemBrightnessDarkThemeId), ), ) as String); + @override set systemBrightnessDarkThemeId(String? systemBrightnessDarkThemeId) => super.noSuchMethod( @@ -601,11 +662,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useTor => (super.noSuchMethod( Invocation.getter(#useTor), returnValue: false, ) as bool); + @override set useTor(bool? useTor) => super.noSuchMethod( Invocation.setter( @@ -614,11 +677,13 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override bool get autoPin => (super.noSuchMethod( Invocation.getter(#autoPin), returnValue: false, ) as bool); + @override set autoPin(bool? autoPin) => super.noSuchMethod( Invocation.setter( @@ -627,11 +692,28 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + + @override + bool get enableExchange => (super.noSuchMethod( + Invocation.getter(#enableExchange), + returnValue: false, + ) as bool); + + @override + set enableExchange(bool? showExchange) => super.noSuchMethod( + Invocation.setter( + #enableExchange, + showExchange, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i10.Future init() => (super.noSuchMethod( Invocation.method( @@ -641,6 +723,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( @@ -650,6 +733,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future isExternalCallsSet() => (super.noSuchMethod( Invocation.method( @@ -658,6 +742,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValue: _i10.Future.value(false), ) as _i10.Future); + @override _i10.Future saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( @@ -667,6 +752,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( @@ -676,6 +762,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i16.AmountUnit amountUnit(_i4.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -684,6 +771,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValue: _i16.AmountUnit.normal, ) as _i16.AmountUnit); + @override void updateAmountUnit({ required _i4.CryptoCurrency? coin, @@ -700,6 +788,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override int maxDecimals(_i4.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -708,6 +797,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValue: 0, ) as int); + @override void updateMaxDecimals({ required _i4.CryptoCurrency? coin, @@ -724,6 +814,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override _i6.FusionInfo getFusionServerInfo(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -739,6 +830,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), ), ) as _i6.FusionInfo); + @override void setFusionServerInfo( _i4.CryptoCurrency? coin, @@ -754,6 +846,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -762,6 +855,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -770,6 +864,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -778,6 +873,7 @@ class MockPrefs extends _i1.Mock implements _i12.Prefs { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -804,21 +900,25 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i7.SecureStorageInterface); + @override List<_i18.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i18.NodeModel>[], ) as List<_i18.NodeModel>); + @override List<_i18.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i18.NodeModel>[], ) as List<_i18.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i10.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -828,6 +928,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future setPrimaryNodeFor({ required _i4.CryptoCurrency? coin, @@ -847,6 +948,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i18.NodeModel? getPrimaryNodeFor({required _i4.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -854,6 +956,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#currency: currency}, )) as _i18.NodeModel?); + @override List<_i18.NodeModel> getNodesFor(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -863,6 +966,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i18.NodeModel>[], ) as List<_i18.NodeModel>); + @override _i18.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -870,6 +974,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#id: id}, )) as _i18.NodeModel?); + @override List<_i18.NodeModel> failoverNodesFor( {required _i4.CryptoCurrency? currency}) => @@ -881,6 +986,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i18.NodeModel>[], ) as List<_i18.NodeModel>); + @override _i10.Future add( _i18.NodeModel? node, @@ -899,6 +1005,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future delete( String? id, @@ -915,6 +1022,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future setEnabledState( String? id, @@ -933,6 +1041,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future edit( _i18.NodeModel? editedNode, @@ -951,6 +1060,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -960,6 +1070,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -968,6 +1079,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -976,6 +1088,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -984,6 +1097,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -1007,6 +1121,7 @@ class MockTorService extends _i1.Mock implements _i19.TorService { Invocation.getter(#status), returnValue: _i20.TorConnectionStatus.disconnected, ) as _i20.TorConnectionStatus); + @override ({_i8.InternetAddress host, int port}) getProxyInfo() => (super.noSuchMethod( Invocation.method( @@ -1024,6 +1139,7 @@ class MockTorService extends _i1.Mock implements _i19.TorService { port: 0 ), ) as ({_i8.InternetAddress host, int port})); + @override void init({ required String? torDataDirPath, @@ -1040,6 +1156,7 @@ class MockTorService extends _i1.Mock implements _i19.TorService { ), returnValueForMissingStub: null, ); + @override _i10.Future start() => (super.noSuchMethod( Invocation.method( @@ -1049,6 +1166,7 @@ class MockTorService extends _i1.Mock implements _i19.TorService { returnValue: _i10.Future.value(), returnValueForMissingStub: _i10.Future.value(), ) as _i10.Future); + @override _i10.Future disable() => (super.noSuchMethod( Invocation.method( diff --git a/test/widget_tests/table_view/table_view_row_test.mocks.dart b/test/widget_tests/table_view/table_view_row_test.mocks.dart index 09791d1f0..9393a5730 100644 --- a/test/widget_tests/table_view/table_view_row_test.mocks.dart +++ b/test/widget_tests/table_view/table_view_row_test.mocks.dart @@ -91,6 +91,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { Invocation.getter(#nodeService), ), ) as _i2.NodeService); + @override set nodeService(_i2.NodeService? _nodeService) => super.noSuchMethod( Invocation.setter( @@ -99,6 +100,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get mainDB => (super.noSuchMethod( Invocation.getter(#mainDB), @@ -107,6 +109,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { Invocation.getter(#mainDB), ), ) as _i3.MainDB); + @override set mainDB(_i3.MainDB? _mainDB) => super.noSuchMethod( Invocation.setter( @@ -115,11 +118,13 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), returnValueForMissingStub: null, ); + @override List<_i5.Wallet<_i4.CryptoCurrency>> get wallets => (super.noSuchMethod( Invocation.getter(#wallets), returnValue: <_i5.Wallet<_i4.CryptoCurrency>>[], ) as List<_i5.Wallet<_i4.CryptoCurrency>>); + @override _i5.Wallet<_i4.CryptoCurrency> getWallet(String? walletId) => (super.noSuchMethod( @@ -135,6 +140,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), ), ) as _i5.Wallet<_i4.CryptoCurrency>); + @override void addWallet(_i5.Wallet<_i4.CryptoCurrency>? wallet) => super.noSuchMethod( Invocation.method( @@ -143,6 +149,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), returnValueForMissingStub: null, ); + @override _i8.Future deleteWallet( _i9.WalletInfo? info, @@ -159,6 +166,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future load( _i11.Prefs? prefs, @@ -175,6 +183,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future loadAfterStackRestore( _i11.Prefs? prefs, @@ -211,6 +220,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { Invocation.getter(#client), ), ) as _i6.HTTP); + @override set client(_i6.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -219,6 +229,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -227,11 +238,13 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i13.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i13.StackTheme>[], ) as List<_i13.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -240,6 +253,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { ), returnValueForMissingStub: null, ); + @override _i8.Future install({required _i14.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -251,6 +265,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -261,6 +276,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -270,6 +286,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -280,6 +297,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { ), returnValue: _i8.Future.value(false), ) as _i8.Future); + @override _i8.Future> fetchThemes() => (super.noSuchMethod( @@ -290,6 +308,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { returnValue: _i8.Future>.value( <_i12.StackThemeMetaData>[]), ) as _i8.Future>); + @override _i8.Future<_i14.Uint8List> fetchTheme( {required _i12.StackThemeMetaData? themeMetaData}) => @@ -301,6 +320,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { ), returnValue: _i8.Future<_i14.Uint8List>.value(_i14.Uint8List(0)), ) as _i8.Future<_i14.Uint8List>); + @override _i13.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( diff --git a/test/widget_tests/trade_card_test.mocks.dart b/test/widget_tests/trade_card_test.mocks.dart index 0f62658a4..a8080d990 100644 --- a/test/widget_tests/trade_card_test.mocks.dart +++ b/test/widget_tests/trade_card_test.mocks.dart @@ -62,6 +62,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#client), ), ) as _i2.HTTP); + @override set client(_i2.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -70,6 +71,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -78,11 +80,13 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i5.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i5.StackTheme>[], ) as List<_i5.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -91,6 +95,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValueForMissingStub: null, ); + @override _i6.Future install({required _i7.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -102,6 +107,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -112,6 +118,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -121,6 +128,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future.value(), returnValueForMissingStub: _i6.Future.value(), ) as _i6.Future); + @override _i6.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -131,6 +139,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future.value(false), ) as _i6.Future); + @override _i6.Future> fetchThemes() => (super.noSuchMethod( Invocation.method( @@ -140,6 +149,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { returnValue: _i6.Future>.value( <_i4.StackThemeMetaData>[]), ) as _i6.Future>); + @override _i6.Future<_i7.Uint8List> fetchTheme( {required _i4.StackThemeMetaData? themeMetaData}) => @@ -151,6 +161,7 @@ class MockThemeService extends _i1.Mock implements _i4.ThemeService { ), returnValue: _i6.Future<_i7.Uint8List>.value(_i7.Uint8List(0)), ) as _i6.Future<_i7.Uint8List>); + @override _i5.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( @@ -176,6 +187,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#bellNew), ), ) as String); + @override String get buy => (super.noSuchMethod( Invocation.getter(#buy), @@ -184,6 +196,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#buy), ), ) as String); + @override String get exchange => (super.noSuchMethod( Invocation.getter(#exchange), @@ -192,6 +205,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#exchange), ), ) as String); + @override String get personaIncognito => (super.noSuchMethod( Invocation.getter(#personaIncognito), @@ -200,6 +214,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#personaIncognito), ), ) as String); + @override String get personaEasy => (super.noSuchMethod( Invocation.getter(#personaEasy), @@ -208,6 +223,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#personaEasy), ), ) as String); + @override String get stack => (super.noSuchMethod( Invocation.getter(#stack), @@ -216,6 +232,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#stack), ), ) as String); + @override String get stackIcon => (super.noSuchMethod( Invocation.getter(#stackIcon), @@ -224,6 +241,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#stackIcon), ), ) as String); + @override String get receive => (super.noSuchMethod( Invocation.getter(#receive), @@ -232,6 +250,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#receive), ), ) as String); + @override String get receivePending => (super.noSuchMethod( Invocation.getter(#receivePending), @@ -240,6 +259,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#receivePending), ), ) as String); + @override String get receiveCancelled => (super.noSuchMethod( Invocation.getter(#receiveCancelled), @@ -248,6 +268,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#receiveCancelled), ), ) as String); + @override String get send => (super.noSuchMethod( Invocation.getter(#send), @@ -256,6 +277,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#send), ), ) as String); + @override String get sendPending => (super.noSuchMethod( Invocation.getter(#sendPending), @@ -264,6 +286,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#sendPending), ), ) as String); + @override String get sendCancelled => (super.noSuchMethod( Invocation.getter(#sendCancelled), @@ -272,6 +295,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#sendCancelled), ), ) as String); + @override String get themeSelector => (super.noSuchMethod( Invocation.getter(#themeSelector), @@ -280,6 +304,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#themeSelector), ), ) as String); + @override String get themePreview => (super.noSuchMethod( Invocation.getter(#themePreview), @@ -288,6 +313,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#themePreview), ), ) as String); + @override String get txExchange => (super.noSuchMethod( Invocation.getter(#txExchange), @@ -296,6 +322,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#txExchange), ), ) as String); + @override String get txExchangePending => (super.noSuchMethod( Invocation.getter(#txExchangePending), @@ -304,6 +331,7 @@ class MockIThemeAssets extends _i1.Mock implements _i5.IThemeAssets { Invocation.getter(#txExchangePending), ), ) as String); + @override String get txExchangeFailed => (super.noSuchMethod( Invocation.getter(#txExchangeFailed), diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart index beca96c89..a5816bdcb 100644 --- a/test/widget_tests/transaction_card_test.mocks.dart +++ b/test/widget_tests/transaction_card_test.mocks.dart @@ -160,6 +160,7 @@ class MockWallets extends _i1.Mock implements _i10.Wallets { Invocation.getter(#nodeService), ), ) as _i2.NodeService); + @override set nodeService(_i2.NodeService? _nodeService) => super.noSuchMethod( Invocation.setter( @@ -168,6 +169,7 @@ class MockWallets extends _i1.Mock implements _i10.Wallets { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get mainDB => (super.noSuchMethod( Invocation.getter(#mainDB), @@ -176,6 +178,7 @@ class MockWallets extends _i1.Mock implements _i10.Wallets { Invocation.getter(#mainDB), ), ) as _i3.MainDB); + @override set mainDB(_i3.MainDB? _mainDB) => super.noSuchMethod( Invocation.setter( @@ -184,11 +187,13 @@ class MockWallets extends _i1.Mock implements _i10.Wallets { ), returnValueForMissingStub: null, ); + @override List<_i5.Wallet<_i4.CryptoCurrency>> get wallets => (super.noSuchMethod( Invocation.getter(#wallets), returnValue: <_i5.Wallet<_i4.CryptoCurrency>>[], ) as List<_i5.Wallet<_i4.CryptoCurrency>>); + @override _i5.Wallet<_i4.CryptoCurrency> getWallet(String? walletId) => (super.noSuchMethod( @@ -204,6 +209,7 @@ class MockWallets extends _i1.Mock implements _i10.Wallets { ), ), ) as _i5.Wallet<_i4.CryptoCurrency>); + @override void addWallet(_i5.Wallet<_i4.CryptoCurrency>? wallet) => super.noSuchMethod( Invocation.method( @@ -212,6 +218,7 @@ class MockWallets extends _i1.Mock implements _i10.Wallets { ), returnValueForMissingStub: null, ); + @override _i11.Future deleteWallet( _i12.WalletInfo? info, @@ -228,6 +235,7 @@ class MockWallets extends _i1.Mock implements _i10.Wallets { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future load( _i14.Prefs? prefs, @@ -244,6 +252,7 @@ class MockWallets extends _i1.Mock implements _i10.Wallets { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future loadAfterStackRestore( _i14.Prefs? prefs, @@ -280,11 +289,13 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i11.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -295,6 +306,7 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -303,6 +315,7 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -311,6 +324,7 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -319,6 +333,7 @@ class MockLocaleService extends _i1.Mock implements _i15.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -342,11 +357,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { Invocation.getter(#isInitialized), returnValue: false, ) as bool); + @override int get lastUnlockedTimeout => (super.noSuchMethod( Invocation.getter(#lastUnlockedTimeout), returnValue: 0, ) as int); + @override set lastUnlockedTimeout(int? lastUnlockedTimeout) => super.noSuchMethod( Invocation.setter( @@ -355,11 +372,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override int get lastUnlocked => (super.noSuchMethod( Invocation.getter(#lastUnlocked), returnValue: 0, ) as int); + @override set lastUnlocked(int? lastUnlocked) => super.noSuchMethod( Invocation.setter( @@ -368,16 +387,19 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override int get currentNotificationId => (super.noSuchMethod( Invocation.getter(#currentNotificationId), returnValue: 0, ) as int); + @override List get walletIdsSyncOnStartup => (super.noSuchMethod( Invocation.getter(#walletIdsSyncOnStartup), returnValue: [], ) as List); + @override set walletIdsSyncOnStartup(List? walletIdsSyncOnStartup) => super.noSuchMethod( @@ -387,11 +409,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override _i18.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), returnValue: _i18.SyncingType.currentWalletOnly, ) as _i18.SyncingType); + @override set syncType(_i18.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( @@ -400,11 +424,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get wifiOnly => (super.noSuchMethod( Invocation.getter(#wifiOnly), returnValue: false, ) as bool); + @override set wifiOnly(bool? wifiOnly) => super.noSuchMethod( Invocation.setter( @@ -413,11 +439,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showFavoriteWallets => (super.noSuchMethod( Invocation.getter(#showFavoriteWallets), returnValue: false, ) as bool); + @override set showFavoriteWallets(bool? showFavoriteWallets) => super.noSuchMethod( Invocation.setter( @@ -426,6 +454,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override String get language => (super.noSuchMethod( Invocation.getter(#language), @@ -434,6 +463,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { Invocation.getter(#language), ), ) as String); + @override set language(String? newLanguage) => super.noSuchMethod( Invocation.setter( @@ -442,6 +472,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override String get currency => (super.noSuchMethod( Invocation.getter(#currency), @@ -450,6 +481,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { Invocation.getter(#currency), ), ) as String); + @override set currency(String? newCurrency) => super.noSuchMethod( Invocation.setter( @@ -458,11 +490,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get randomizePIN => (super.noSuchMethod( Invocation.getter(#randomizePIN), returnValue: false, ) as bool); + @override set randomizePIN(bool? randomizePIN) => super.noSuchMethod( Invocation.setter( @@ -471,11 +505,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useBiometrics => (super.noSuchMethod( Invocation.getter(#useBiometrics), returnValue: false, ) as bool); + @override set useBiometrics(bool? useBiometrics) => super.noSuchMethod( Invocation.setter( @@ -484,11 +520,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hasPin => (super.noSuchMethod( Invocation.getter(#hasPin), returnValue: false, ) as bool); + @override set hasPin(bool? hasPin) => super.noSuchMethod( Invocation.setter( @@ -497,11 +535,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override int get familiarity => (super.noSuchMethod( Invocation.getter(#familiarity), returnValue: 0, ) as int); + @override set familiarity(int? familiarity) => super.noSuchMethod( Invocation.setter( @@ -510,11 +550,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get torKillSwitch => (super.noSuchMethod( Invocation.getter(#torKillSwitch), returnValue: false, ) as bool); + @override set torKillSwitch(bool? torKillswitch) => super.noSuchMethod( Invocation.setter( @@ -523,11 +565,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get showTestNetCoins => (super.noSuchMethod( Invocation.getter(#showTestNetCoins), returnValue: false, ) as bool); + @override set showTestNetCoins(bool? showTestNetCoins) => super.noSuchMethod( Invocation.setter( @@ -536,11 +580,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get isAutoBackupEnabled => (super.noSuchMethod( Invocation.getter(#isAutoBackupEnabled), returnValue: false, ) as bool); + @override set isAutoBackupEnabled(bool? isAutoBackupEnabled) => super.noSuchMethod( Invocation.setter( @@ -549,6 +595,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override set autoBackupLocation(String? autoBackupLocation) => super.noSuchMethod( Invocation.setter( @@ -557,11 +604,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override _i19.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), returnValue: _i19.BackupFrequencyType.everyTenMinutes, ) as _i19.BackupFrequencyType); + @override set backupFrequencyType(_i19.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( @@ -571,6 +620,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override set lastAutoBackup(DateTime? lastAutoBackup) => super.noSuchMethod( Invocation.setter( @@ -579,11 +629,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get hideBlockExplorerWarning => (super.noSuchMethod( Invocation.getter(#hideBlockExplorerWarning), returnValue: false, ) as bool); + @override set hideBlockExplorerWarning(bool? hideBlockExplorerWarning) => super.noSuchMethod( @@ -593,11 +645,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get gotoWalletOnStartup => (super.noSuchMethod( Invocation.getter(#gotoWalletOnStartup), returnValue: false, ) as bool); + @override set gotoWalletOnStartup(bool? gotoWalletOnStartup) => super.noSuchMethod( Invocation.setter( @@ -606,6 +660,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override set startupWalletId(String? startupWalletId) => super.noSuchMethod( Invocation.setter( @@ -614,11 +669,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get externalCalls => (super.noSuchMethod( Invocation.getter(#externalCalls), returnValue: false, ) as bool); + @override set externalCalls(bool? externalCalls) => super.noSuchMethod( Invocation.setter( @@ -627,11 +684,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableCoinControl => (super.noSuchMethod( Invocation.getter(#enableCoinControl), returnValue: false, ) as bool); + @override set enableCoinControl(bool? enableCoinControl) => super.noSuchMethod( Invocation.setter( @@ -640,11 +699,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get enableSystemBrightness => (super.noSuchMethod( Invocation.getter(#enableSystemBrightness), returnValue: false, ) as bool); + @override set enableSystemBrightness(bool? enableSystemBrightness) => super.noSuchMethod( @@ -654,6 +715,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override String get themeId => (super.noSuchMethod( Invocation.getter(#themeId), @@ -662,6 +724,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { Invocation.getter(#themeId), ), ) as String); + @override set themeId(String? themeId) => super.noSuchMethod( Invocation.setter( @@ -670,6 +733,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessLightThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessLightThemeId), @@ -678,6 +742,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { Invocation.getter(#systemBrightnessLightThemeId), ), ) as String); + @override set systemBrightnessLightThemeId(String? systemBrightnessLightThemeId) => super.noSuchMethod( @@ -687,6 +752,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override String get systemBrightnessDarkThemeId => (super.noSuchMethod( Invocation.getter(#systemBrightnessDarkThemeId), @@ -695,6 +761,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { Invocation.getter(#systemBrightnessDarkThemeId), ), ) as String); + @override set systemBrightnessDarkThemeId(String? systemBrightnessDarkThemeId) => super.noSuchMethod( @@ -704,11 +771,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get useTor => (super.noSuchMethod( Invocation.getter(#useTor), returnValue: false, ) as bool); + @override set useTor(bool? useTor) => super.noSuchMethod( Invocation.setter( @@ -717,11 +786,13 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override bool get autoPin => (super.noSuchMethod( Invocation.getter(#autoPin), returnValue: false, ) as bool); + @override set autoPin(bool? autoPin) => super.noSuchMethod( Invocation.setter( @@ -730,11 +801,28 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + + @override + bool get enableExchange => (super.noSuchMethod( + Invocation.getter(#enableExchange), + returnValue: false, + ) as bool); + + @override + set enableExchange(bool? showExchange) => super.noSuchMethod( + Invocation.setter( + #enableExchange, + showExchange, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i11.Future init() => (super.noSuchMethod( Invocation.method( @@ -744,6 +832,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( @@ -753,6 +842,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future isExternalCallsSet() => (super.noSuchMethod( Invocation.method( @@ -761,6 +851,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValue: _i11.Future.value(false), ) as _i11.Future); + @override _i11.Future saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( @@ -770,6 +861,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( @@ -779,6 +871,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i20.AmountUnit amountUnit(_i4.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -787,6 +880,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValue: _i20.AmountUnit.normal, ) as _i20.AmountUnit); + @override void updateAmountUnit({ required _i4.CryptoCurrency? coin, @@ -803,6 +897,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override int maxDecimals(_i4.CryptoCurrency? coin) => (super.noSuchMethod( Invocation.method( @@ -811,6 +906,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValue: 0, ) as int); + @override void updateMaxDecimals({ required _i4.CryptoCurrency? coin, @@ -827,6 +923,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override _i6.FusionInfo getFusionServerInfo(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -842,6 +939,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), ), ) as _i6.FusionInfo); + @override void setFusionServerInfo( _i4.CryptoCurrency? coin, @@ -857,6 +955,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -865,6 +964,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -873,6 +973,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -881,6 +982,7 @@ class MockPrefs extends _i1.Mock implements _i14.Prefs { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -907,6 +1009,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { Invocation.getter(#baseTicker), ), ) as String); + @override set baseTicker(String? _baseTicker) => super.noSuchMethod( Invocation.setter( @@ -915,6 +1018,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { ), returnValueForMissingStub: null, ); + @override Duration get updateInterval => (super.noSuchMethod( Invocation.getter(#updateInterval), @@ -923,17 +1027,20 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { Invocation.getter(#updateInterval), ), ) as Duration); + @override _i11.Future> get tokenContractAddressesToCheck => (super.noSuchMethod( Invocation.getter(#tokenContractAddressesToCheck), returnValue: _i11.Future>.value({}), ) as _i11.Future>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i7.Tuple2<_i22.Decimal, double> getPrice(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -949,6 +1056,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { ), ), ) as _i7.Tuple2<_i22.Decimal, double>); + @override _i7.Tuple2<_i22.Decimal, double> getTokenPrice(String? contractAddress) => (super.noSuchMethod( @@ -964,6 +1072,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { ), ), ) as _i7.Tuple2<_i22.Decimal, double>); + @override _i11.Future updatePrice() => (super.noSuchMethod( Invocation.method( @@ -973,6 +1082,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override void cancel() => super.noSuchMethod( Invocation.method( @@ -981,6 +1091,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { ), returnValueForMissingStub: null, ); + @override void start(bool? rightAway) => super.noSuchMethod( Invocation.method( @@ -989,6 +1100,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -997,6 +1109,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { ), returnValueForMissingStub: null, ); + @override void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1005,6 +1118,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -1013,6 +1127,7 @@ class MockPriceService extends _i1.Mock implements _i21.PriceService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -1039,6 +1154,7 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { Invocation.getter(#client), ), ) as _i8.HTTP); + @override set client(_i8.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -1047,6 +1163,7 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -1055,11 +1172,13 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i24.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i24.StackTheme>[], ) as List<_i24.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -1068,6 +1187,7 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { ), returnValueForMissingStub: null, ); + @override _i11.Future install({required _i25.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -1079,6 +1199,7 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -1089,6 +1210,7 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -1098,6 +1220,7 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -1108,6 +1231,7 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { ), returnValue: _i11.Future.value(false), ) as _i11.Future); + @override _i11.Future> fetchThemes() => (super.noSuchMethod( @@ -1118,6 +1242,7 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { returnValue: _i11.Future>.value( <_i23.StackThemeMetaData>[]), ) as _i11.Future>); + @override _i11.Future<_i25.Uint8List> fetchTheme( {required _i23.StackThemeMetaData? themeMetaData}) => @@ -1129,6 +1254,7 @@ class MockThemeService extends _i1.Mock implements _i23.ThemeService { ), returnValue: _i11.Future<_i25.Uint8List>.value(_i25.Uint8List(0)), ) as _i11.Future<_i25.Uint8List>); + @override _i24.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( @@ -1154,6 +1280,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { Invocation.getter(#isar), ), ) as _i9.Isar); + @override _i11.Future initMainDB({_i9.Isar? mock}) => (super.noSuchMethod( Invocation.method( @@ -1163,6 +1290,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(false), ) as _i11.Future); + @override _i11.Future putWalletInfo(_i12.WalletInfo? walletInfo) => (super.noSuchMethod( @@ -1173,6 +1301,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future updateWalletInfo(_i12.WalletInfo? walletInfo) => (super.noSuchMethod( @@ -1183,6 +1312,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override List<_i26.ContactEntry> getContactEntries() => (super.noSuchMethod( Invocation.method( @@ -1191,6 +1321,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: <_i26.ContactEntry>[], ) as List<_i26.ContactEntry>); + @override _i11.Future deleteContactEntry({required String? id}) => (super.noSuchMethod( @@ -1201,6 +1332,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(false), ) as _i11.Future); + @override _i11.Future isContactEntryExists({required String? id}) => (super.noSuchMethod( @@ -1211,6 +1343,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(false), ) as _i11.Future); + @override _i26.ContactEntry? getContactEntry({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -1218,6 +1351,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { [], {#id: id}, )) as _i26.ContactEntry?); + @override _i11.Future putContactEntry( {required _i26.ContactEntry? contactEntry}) => @@ -1229,6 +1363,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(false), ) as _i11.Future); + @override _i27.TransactionBlockExplorer? getTransactionBlockExplorer( {required _i4.CryptoCurrency? cryptoCurrency}) => @@ -1237,6 +1372,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { [], {#cryptoCurrency: cryptoCurrency}, )) as _i27.TransactionBlockExplorer?); + @override _i11.Future putTransactionBlockExplorer( _i27.TransactionBlockExplorer? explorer) => @@ -1247,6 +1383,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(0), ) as _i11.Future); + @override _i9.QueryBuilder<_i28.Address, _i28.Address, _i9.QAfterWhereClause> getAddresses(String? walletId) => (super.noSuchMethod( @@ -1264,6 +1401,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), ) as _i9 .QueryBuilder<_i28.Address, _i28.Address, _i9.QAfterWhereClause>); + @override _i11.Future putAddress(_i28.Address? address) => (super.noSuchMethod( Invocation.method( @@ -1272,6 +1410,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(0), ) as _i11.Future); + @override _i11.Future> putAddresses(List<_i28.Address>? addresses) => (super.noSuchMethod( @@ -1281,6 +1420,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future>.value([]), ) as _i11.Future>); + @override _i11.Future> updateOrPutAddresses(List<_i28.Address>? addresses) => (super.noSuchMethod( @@ -1290,6 +1430,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future>.value([]), ) as _i11.Future>); + @override _i11.Future<_i28.Address?> getAddress( String? walletId, @@ -1305,6 +1446,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future<_i28.Address?>.value(), ) as _i11.Future<_i28.Address?>); + @override _i11.Future updateAddress( _i28.Address? oldAddress, @@ -1320,6 +1462,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(0), ) as _i11.Future); + @override _i9.QueryBuilder<_i28.Transaction, _i28.Transaction, _i9.QAfterWhereClause> getTransactions(String? walletId) => (super.noSuchMethod( @@ -1337,6 +1480,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), ) as _i9.QueryBuilder<_i28.Transaction, _i28.Transaction, _i9.QAfterWhereClause>); + @override _i11.Future putTransaction(_i28.Transaction? transaction) => (super.noSuchMethod( @@ -1346,6 +1490,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(0), ) as _i11.Future); + @override _i11.Future> putTransactions( List<_i28.Transaction>? transactions) => @@ -1356,6 +1501,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future>.value([]), ) as _i11.Future>); + @override _i11.Future<_i28.Transaction?> getTransaction( String? walletId, @@ -1371,6 +1517,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future<_i28.Transaction?>.value(), ) as _i11.Future<_i28.Transaction?>); + @override _i11.Stream<_i28.Transaction?> watchTransaction({ required int? id, @@ -1387,6 +1534,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Stream<_i28.Transaction?>.empty(), ) as _i11.Stream<_i28.Transaction?>); + @override _i9.QueryBuilder<_i28.UTXO, _i28.UTXO, _i9.QAfterWhereClause> getUTXOs( String? walletId) => @@ -1404,6 +1552,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), ), ) as _i9.QueryBuilder<_i28.UTXO, _i28.UTXO, _i9.QAfterWhereClause>); + @override _i9.QueryBuilder<_i28.UTXO, _i28.UTXO, _i9.QAfterFilterCondition> getUTXOsByAddress( @@ -1431,6 +1580,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), ) as _i9 .QueryBuilder<_i28.UTXO, _i28.UTXO, _i9.QAfterFilterCondition>); + @override _i11.Future putUTXO(_i28.UTXO? utxo) => (super.noSuchMethod( Invocation.method( @@ -1440,6 +1590,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future putUTXOs(List<_i28.UTXO>? utxos) => (super.noSuchMethod( Invocation.method( @@ -1449,6 +1600,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future updateUTXOs( String? walletId, @@ -1464,6 +1616,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(false), ) as _i11.Future); + @override _i11.Stream<_i28.UTXO?> watchUTXO({ required int? id, @@ -1480,6 +1633,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Stream<_i28.UTXO?>.empty(), ) as _i11.Stream<_i28.UTXO?>); + @override _i9.QueryBuilder<_i28.TransactionNote, _i28.TransactionNote, _i9.QAfterWhereClause> getTransactionNotes( @@ -1499,6 +1653,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), ) as _i9.QueryBuilder<_i28.TransactionNote, _i28.TransactionNote, _i9.QAfterWhereClause>); + @override _i11.Future putTransactionNote(_i28.TransactionNote? transactionNote) => (super.noSuchMethod( @@ -1509,6 +1664,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future putTransactionNotes( List<_i28.TransactionNote>? transactionNotes) => @@ -1520,6 +1676,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future<_i28.TransactionNote?> getTransactionNote( String? walletId, @@ -1535,6 +1692,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future<_i28.TransactionNote?>.value(), ) as _i11.Future<_i28.TransactionNote?>); + @override _i11.Stream<_i28.TransactionNote?> watchTransactionNote({ required int? id, @@ -1551,6 +1709,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Stream<_i28.TransactionNote?>.empty(), ) as _i11.Stream<_i28.TransactionNote?>); + @override _i9.QueryBuilder<_i28.AddressLabel, _i28.AddressLabel, _i9.QAfterWhereClause> getAddressLabels(String? walletId) => (super.noSuchMethod( @@ -1568,6 +1727,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), ) as _i9.QueryBuilder<_i28.AddressLabel, _i28.AddressLabel, _i9.QAfterWhereClause>); + @override _i11.Future putAddressLabel(_i28.AddressLabel? addressLabel) => (super.noSuchMethod( @@ -1577,6 +1737,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(0), ) as _i11.Future); + @override int putAddressLabelSync(_i28.AddressLabel? addressLabel) => (super.noSuchMethod( @@ -1586,6 +1747,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: 0, ) as int); + @override _i11.Future putAddressLabels(List<_i28.AddressLabel>? addressLabels) => (super.noSuchMethod( @@ -1596,6 +1758,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future<_i28.AddressLabel?> getAddressLabel( String? walletId, @@ -1611,6 +1774,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future<_i28.AddressLabel?>.value(), ) as _i11.Future<_i28.AddressLabel?>); + @override _i28.AddressLabel? getAddressLabelSync( String? walletId, @@ -1623,6 +1787,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { addressString, ], )) as _i28.AddressLabel?); + @override _i11.Stream<_i28.AddressLabel?> watchAddressLabel({ required int? id, @@ -1639,6 +1804,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Stream<_i28.AddressLabel?>.empty(), ) as _i11.Stream<_i28.AddressLabel?>); + @override _i11.Future updateAddressLabel(_i28.AddressLabel? addressLabel) => (super.noSuchMethod( @@ -1648,6 +1814,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(0), ) as _i11.Future); + @override _i11.Future deleteWalletBlockchainData(String? walletId) => (super.noSuchMethod( @@ -1658,6 +1825,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future deleteAddressLabels(String? walletId) => (super.noSuchMethod( @@ -1668,6 +1836,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future deleteTransactionNotes(String? walletId) => (super.noSuchMethod( @@ -1678,6 +1847,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future addNewTransactionData( List<_i7.Tuple2<_i28.Transaction, _i28.Address?>>? transactionsData, @@ -1694,6 +1864,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future> updateOrPutTransactionV2s( List<_i29.TransactionV2>? transactions) => @@ -1704,6 +1875,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future>.value([]), ) as _i11.Future>); + @override _i9.QueryBuilder<_i28.EthContract, _i28.EthContract, _i9.QWhere> getEthContracts() => (super.noSuchMethod( @@ -1721,6 +1893,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), ) as _i9 .QueryBuilder<_i28.EthContract, _i28.EthContract, _i9.QWhere>); + @override _i11.Future<_i28.EthContract?> getEthContract(String? contractAddress) => (super.noSuchMethod( @@ -1730,12 +1903,14 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future<_i28.EthContract?>.value(), ) as _i11.Future<_i28.EthContract?>); + @override _i28.EthContract? getEthContractSync(String? contractAddress) => (super.noSuchMethod(Invocation.method( #getEthContractSync, [contractAddress], )) as _i28.EthContract?); + @override _i11.Future putEthContract(_i28.EthContract? contract) => (super.noSuchMethod( @@ -1745,6 +1920,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { ), returnValue: _i11.Future.value(0), ) as _i11.Future); + @override _i11.Future putEthContracts(List<_i28.EthContract>? contracts) => (super.noSuchMethod( @@ -1755,6 +1931,7 @@ class MockMainDB extends _i1.Mock implements _i3.MainDB { returnValue: _i11.Future.value(), returnValueForMissingStub: _i11.Future.value(), ) as _i11.Future); + @override _i11.Future getHighestUsedMintIndex({required String? walletId}) => (super.noSuchMethod( @@ -1783,6 +1960,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#bellNew), ), ) as String); + @override String get buy => (super.noSuchMethod( Invocation.getter(#buy), @@ -1791,6 +1969,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#buy), ), ) as String); + @override String get exchange => (super.noSuchMethod( Invocation.getter(#exchange), @@ -1799,6 +1978,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#exchange), ), ) as String); + @override String get personaIncognito => (super.noSuchMethod( Invocation.getter(#personaIncognito), @@ -1807,6 +1987,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#personaIncognito), ), ) as String); + @override String get personaEasy => (super.noSuchMethod( Invocation.getter(#personaEasy), @@ -1815,6 +1996,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#personaEasy), ), ) as String); + @override String get stack => (super.noSuchMethod( Invocation.getter(#stack), @@ -1823,6 +2005,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#stack), ), ) as String); + @override String get stackIcon => (super.noSuchMethod( Invocation.getter(#stackIcon), @@ -1831,6 +2014,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#stackIcon), ), ) as String); + @override String get receive => (super.noSuchMethod( Invocation.getter(#receive), @@ -1839,6 +2023,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#receive), ), ) as String); + @override String get receivePending => (super.noSuchMethod( Invocation.getter(#receivePending), @@ -1847,6 +2032,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#receivePending), ), ) as String); + @override String get receiveCancelled => (super.noSuchMethod( Invocation.getter(#receiveCancelled), @@ -1855,6 +2041,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#receiveCancelled), ), ) as String); + @override String get send => (super.noSuchMethod( Invocation.getter(#send), @@ -1863,6 +2050,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#send), ), ) as String); + @override String get sendPending => (super.noSuchMethod( Invocation.getter(#sendPending), @@ -1871,6 +2059,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#sendPending), ), ) as String); + @override String get sendCancelled => (super.noSuchMethod( Invocation.getter(#sendCancelled), @@ -1879,6 +2068,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#sendCancelled), ), ) as String); + @override String get themeSelector => (super.noSuchMethod( Invocation.getter(#themeSelector), @@ -1887,6 +2077,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#themeSelector), ), ) as String); + @override String get themePreview => (super.noSuchMethod( Invocation.getter(#themePreview), @@ -1895,6 +2086,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#themePreview), ), ) as String); + @override String get txExchange => (super.noSuchMethod( Invocation.getter(#txExchange), @@ -1903,6 +2095,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#txExchange), ), ) as String); + @override String get txExchangePending => (super.noSuchMethod( Invocation.getter(#txExchangePending), @@ -1911,6 +2104,7 @@ class MockIThemeAssets extends _i1.Mock implements _i24.IThemeAssets { Invocation.getter(#txExchangePending), ), ) as String); + @override String get txExchangeFailed => (super.noSuchMethod( Invocation.getter(#txExchangeFailed), diff --git a/test/widget_tests/wallet_card_test.mocks.dart b/test/widget_tests/wallet_card_test.mocks.dart index 1c8afe8db..80c03af35 100644 --- a/test/widget_tests/wallet_card_test.mocks.dart +++ b/test/widget_tests/wallet_card_test.mocks.dart @@ -94,6 +94,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { Invocation.getter(#nodeService), ), ) as _i2.NodeService); + @override set nodeService(_i2.NodeService? _nodeService) => super.noSuchMethod( Invocation.setter( @@ -102,6 +103,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get mainDB => (super.noSuchMethod( Invocation.getter(#mainDB), @@ -110,6 +112,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { Invocation.getter(#mainDB), ), ) as _i3.MainDB); + @override set mainDB(_i3.MainDB? _mainDB) => super.noSuchMethod( Invocation.setter( @@ -118,11 +121,13 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), returnValueForMissingStub: null, ); + @override List<_i5.Wallet<_i4.CryptoCurrency>> get wallets => (super.noSuchMethod( Invocation.getter(#wallets), returnValue: <_i5.Wallet<_i4.CryptoCurrency>>[], ) as List<_i5.Wallet<_i4.CryptoCurrency>>); + @override _i5.Wallet<_i4.CryptoCurrency> getWallet(String? walletId) => (super.noSuchMethod( @@ -138,6 +143,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), ), ) as _i5.Wallet<_i4.CryptoCurrency>); + @override void addWallet(_i5.Wallet<_i4.CryptoCurrency>? wallet) => super.noSuchMethod( Invocation.method( @@ -146,6 +152,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), returnValueForMissingStub: null, ); + @override _i8.Future deleteWallet( _i9.WalletInfo? info, @@ -162,6 +169,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future load( _i11.Prefs? prefs, @@ -178,6 +186,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future loadAfterStackRestore( _i11.Prefs? prefs, @@ -214,11 +223,13 @@ class MockLocaleService extends _i1.Mock implements _i12.LocaleService { Invocation.getter(#locale), ), ) as String); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i8.Future loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( @@ -229,6 +240,7 @@ class MockLocaleService extends _i1.Mock implements _i12.LocaleService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -237,6 +249,7 @@ class MockLocaleService extends _i1.Mock implements _i12.LocaleService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -245,6 +258,7 @@ class MockLocaleService extends _i1.Mock implements _i12.LocaleService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -253,6 +267,7 @@ class MockLocaleService extends _i1.Mock implements _i12.LocaleService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( @@ -279,6 +294,7 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { Invocation.getter(#client), ), ) as _i6.HTTP); + @override set client(_i6.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -287,6 +303,7 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -295,11 +312,13 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i16.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i16.StackTheme>[], ) as List<_i16.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -308,6 +327,7 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { ), returnValueForMissingStub: null, ); + @override _i8.Future install({required _i17.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -319,6 +339,7 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -329,6 +350,7 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -338,6 +360,7 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -348,6 +371,7 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { ), returnValue: _i8.Future.value(false), ) as _i8.Future); + @override _i8.Future> fetchThemes() => (super.noSuchMethod( @@ -358,6 +382,7 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { returnValue: _i8.Future>.value( <_i15.StackThemeMetaData>[]), ) as _i8.Future>); + @override _i8.Future<_i17.Uint8List> fetchTheme( {required _i15.StackThemeMetaData? themeMetaData}) => @@ -369,6 +394,7 @@ class MockThemeService extends _i1.Mock implements _i15.ThemeService { ), returnValue: _i8.Future<_i17.Uint8List>.value(_i17.Uint8List(0)), ) as _i8.Future<_i17.Uint8List>); + @override _i16.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( diff --git a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart index 2084bd833..d7fea45d4 100644 --- a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart +++ b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart @@ -90,6 +90,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { Invocation.getter(#nodeService), ), ) as _i2.NodeService); + @override set nodeService(_i2.NodeService? _nodeService) => super.noSuchMethod( Invocation.setter( @@ -98,6 +99,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get mainDB => (super.noSuchMethod( Invocation.getter(#mainDB), @@ -106,6 +108,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { Invocation.getter(#mainDB), ), ) as _i3.MainDB); + @override set mainDB(_i3.MainDB? _mainDB) => super.noSuchMethod( Invocation.setter( @@ -114,11 +117,13 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), returnValueForMissingStub: null, ); + @override List<_i5.Wallet<_i4.CryptoCurrency>> get wallets => (super.noSuchMethod( Invocation.getter(#wallets), returnValue: <_i5.Wallet<_i4.CryptoCurrency>>[], ) as List<_i5.Wallet<_i4.CryptoCurrency>>); + @override _i5.Wallet<_i4.CryptoCurrency> getWallet(String? walletId) => (super.noSuchMethod( @@ -134,6 +139,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), ), ) as _i5.Wallet<_i4.CryptoCurrency>); + @override void addWallet(_i5.Wallet<_i4.CryptoCurrency>? wallet) => super.noSuchMethod( Invocation.method( @@ -142,6 +148,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { ), returnValueForMissingStub: null, ); + @override _i8.Future deleteWallet( _i9.WalletInfo? info, @@ -158,6 +165,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future load( _i10.Prefs? prefs, @@ -174,6 +182,7 @@ class MockWallets extends _i1.Mock implements _i7.Wallets { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future loadAfterStackRestore( _i10.Prefs? prefs, @@ -210,21 +219,25 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i6.SecureStorageInterface); + @override List<_i11.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i11.NodeModel>[], ) as List<_i11.NodeModel>); + @override List<_i11.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i11.NodeModel>[], ) as List<_i11.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i8.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -234,6 +247,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future setPrimaryNodeFor({ required _i4.CryptoCurrency? coin, @@ -253,6 +267,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i11.NodeModel? getPrimaryNodeFor({required _i4.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -260,6 +275,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#currency: currency}, )) as _i11.NodeModel?); + @override List<_i11.NodeModel> getNodesFor(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -269,6 +285,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i11.NodeModel>[], ) as List<_i11.NodeModel>); + @override _i11.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -276,6 +293,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#id: id}, )) as _i11.NodeModel?); + @override List<_i11.NodeModel> failoverNodesFor( {required _i4.CryptoCurrency? currency}) => @@ -287,6 +305,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i11.NodeModel>[], ) as List<_i11.NodeModel>); + @override _i8.Future add( _i11.NodeModel? node, @@ -305,6 +324,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future delete( String? id, @@ -321,6 +341,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future setEnabledState( String? id, @@ -339,6 +360,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future edit( _i11.NodeModel? editedNode, @@ -357,6 +379,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override _i8.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -366,6 +389,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i8.Future.value(), returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override void addListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -374,6 +398,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i12.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -382,6 +407,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -390,6 +416,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart b/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart index 057284d51..88f854589 100644 --- a/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart +++ b/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart @@ -104,6 +104,7 @@ class MockWallets extends _i1.Mock implements _i8.Wallets { Invocation.getter(#nodeService), ), ) as _i2.NodeService); + @override set nodeService(_i2.NodeService? _nodeService) => super.noSuchMethod( Invocation.setter( @@ -112,6 +113,7 @@ class MockWallets extends _i1.Mock implements _i8.Wallets { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get mainDB => (super.noSuchMethod( Invocation.getter(#mainDB), @@ -120,6 +122,7 @@ class MockWallets extends _i1.Mock implements _i8.Wallets { Invocation.getter(#mainDB), ), ) as _i3.MainDB); + @override set mainDB(_i3.MainDB? _mainDB) => super.noSuchMethod( Invocation.setter( @@ -128,11 +131,13 @@ class MockWallets extends _i1.Mock implements _i8.Wallets { ), returnValueForMissingStub: null, ); + @override List<_i5.Wallet<_i4.CryptoCurrency>> get wallets => (super.noSuchMethod( Invocation.getter(#wallets), returnValue: <_i5.Wallet<_i4.CryptoCurrency>>[], ) as List<_i5.Wallet<_i4.CryptoCurrency>>); + @override _i5.Wallet<_i4.CryptoCurrency> getWallet(String? walletId) => (super.noSuchMethod( @@ -148,6 +153,7 @@ class MockWallets extends _i1.Mock implements _i8.Wallets { ), ), ) as _i5.Wallet<_i4.CryptoCurrency>); + @override void addWallet(_i5.Wallet<_i4.CryptoCurrency>? wallet) => super.noSuchMethod( Invocation.method( @@ -156,6 +162,7 @@ class MockWallets extends _i1.Mock implements _i8.Wallets { ), returnValueForMissingStub: null, ); + @override _i9.Future deleteWallet( _i10.WalletInfo? info, @@ -172,6 +179,7 @@ class MockWallets extends _i1.Mock implements _i8.Wallets { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future load( _i11.Prefs? prefs, @@ -188,6 +196,7 @@ class MockWallets extends _i1.Mock implements _i8.Wallets { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future loadAfterStackRestore( _i11.Prefs? prefs, @@ -224,6 +233,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { Invocation.getter(#client), ), ) as _i6.HTTP); + @override set client(_i6.HTTP? _client) => super.noSuchMethod( Invocation.setter( @@ -232,6 +242,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { ), returnValueForMissingStub: null, ); + @override _i3.MainDB get db => (super.noSuchMethod( Invocation.getter(#db), @@ -240,11 +251,13 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { Invocation.getter(#db), ), ) as _i3.MainDB); + @override List<_i13.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), returnValue: <_i13.StackTheme>[], ) as List<_i13.StackTheme>); + @override void init(_i3.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -253,6 +266,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { ), returnValueForMissingStub: null, ); + @override _i9.Future install({required _i14.Uint8List? themeArchiveData}) => (super.noSuchMethod( @@ -264,6 +278,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( @@ -274,6 +289,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( @@ -283,6 +299,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future verifyInstalled({required String? themeId}) => (super.noSuchMethod( @@ -293,6 +310,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { ), returnValue: _i9.Future.value(false), ) as _i9.Future); + @override _i9.Future> fetchThemes() => (super.noSuchMethod( @@ -303,6 +321,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { returnValue: _i9.Future>.value( <_i12.StackThemeMetaData>[]), ) as _i9.Future>); + @override _i9.Future<_i14.Uint8List> fetchTheme( {required _i12.StackThemeMetaData? themeMetaData}) => @@ -314,6 +333,7 @@ class MockThemeService extends _i1.Mock implements _i12.ThemeService { ), returnValue: _i9.Future<_i14.Uint8List>.value(_i14.Uint8List(0)), ) as _i9.Future<_i14.Uint8List>); + @override _i13.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( @@ -339,21 +359,25 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { Invocation.getter(#secureStorageInterface), ), ) as _i7.SecureStorageInterface); + @override List<_i15.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), returnValue: <_i15.NodeModel>[], ) as List<_i15.NodeModel>); + @override List<_i15.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), returnValue: <_i15.NodeModel>[], ) as List<_i15.NodeModel>); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); + @override _i9.Future updateDefaults() => (super.noSuchMethod( Invocation.method( @@ -363,6 +387,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future setPrimaryNodeFor({ required _i4.CryptoCurrency? coin, @@ -382,6 +407,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i15.NodeModel? getPrimaryNodeFor({required _i4.CryptoCurrency? currency}) => (super.noSuchMethod(Invocation.method( @@ -389,6 +415,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#currency: currency}, )) as _i15.NodeModel?); + @override List<_i15.NodeModel> getNodesFor(_i4.CryptoCurrency? coin) => (super.noSuchMethod( @@ -398,6 +425,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i15.NodeModel>[], ) as List<_i15.NodeModel>); + @override _i15.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( @@ -405,6 +433,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { [], {#id: id}, )) as _i15.NodeModel?); + @override List<_i15.NodeModel> failoverNodesFor( {required _i4.CryptoCurrency? currency}) => @@ -416,6 +445,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValue: <_i15.NodeModel>[], ) as List<_i15.NodeModel>); + @override _i9.Future add( _i15.NodeModel? node, @@ -434,6 +464,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future delete( String? id, @@ -450,6 +481,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future setEnabledState( String? id, @@ -468,6 +500,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future edit( _i15.NodeModel? editedNode, @@ -486,6 +519,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override _i9.Future updateCommunityNodes() => (super.noSuchMethod( Invocation.method( @@ -495,6 +529,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { returnValue: _i9.Future.value(), returnValueForMissingStub: _i9.Future.value(), ) as _i9.Future); + @override void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -503,6 +538,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method( @@ -511,6 +547,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void dispose() => super.noSuchMethod( Invocation.method( @@ -519,6 +556,7 @@ class MockNodeService extends _i1.Mock implements _i2.NodeService { ), returnValueForMissingStub: null, ); + @override void notifyListeners() => super.noSuchMethod( Invocation.method( diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index bf62d9b0c..74ef33c4e 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -8,10 +8,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -24,6 +26,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("CameraWindows")); ConnectivityPlusWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); + CsMoneroFlutterLibsWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("CsMoneroFlutterLibsWindowsPluginCApi")); DesktopDropPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("DesktopDropPlugin")); FlutterLibepiccashPluginCApiRegisterWithRegistrar( @@ -32,6 +36,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); IsarFlutterLibsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin")); + LocalAuthPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("LocalAuthPlugin")); PermissionHandlerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); SharePlusWindowsPluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index d5305699e..2f370e685 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -5,10 +5,12 @@ list(APPEND FLUTTER_PLUGIN_LIST camera_windows connectivity_plus + cs_monero_flutter_libs_windows desktop_drop flutter_libepiccash flutter_secure_storage_windows isar_flutter_libs + local_auth_windows permission_handler_windows share_plus sqlite3_flutter_libs