diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4638e84dd..01cd71173 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -23,6 +23,7 @@ jobs: run: | cargo install cargo-ndk rustup target add x86_64-unknown-linux-gnu + sudo apt clean sudo apt update sudo apt install -y unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake openjdk-8-jre-headless libgit2-dev clang libncurses5-dev libncursesw5-dev zlib1g-dev llvm sudo apt install -y debhelper libclang-dev cargo rustc opencl-headers libssl-dev ocl-icd-opencl-dev diff --git a/assets/images/unclaimed.png b/assets/images/unclaimed.png new file mode 100644 index 000000000..f99d4ab2a Binary files /dev/null and b/assets/images/unclaimed.png differ diff --git a/assets/svg/fruitSorbet/buy-coins-icon.svg b/assets/svg/fruitSorbet/buy-coins-icon.svg index 5788e2bf0..63b214e40 100644 --- a/assets/svg/fruitSorbet/buy-coins-icon.svg +++ b/assets/svg/fruitSorbet/buy-coins-icon.svg @@ -1,11 +1,18 @@ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_908_22491)"> <g opacity="0.4"> -<path d="M22.2 6C23.3297 5.37187 24 4.59422 24 3.75C24 1.67906 19.9688 0 15 0C9.98906 0 6 1.67906 6 3.75C6 4.59422 6.67031 5.37187 7.8 6C7.80937 6.00469 7.81758 6.00937 7.82578 6.01406C7.83398 6.01875 7.84219 6.02344 7.85156 6.02813C8.23125 6.00938 8.61094 6 9 6C11.6344 6 14.0906 6.44062 15.9422 7.21406C16.1203 7.28906 16.2984 7.36875 16.4672 7.44844C18.8062 7.28906 20.8359 6.75469 22.2 6Z" fill="#232323"/> -<path d="M19.9435 12.9151C19.7958 12.9551 19.6477 12.9951 19.5 13.0359V13.5C20.7602 13.5 21.9296 13.8885 22.8951 14.5522C23.5995 14.0172 24 13.4028 24 12.75V11.0906C23.4141 11.5734 22.7063 11.9672 21.9422 12.2859C21.3382 12.5376 20.6447 12.7253 19.9435 12.9151Z" fill="#232323"/> -<path d="M18.3703 8.74688C19.0031 9.37969 19.5 10.2234 19.5 11.25V11.4984C20.4328 11.2734 21.2625 10.9781 21.9469 10.6359C21.9739 10.6209 22.0009 10.6021 22.0279 10.5833C22.0852 10.5432 22.1426 10.5032 22.2 10.5C23.3297 9.87187 24 9.09375 24 8.25V6.59063C23.4141 7.07344 22.7063 7.46719 21.9422 7.78594C20.9109 8.2125 19.6969 8.54063 18.3703 8.74688Z" fill="#232323"/> +<path d="M22.2 6C23.3297 5.37187 24 4.59422 24 3.75C24 1.67906 19.9688 0 15 0C9.98906 0 6 1.67906 6 3.75C6 4.59422 6.67031 5.37187 7.8 6C7.80937 6.00469 7.81758 6.00937 7.82578 6.01406C7.83398 6.01875 7.84219 6.02344 7.85156 6.02813C8.23125 6.00938 8.61094 6 9 6C11.6344 6 14.0906 6.44062 15.9422 7.21406C16.1203 7.28906 16.2984 7.36875 16.4672 7.44844C18.8062 7.28906 20.8359 6.75469 22.2 6Z" fill="#D12B41"/> +<path d="M19.9435 12.9151C19.7958 12.9551 19.6477 12.9951 19.5 13.0359V13.5C20.7602 13.5 21.9296 13.8885 22.8951 14.5522C23.5995 14.0172 24 13.4028 24 12.75V11.0906C23.4141 11.5734 22.7063 11.9672 21.9422 12.2859C21.3382 12.5376 20.6447 12.7253 19.9435 12.9151Z" fill="#D12B41"/> +<path d="M18.3703 8.74688C19.0031 9.37969 19.5 10.2234 19.5 11.25V11.4984C20.4328 11.2734 21.2625 10.9781 21.9469 10.6359C21.9739 10.6209 22.0009 10.6021 22.0279 10.5833C22.0852 10.5432 22.1426 10.5032 22.2 10.5C23.3297 9.87187 24 9.09375 24 8.25V6.59063C23.4141 7.07344 22.7063 7.46719 21.9422 7.78594C20.9109 8.2125 19.6969 8.54063 18.3703 8.74688Z" fill="#D12B41"/> </g> -<path d="M16.2 13.5C17.3297 12.8719 18 12.0938 18 11.25C18 9.17813 13.9688 7.5 9 7.5C4.02938 7.5 0 9.17813 0 11.25C0 12.0938 0.669375 12.8719 1.79953 13.5C1.85443 13.5031 1.91057 13.5415 1.96782 13.5807C1.9966 13.6004 2.02567 13.6203 2.055 13.6359C3.70594 14.4703 6.20625 15 9 15C11.9438 15 14.5594 14.4094 16.2 13.5Z" fill="#232323"/> -<path d="M14.8788 15.6729C13.1948 16.2046 11.1571 16.5 9 16.5C6.36562 16.5 3.91125 16.0594 2.05922 15.2859C1.29469 14.9672 0.583594 14.5734 0 14.0906V15.75C0 16.5938 0.669375 17.3719 1.79953 18C3.44109 18.9094 6.05625 19.5 9 19.5C10.6471 19.5 12.1916 19.3159 13.5211 18.9937C13.6261 17.7367 14.1186 16.5898 14.8788 15.6729Z" fill="#232323"/> -<path d="M13.5862 20.5191C13.7529 21.4936 14.1547 22.3879 14.731 23.1415C13.1742 23.6778 11.1771 24 9 24C4.02938 24 0 22.3219 0 20.25V18.5906C0.583594 19.0734 1.29469 19.4672 2.05922 19.7859C3.91125 20.5594 6.36562 21 9 21C10.6307 21 12.1932 20.8312 13.5862 20.5191Z" fill="#232323"/> -<path d="M24 19.5C24 21.9844 21.9844 24 19.5 24C17.0156 24 15 21.9844 15 19.5C15 17.0156 17.0156 15 19.5 15C21.9844 15 24 17.0156 24 19.5ZM19 17.4719V18.9719H17.5C17.225 18.9719 17 19.225 17 19.4719C17 19.775 17.225 19.9719 17.5 19.9719H19V21.4719C19 21.775 19.225 21.9719 19.5 21.9719C19.775 21.9719 20 21.775 20 21.4719V19.9719H21.5C21.775 19.9719 22 19.775 22 19.4719C22 19.225 21.775 18.9719 21.5 18.9719H20V17.4719C20 17.225 19.775 16.9719 19.5 16.9719C19.225 16.9719 19 17.225 19 17.4719Z" fill="#232323"/> +<path d="M16.2 13.5C17.3297 12.8719 18 12.0938 18 11.25C18 9.17813 13.9688 7.5 9 7.5C4.02938 7.5 0 9.17813 0 11.25C0 12.0938 0.669375 12.8719 1.79953 13.5C1.85443 13.5031 1.91057 13.5415 1.96782 13.5807C1.9966 13.6004 2.02567 13.6203 2.055 13.6359C3.70594 14.4703 6.20625 15 9 15C11.9438 15 14.5594 14.4094 16.2 13.5Z" fill="#D12B41"/> +<path d="M14.8788 15.6729C13.1948 16.2046 11.1571 16.5 9 16.5C6.36562 16.5 3.91125 16.0594 2.05922 15.2859C1.29469 14.9672 0.583594 14.5734 0 14.0906V15.75C0 16.5938 0.669375 17.3719 1.79953 18C3.44109 18.9094 6.05625 19.5 9 19.5C10.6471 19.5 12.1916 19.3159 13.5211 18.9937C13.6261 17.7367 14.1186 16.5898 14.8788 15.6729Z" fill="#D12B41"/> +<path d="M13.5862 20.5191C13.7529 21.4936 14.1547 22.3879 14.731 23.1415C13.1742 23.6778 11.1771 24 9 24C4.02938 24 0 22.3219 0 20.25V18.5906C0.583594 19.0734 1.29469 19.4672 2.05922 19.7859C3.91125 20.5594 6.36562 21 9 21C10.6307 21 12.1932 20.8312 13.5862 20.5191Z" fill="#D12B41"/> +<path d="M24 19.5C24 21.9844 21.9844 24 19.5 24C17.0156 24 15 21.9844 15 19.5C15 17.0156 17.0156 15 19.5 15C21.9844 15 24 17.0156 24 19.5ZM19 17.4719V18.9719H17.5C17.225 18.9719 17 19.225 17 19.4719C17 19.775 17.225 19.9719 17.5 19.9719H19V21.4719C19 21.775 19.225 21.9719 19.5 21.9719C19.775 21.9719 20 21.775 20 21.4719V19.9719H21.5C21.775 19.9719 22 19.775 22 19.4719C22 19.225 21.775 18.9719 21.5 18.9719H20V17.4719C20 17.225 19.775 16.9719 19.5 16.9719C19.225 16.9719 19 17.225 19 17.4719Z" fill="#D12B41"/> +</g> +<defs> +<clipPath id="clip0_908_22491"> +<rect width="24" height="24" fill="white"/> +</clipPath> +</defs> </svg> diff --git a/assets/svg/fruitSorbet/exchange-2.svg b/assets/svg/fruitSorbet/exchange-2.svg index 11e246a3b..0310a3386 100644 --- a/assets/svg/fruitSorbet/exchange-2.svg +++ b/assets/svg/fruitSorbet/exchange-2.svg @@ -1,4 +1,4 @@ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M14.6695 1.06575C15.1855 0.607104 15.9756 0.65358 16.4343 1.16956L20.4343 5.66956C20.8552 6.14317 20.8552 6.85686 20.4343 7.33047L16.4343 11.8305C15.9756 12.3464 15.1855 12.3929 14.6695 11.9343C14.1536 11.4756 14.1071 10.6855 14.5657 10.1696L16.7164 7.75001H6C4.48122 7.75001 3.25 8.98123 3.25 10.5C3.25 11.1904 2.69036 11.75 2 11.75C1.30964 11.75 0.75 11.1904 0.75 10.5C0.75 7.60052 3.10051 5.25001 6 5.25001H16.7164L14.5657 2.83047C14.1071 2.31449 14.1536 1.5244 14.6695 1.06575Z" fill="#232323"/> -<path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M9.33045 23.4342C8.81448 23.8929 8.02439 23.8464 7.56574 23.3304L3.56574 18.8304C3.14475 18.3568 3.14475 17.6431 3.56574 17.1695L7.56574 12.6695C8.02439 12.1536 8.81448 12.1071 9.33046 12.5657C9.84643 13.0244 9.89291 13.8145 9.43426 14.3304L7.28355 16.75L18 16.75C19.5188 16.75 20.75 15.5188 20.75 14C20.75 13.3096 21.3096 12.75 22 12.75C22.6904 12.75 23.25 13.3096 23.25 14C23.25 16.8995 20.8995 19.25 18 19.25L7.28355 19.25L9.43426 21.6695C9.89291 22.1855 9.84643 22.9756 9.33045 23.4342Z" fill="#232323"/> +<path d="M19.5 6.5H6C3.79086 6.5 2 8.29086 2 10.5M19.5 6.5L15.5 2M19.5 6.5L15.5 11" stroke="#D12B41" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/> +<path opacity="0.4" d="M4.5 18L18 18C20.2091 18 22 16.2091 22 14M4.5 18L8.5 22.5M4.5 18L8.5 13.5" stroke="#D12B41" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/> </svg> diff --git a/assets/svg/robot-head.svg b/assets/svg/robot-head.svg new file mode 100644 index 000000000..b6810c227 --- /dev/null +++ b/assets/svg/robot-head.svg @@ -0,0 +1,3 @@ +<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M10.4173 5.41699V5.91699H10.9173H14.1257C15.1181 5.91699 15.9173 6.71825 15.9173 7.70866V15.5003C15.9173 16.2377 15.3213 16.8337 14.584 16.8337H5.41732C4.67997 16.8337 4.08398 16.2377 4.08398 15.5003V7.70866C4.08398 6.71866 4.88565 5.91699 5.87565 5.91699H9.08398H9.58398V5.41699V3.58366C9.58398 3.35506 9.77205 3.16699 10.0007 3.16699C10.2292 3.16699 10.4173 3.35506 10.4173 3.58366V5.41699ZM8.16732 15.0837H8.58398H8.66732H9.08398H10.9173H11.334H11.4173H11.834H13.6673H14.1673V14.5837V13.667V13.167H13.6673H11.834H11.4173H11.334H10.9173H9.08398H8.66732H8.58398H8.16732H6.33398H5.83398V13.667V14.5837V15.0837H6.33398H8.16732ZM1.33398 10.0003C1.33398 9.89019 1.37745 9.7852 1.45595 9.70663C1.53524 9.62741 1.64114 9.58366 1.75065 9.58366H2.16732V14.0837H1.75065C1.64023 14.0837 1.53452 14.0398 1.45609 13.9614C1.37774 13.8831 1.33398 13.7775 1.33398 13.667V10.0003ZM5.60482 10.0003C5.60482 10.9095 6.34144 11.6462 7.25065 11.6462C8.15987 11.6462 8.89648 10.9095 8.89648 10.0003C8.89648 9.09111 8.15987 8.35449 7.25065 8.35449C6.34144 8.35449 5.60482 9.09111 5.60482 10.0003ZM11.1048 10.0003C11.1048 10.9101 11.8409 11.6462 12.7507 11.6462C13.6599 11.6462 14.3965 10.9095 14.3965 10.0003C14.3965 9.09111 13.6599 8.35449 12.7507 8.35449C11.8416 8.35449 11.1048 9.09037 11.1048 10.0003ZM18.2507 9.58366C18.3599 9.58366 18.4652 9.62719 18.5445 9.70648C18.6238 9.78578 18.6673 9.89112 18.6673 10.0003V13.667C18.6673 13.7774 18.6235 13.8831 18.5451 13.9616C18.4667 14.0399 18.3612 14.0837 18.2507 14.0837H17.834V9.58366H18.2507Z" fill="#8E9192" stroke="#8E9192"/> +</svg> diff --git a/assets/svg/whirlpool.svg b/assets/svg/whirlpool.svg new file mode 100644 index 000000000..cf075308f --- /dev/null +++ b/assets/svg/whirlpool.svg @@ -0,0 +1,3 @@ +<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M6.16811 18.29C4.45149 18.089 3.04304 17.5064 1.84171 16.5006C1.52855 16.2383 1.08929 15.7904 0.868214 15.5078C0.795124 15.4144 0.815885 15.4205 1.16357 15.5943C2.17257 16.0986 3.56529 16.3941 4.67986 16.3404C5.4666 16.3025 6.00361 16.1827 6.16709 16.0087C6.30087 15.8663 6.24663 15.772 5.85013 15.458C4.68271 14.5333 3.91789 13.4633 3.48109 12.1436C2.95876 10.5655 3.03006 8.85291 3.68121 7.33745C3.85982 6.92178 4.22353 6.25056 4.46108 5.89825C5.0569 5.01461 6.02359 4.09702 7.04772 3.443C7.53459 3.13207 8.67134 2.57608 9.28978 2.34638C10.1175 2.03895 11.0493 1.81907 11.9322 1.72278C12.5152 1.6592 13.8654 1.6973 14.3766 1.79177C15.7252 2.04096 16.8058 2.50254 17.8199 3.26249C18.1679 3.52329 18.8273 4.15363 19.0478 4.43636L19.1673 4.58953L18.7556 4.39158C17.6907 3.87949 16.4125 3.60951 15.2969 3.66106C13.9736 3.72218 13.4271 3.9979 13.8908 4.37051C14.4654 4.83219 14.718 5.05501 14.9678 5.32051C16.047 6.46745 16.6696 7.8829 16.8049 9.49648C16.8912 10.527 16.6998 11.6803 16.2805 12.6564C15.6851 14.0423 14.7972 15.1697 13.573 16.0943C13.0338 16.5014 12.6196 16.756 11.9526 17.09C10.795 17.6696 9.68552 18.033 8.49122 18.2239C8.12694 18.2821 6.49683 18.3285 6.16811 18.29ZM10.567 12.7788C11.6493 12.5494 12.5288 11.6694 12.7584 10.586C12.824 10.2766 12.8238 9.72298 12.7584 9.41267C12.6408 8.85789 12.4049 8.43337 11.9758 8.00424C11.3957 7.42417 10.7838 7.17097 9.95841 7.16954C9.16291 7.16743 8.43295 7.4925 7.88801 8.0894C7.39072 8.63413 7.14979 9.25773 7.14979 10.0002C7.14979 10.8011 7.40895 11.4213 7.98385 11.9962C8.40667 12.419 8.83591 12.6598 9.37601 12.7773C9.67249 12.8418 10.2667 12.8425 10.5673 12.7794L10.567 12.7788Z" fill="#8E9192"/> +</svg> diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index 0309140a9..9a150d8cd 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit 0309140a95a51388df0effcc39ff0a25b2752b29 +Subproject commit 9a150d8cd2c3625424b0059e6b7306f3659fdbe0 diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index c1b403ccf..af88796d5 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit c1b403ccf6f4fffc9f7c233038c3df40f997c2b3 +Subproject commit af88796d5e4988c03422320c3842af5cf6c049ef diff --git a/lib/db/main_db.dart b/lib/db/main_db.dart index 413951e37..426e9f493 100644 --- a/lib/db/main_db.dart +++ b/lib/db/main_db.dart @@ -1,4 +1,6 @@ +import 'package:flutter/foundation.dart'; import 'package:isar/isar.dart'; +import 'package:stackwallet/exceptions/main_db/main_db_exception.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; import 'package:tuple/tuple.dart'; @@ -28,7 +30,7 @@ class MainDB { AddressSchema, ], directory: (await StackFileSystem.applicationIsarDirectory()).path, - inspector: false, + inspector: kDebugMode, name: "wallet_data", ); return true; @@ -39,39 +41,105 @@ class MainDB { String walletId) => isar.addresses.where().walletIdEqualTo(walletId); - Future<void> putAddress(Address address) => isar.writeTxn(() async { - await isar.addresses.put(address); + Future<int> putAddress(Address address) async { + try { + return await isar.writeTxn(() async { + return await isar.addresses.put(address); }); + } catch (e) { + throw MainDBException("failed putAddress: $address", e); + } + } - Future<void> putAddresses(List<Address> addresses) => isar.writeTxn(() async { - await isar.addresses.putAll(addresses); + Future<List<int>> putAddresses(List<Address> addresses) async { + try { + return await isar.writeTxn(() async { + return await isar.addresses.putAll(addresses); }); + } catch (e) { + throw MainDBException("failed putAddresses: $addresses", e); + } + } - Future<void> updateAddress(Address oldAddress, Address newAddress) => - isar.writeTxn(() async { + Future<List<int>> updateOrPutAddresses(List<Address> addresses) async { + try { + List<int> ids = []; + await isar.writeTxn(() async { + for (final address in addresses) { + final storedAddress = await isar.addresses + .getByValueWalletId(address.value, address.walletId); + + int id; + if (storedAddress == null) { + id = await isar.addresses.put(address); + } else { + address.id = storedAddress.id; + await storedAddress.transactions.load(); + final txns = storedAddress.transactions.toList(); + await isar.addresses.delete(storedAddress.id); + id = await isar.addresses.put(address); + address.transactions.addAll(txns); + await address.transactions.save(); + } + ids.add(id); + } + }); + return ids; + } catch (e) { + throw MainDBException("failed updateOrPutAddresses: $addresses", e); + } + } + + Future<Address?> getAddress(String walletId, String address) async { + return isar.addresses.getByValueWalletId(address, walletId); + } + + Future<int> updateAddress(Address oldAddress, Address newAddress) async { + try { + return await isar.writeTxn(() async { newAddress.id = oldAddress.id; await oldAddress.transactions.load(); final txns = oldAddress.transactions.toList(); await isar.addresses.delete(oldAddress.id); - await isar.addresses.put(newAddress); + final id = await isar.addresses.put(newAddress); newAddress.transactions.addAll(txns); await newAddress.transactions.save(); + return id; }); + } catch (e) { + throw MainDBException( + "failed updateAddress: from=$oldAddress to=$newAddress", e); + } + } // transactions QueryBuilder<Transaction, Transaction, QAfterWhereClause> getTransactions( String walletId) => isar.transactions.where().walletIdEqualTo(walletId); - Future<void> putTransaction(Transaction transaction) => - isar.writeTxn(() async { - await isar.transactions.put(transaction); + Future<int> putTransaction(Transaction transaction) async { + try { + return await isar.writeTxn(() async { + return await isar.transactions.put(transaction); }); + } catch (e) { + throw MainDBException("failed putTransaction: $transaction", e); + } + } - Future<void> putTransactions(List<Transaction> transactions) => - isar.writeTxn(() async { - await isar.transactions.putAll(transactions); + Future<List<int>> putTransactions(List<Transaction> transactions) async { + try { + return await isar.writeTxn(() async { + return await isar.transactions.putAll(transactions); }); + } catch (e) { + throw MainDBException("failed putTransactions: $transactions", e); + } + } + + Future<Transaction?> getTransaction(String walletId, String txid) async { + return isar.transactions.getByTxidWalletId(txid, walletId); + } // utxos QueryBuilder<UTXO, UTXO, QAfterWhereClause> getUTXOs(String walletId) => @@ -182,55 +250,60 @@ class MainDB { } Future<void> addNewTransactionData( - List<Tuple4<Transaction, List<Output>, List<Input>, Address?>> - transactionsData, - String walletId) async { - await isar.writeTxn(() async { - for (final data in transactionsData) { - final tx = data.item1; + List<Tuple4<Transaction, List<Output>, List<Input>, Address?>> + transactionsData, + String walletId, + ) async { + try { + await isar.writeTxn(() async { + for (final data in transactionsData) { + final tx = data.item1; - final potentiallyUnconfirmedTx = await getTransactions(walletId) - .filter() - .txidEqualTo(tx.txid) - .findFirst(); - if (potentiallyUnconfirmedTx != null) { - // update use id to replace tx - tx.id = potentiallyUnconfirmedTx.id; - await isar.transactions.delete(potentiallyUnconfirmedTx.id); - } - // save transaction - await isar.transactions.put(tx); - - // link and save outputs - if (data.item2.isNotEmpty) { - await isar.outputs.putAll(data.item2); - tx.outputs.addAll(data.item2); - await tx.outputs.save(); - } - - // link and save inputs - if (data.item3.isNotEmpty) { - await isar.inputs.putAll(data.item3); - tx.inputs.addAll(data.item3); - await tx.inputs.save(); - } - - if (data.item4 != null) { - final address = await getAddresses(walletId) + final potentiallyUnconfirmedTx = await getTransactions(walletId) .filter() - .valueEqualTo(data.item4!.value) + .txidEqualTo(tx.txid) .findFirst(); + if (potentiallyUnconfirmedTx != null) { + // update use id to replace tx + tx.id = potentiallyUnconfirmedTx.id; + await isar.transactions.delete(potentiallyUnconfirmedTx.id); + } + // save transaction + await isar.transactions.put(tx); - // check if address exists in db and add if it does not - if (address == null) { - await isar.addresses.put(data.item4!); + // link and save outputs + if (data.item2.isNotEmpty) { + await isar.outputs.putAll(data.item2); + tx.outputs.addAll(data.item2); + await tx.outputs.save(); } - // link and save address - tx.address.value = address ?? data.item4!; - await tx.address.save(); + // link and save inputs + if (data.item3.isNotEmpty) { + await isar.inputs.putAll(data.item3); + tx.inputs.addAll(data.item3); + await tx.inputs.save(); + } + + if (data.item4 != null) { + final address = await getAddresses(walletId) + .filter() + .valueEqualTo(data.item4!.value) + .findFirst(); + + // check if address exists in db and add if it does not + if (address == null) { + await isar.addresses.put(data.item4!); + } + + // link and save address + tx.address.value = address ?? data.item4!; + await tx.address.save(); + } } - } - }); + }); + } catch (e) { + throw MainDBException("failed addNewTransactionData", e); + } } } diff --git a/lib/electrumx_rpc/electrumx.dart b/lib/electrumx_rpc/electrumx.dart index c34b760e4..6667c3de5 100644 --- a/lib/electrumx_rpc/electrumx.dart +++ b/lib/electrumx_rpc/electrumx.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:decimal/decimal.dart'; import 'package:stackwallet/electrumx_rpc/rpc.dart'; +import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/prefs.dart'; import 'package:uuid/uuid.dart'; @@ -132,7 +133,17 @@ class ElectrumX { final response = await _rpcClient!.request(jsonRequestString); if (response["error"] != null) { - throw Exception("JSONRPC response error: $response"); + if (response["error"] + .toString() + .contains("No such mempool or blockchain transaction")) { + throw NoSuchTransactionException( + "No such mempool or blockchain transaction", + args.first.toString(), + ); + } + + throw Exception( + "JSONRPC response \ncommand: $command \nargs: $args \nerror: $response"); } currentFailoverIndex = -1; @@ -544,6 +555,10 @@ class ElectrumX { verbose, ], ); + if (!verbose) { + return {"rawtx": response["result"] as String}; + } + return Map<String, dynamic>.from(response["result"] as Map); } catch (e) { rethrow; diff --git a/lib/exceptions/address/address_exception.dart b/lib/exceptions/address/address_exception.dart new file mode 100644 index 000000000..3331bef99 --- /dev/null +++ b/lib/exceptions/address/address_exception.dart @@ -0,0 +1,5 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class AddressException extends SWException { + AddressException(super.message); +} diff --git a/lib/exceptions/electrumx/no_such_transaction.dart b/lib/exceptions/electrumx/no_such_transaction.dart new file mode 100644 index 000000000..0c7bedeae --- /dev/null +++ b/lib/exceptions/electrumx/no_such_transaction.dart @@ -0,0 +1,7 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class NoSuchTransactionException extends SWException { + final String txid; + + NoSuchTransactionException(super.message, this.txid); +} diff --git a/lib/exceptions/main_db/main_db_exception.dart b/lib/exceptions/main_db/main_db_exception.dart new file mode 100644 index 000000000..4285060ba --- /dev/null +++ b/lib/exceptions/main_db/main_db_exception.dart @@ -0,0 +1,12 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class MainDBException extends SWException { + MainDBException(super.message, this.originalError); + + final Object originalError; + + @override + String toString() { + return "$message: originalError=$originalError"; + } +} diff --git a/lib/exceptions/sw_exception.dart b/lib/exceptions/sw_exception.dart new file mode 100644 index 000000000..34ab664f2 --- /dev/null +++ b/lib/exceptions/sw_exception.dart @@ -0,0 +1,11 @@ +// generic stack wallet exception which all other custom exceptions should +// extend from + +class SWException with Exception { + SWException(this.message); + + final String message; + + @override + toString() => message; +} diff --git a/lib/exceptions/wallet/insufficient_balance_exception.dart b/lib/exceptions/wallet/insufficient_balance_exception.dart new file mode 100644 index 000000000..219ef6a76 --- /dev/null +++ b/lib/exceptions/wallet/insufficient_balance_exception.dart @@ -0,0 +1,5 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class InsufficientBalanceException extends SWException { + InsufficientBalanceException(super.message); +} diff --git a/lib/exceptions/wallet/paynym_send_exception.dart b/lib/exceptions/wallet/paynym_send_exception.dart new file mode 100644 index 000000000..9980e6790 --- /dev/null +++ b/lib/exceptions/wallet/paynym_send_exception.dart @@ -0,0 +1,5 @@ +import 'package:stackwallet/exceptions/sw_exception.dart'; + +class PaynymSendException extends SWException { + PaynymSendException(super.message); +} diff --git a/lib/main.dart b/lib/main.dart index 8296d739a..e26d983dd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -254,6 +254,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme> _desktopHasPassword = await ref.read(storageCryptoHandlerProvider).hasPassword(); } + await MainDB.instance.initMainDB(); } Future<void> load() async { @@ -267,8 +268,6 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme> await loadShared(); } - await MainDB.instance.initMainDB(); - _notificationsService = ref.read(notificationsProvider); _nodeService = ref.read(nodeServiceChangeNotifierProvider); _tradesService = ref.read(tradesServiceProvider); @@ -344,12 +343,12 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme> case "oceanBreeze": colorTheme = OceanBreezeColors(); break; - case "light": - colorTheme = LightColors(); - break; case "fruitSorbet": - default: colorTheme = FruitSorbetColors(); + break; + case "light": + default: + colorTheme = LightColors(); } loadingCompleter = Completer(); WidgetsBinding.instance.addObserver(this); diff --git a/lib/models/isar/models/address/address.dart b/lib/models/isar/models/address/address.dart index df6d06fa7..1f0d48f8f 100644 --- a/lib/models/isar/models/address/address.dart +++ b/lib/models/isar/models/address/address.dart @@ -1,14 +1,10 @@ import 'package:isar/isar.dart'; +import 'package:stackwallet/exceptions/address/address_exception.dart'; import 'package:stackwallet/models/isar/models/address/crypto_currency_address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; part 'address.g.dart'; -class AddressException extends SWException { - AddressException(super.message); -} - @Collection(accessor: "addresses") class Address extends CryptoCurrencyAddress { Address({ @@ -73,6 +69,7 @@ class Address extends CryptoCurrencyAddress { "}"; } +// do not modify enum AddressType { p2pkh, p2sh, @@ -83,6 +80,7 @@ enum AddressType { nonWallet, } +// do not modify enum AddressSubType { receiving, change, diff --git a/lib/pages/address_book_views/subviews/add_address_book_entry_view.dart b/lib/pages/address_book_views/subviews/add_address_book_entry_view.dart index 36191e0b7..caffb65c7 100644 --- a/lib/pages/address_book_views/subviews/add_address_book_entry_view.dart +++ b/lib/pages/address_book_views/subviews/add_address_book_entry_view.dart @@ -584,7 +584,7 @@ class _AddAddressBookEntryViewState "Address ${i + 1}", style: STextStyles.smallMed12(context), ), - BlueTextButton( + CustomTextButton( onTap: () { _removeForm(forms[i].id); }, @@ -601,7 +601,7 @@ class _AddAddressBookEntryViewState const SizedBox( height: 16, ), - BlueTextButton( + CustomTextButton( onTap: () { _addForm(); scrollController.animateTo( diff --git a/lib/pages/address_book_views/subviews/contact_details_view.dart b/lib/pages/address_book_views/subviews/contact_details_view.dart index ff15420ca..4f417c9a5 100644 --- a/lib/pages/address_book_views/subviews/contact_details_view.dart +++ b/lib/pages/address_book_views/subviews/contact_details_view.dart @@ -311,7 +311,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> { "Addresses", style: STextStyles.itemSubtitle(context), ), - BlueTextButton( + CustomTextButton( text: "Add new", onTap: () { Navigator.of(context).pushNamed( diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index 3ec462ca7..feea9579d 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -122,12 +122,12 @@ class _BuyFormState extends ConsumerState<BuyForm> { setState(() { _amountOutOfRangeErrorString = "Invalid amount"; }); - } else if (value > maxFiat) { + } else if (value > maxFiat && buyWithFiat) { setState(() { _amountOutOfRangeErrorString = "Maximum amount: ${maxFiat.toStringAsFixed(2)}"; }); - } else if (value < minFiat) { + } else if (value < minFiat && buyWithFiat) { setState(() { _amountOutOfRangeErrorString = "Minimum amount: ${minFiat.toStringAsFixed(2)}"; @@ -280,6 +280,7 @@ class _BuyFormState extends ConsumerState<BuyForm> { minFiat = fiat.minAmount != minFiat ? fiat.minAmount : minFiat; maxFiat = fiat.maxAmount != maxFiat ? fiat.maxAmount : maxFiat; }); + validateAmount(); }, ); } @@ -530,25 +531,25 @@ class _BuyFormState extends ConsumerState<BuyForm> { } } else { // Error; probably amount out of bounds - String errorMessage = "${quoteResponse.exception?.errorMessage}"; - if (errorMessage.contains('must be between')) { - errorMessage = errorMessage.substring( - errorMessage.indexOf('getQuote exception: ') + 20, - errorMessage.indexOf(", value: null")); - _BuyFormState.boundedCryptoTicker = errorMessage.substring( - errorMessage.indexOf('The ') + 4, - errorMessage.indexOf(' amount must be between')); - _BuyFormState.minCrypto = Decimal.parse(errorMessage.substring( - errorMessage.indexOf('must be between ') + 16, - errorMessage.indexOf(' and '))); - _BuyFormState.maxCrypto = Decimal.parse(errorMessage.substring( - errorMessage.indexOf("$minCrypto and ") + "$minCrypto and ".length, - errorMessage.length)); - if (Decimal.parse(_buyAmountController.text) > - _BuyFormState.maxCrypto) { - _buyAmountController.text = _BuyFormState.maxCrypto.toString(); - } - } + // String errorMessage = "${quoteResponse.exception?.errorMessage}"; + // if (errorMessage.contains('must be between')) { + // errorMessage = errorMessage.substring( + // errorMessage.indexOf('getQuote exception: ') + 20, + // errorMessage.indexOf(", value: null")); + // _BuyFormState.boundedCryptoTicker = errorMessage.substring( + // errorMessage.indexOf('The ') + 4, + // errorMessage.indexOf(' amount must be between')); + // _BuyFormState.minCrypto = Decimal.parse(errorMessage.substring( + // errorMessage.indexOf('must be between ') + 16, + // errorMessage.indexOf(' and '))); + // _BuyFormState.maxCrypto = Decimal.parse(errorMessage.substring( + // errorMessage.indexOf("$minCrypto and ") + "$minCrypto and ".length, + // errorMessage.length)); + // if (Decimal.parse(_buyAmountController.text) > + // _BuyFormState.maxCrypto) { + // _buyAmountController.text = _BuyFormState.maxCrypto.toString(); + // } + // } await showDialog<dynamic>( context: context, barrierDismissible: true, @@ -570,7 +571,7 @@ class _BuyFormState extends ConsumerState<BuyForm> { height: 24, ), Text( - errorMessage, + quoteResponse.exception!.errorMessage, style: STextStyles.smallMed14(context), ), const SizedBox( @@ -632,10 +633,11 @@ class _BuyFormState extends ConsumerState<BuyForm> { level: LogLevel.Warning, ); return BuyResponse( - exception: BuyException( - response.toString(), - BuyExceptionType.generic, - ), + exception: response.exception ?? + BuyException( + response.toString(), + BuyExceptionType.generic, + ), ); } } @@ -951,12 +953,13 @@ class _BuyFormState extends ConsumerState<BuyForm> { Theme.of(context).extension<StackColors>()!.textDark3, ), ), - BlueTextButton( + CustomTextButton( text: buyWithFiat ? "Use crypto amount" : "Use fiat amount", onTap: () { setState(() { buyWithFiat = !buyWithFiat; }); + validateAmount(); }, ) ], @@ -1126,8 +1129,8 @@ class _BuyFormState extends ConsumerState<BuyForm> { ), ), if (isStackCoin(selectedCrypto?.ticker)) - BlueTextButton( - text: "Choose from stack", + CustomTextButton( + text: "Choose from Stack", onTap: () { try { final coin = coinFromTickerCaseInsensitive( @@ -1150,7 +1153,11 @@ class _BuyFormState extends ConsumerState<BuyForm> { _receiveAddressController.text = await manager.currentReceivingAddress; - setState(() {}); + setState(() { + _addressToggleFlag = + _receiveAddressController.text.isNotEmpty; + }); + validateAmount(); } }); } catch (e, s) { diff --git a/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart b/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart index c98d53580..dc9935a03 100644 --- a/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart +++ b/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart @@ -18,16 +18,28 @@ import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/stack_dialog.dart'; -class BuyWarningPopup extends StatelessWidget { - BuyWarningPopup({ +class BuyWarningPopup extends StatefulWidget { + const BuyWarningPopup({ Key? key, required this.quote, this.order, }) : super(key: key); - final SimplexQuote quote; + final SimplexOrder? order; + @override + State<BuyWarningPopup> createState() => _BuyWarningPopupState(); +} + +class _BuyWarningPopupState extends State<BuyWarningPopup> { + late final bool isDesktop; SimplexOrder? order; + String get title => "Buy ${widget.quote.crypto.ticker}"; + String get message => + "This purchase is provided and fulfilled by Simplex by nuvei " + "(a third party). You will be taken to their website. Please follow " + "their instructions."; + Future<BuyResponse<SimplexOrder>> newOrder(SimplexQuote quote) async { final orderResponse = await SimplexAPI.instance.newOrder(quote); @@ -38,174 +50,241 @@ class BuyWarningPopup extends StatelessWidget { return SimplexAPI.instance.redirect(order); } - @override - Widget build(BuildContext context) { - final isDesktop = Util.isDesktop; - - Future<void> _buyInvoice() async { - await showDialog<void>( - context: context, - // useRootNavigator: isDesktop, - builder: (context) { - return isDesktop - ? DesktopDialog( - maxHeight: 700, - maxWidth: 580, - child: Column( + Future<void> _buyInvoice() async { + await showDialog<void>( + context: context, + // useRootNavigator: isDesktop, + builder: (context) { + return isDesktop + ? DesktopDialog( + maxHeight: 700, + maxWidth: 580, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + Padding( + padding: const EdgeInsets.only( + left: 32, + ), + child: Text( + "Order details", + style: STextStyles.desktopH3(context), + ), + ), + const DesktopDialogCloseButton(), + ], + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + bottom: 32, + ), + child: Row( children: [ - Padding( - padding: const EdgeInsets.only( - left: 32, - ), - child: Text( - "Order details", - style: STextStyles.desktopH3(context), + Expanded( + child: RoundedWhiteContainer( + padding: const EdgeInsets.all(16), + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: BuyOrderDetailsView( + order: order as SimplexOrder, + ), ), ), - const DesktopDialogCloseButton(), ], ), + ), + ), + ], + ), + ) + : BuyOrderDetailsView( + order: order as SimplexOrder, + ); + }, + ); + } + + Future<void> onContinue() async { + BuyResponse<SimplexOrder> orderResponse = await newOrder(widget.quote); + if (orderResponse.exception == null) { + await redirect(orderResponse.value as SimplexOrder) + .then((_response) async { + order = orderResponse.value as SimplexOrder; + Navigator.of(context, rootNavigator: isDesktop).pop(); + Navigator.of(context, rootNavigator: isDesktop).pop(); + await _buyInvoice(); + }); + } else { + await showDialog<dynamic>( + context: context, + barrierDismissible: true, + builder: (context) { + if (isDesktop) { + return DesktopDialog( + maxWidth: 450, + child: Padding( + padding: const EdgeInsets.all(32), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Simplex API error", + style: STextStyles.desktopH3(context), + ), + const SizedBox( + height: 24, + ), + Text( + "${orderResponse.exception?.errorMessage}", + style: STextStyles.smallMed14(context), + ), + const SizedBox( + height: 56, + ), + Row( + children: [ + const Spacer(), Expanded( - child: Padding( - padding: const EdgeInsets.only( - left: 32, - right: 32, - bottom: 32, - ), - child: Row( - children: [ - Expanded( - child: RoundedWhiteContainer( - padding: const EdgeInsets.all(16), - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: BuyOrderDetailsView( - order: order as SimplexOrder, - ), - ), - ), - ], - ), + child: PrimaryButton( + buttonHeight: ButtonHeight.l, + label: "Ok", + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); // weee + }, ), ), ], - ), - ) - : BuyOrderDetailsView( - order: order as SimplexOrder, - ); - }); - } - - return StackDialog( - title: "Buy ${quote.crypto.ticker}", - message: "This purchase is provided and fulfilled by Simplex by nuvei " - "(a third party). You will be taken to their website. Please follow " - "their instructions.", - leftButton: SecondaryButton( - label: "Cancel", - onPressed: Navigator.of(context, rootNavigator: isDesktop).pop, - ), - rightButton: PrimaryButton( - label: "Continue", - onPressed: () async { - BuyResponse<SimplexOrder> orderResponse = await newOrder(quote); - if (orderResponse.exception == null) { - await redirect(orderResponse.value as SimplexOrder) - .then((_response) async { - this.order = orderResponse.value as SimplexOrder; - Navigator.of(context, rootNavigator: isDesktop).pop(); - Navigator.of(context, rootNavigator: isDesktop).pop(); - await _buyInvoice(); - }); + ) + ], + ), + ), + ); } else { - await showDialog<dynamic>( - context: context, - barrierDismissible: true, - builder: (context) { - if (isDesktop) { - return DesktopDialog( - maxWidth: 450, - child: Padding( - padding: const EdgeInsets.all(32), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Simplex API error", - style: STextStyles.desktopH3(context), - ), - const SizedBox( - height: 24, - ), - Text( - "${orderResponse.exception?.errorMessage}", - style: STextStyles.smallMed14(context), - ), - const SizedBox( - height: 56, - ), - Row( - children: [ - const Spacer(), - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.l, - label: "Ok", - onPressed: () { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); // weee - }, - ), - ), - ], - ) - ], - ), - ), - ); - } else { - return StackDialog( - title: "Simplex API error", - message: "${orderResponse.exception?.errorMessage}", - // "${quoteResponse.exception?.errorMessage.substring(8, (quoteResponse.exception?.errorMessage?.length ?? 109) - (8 + 6))}", - rightButton: TextButton( - style: Theme.of(context) + return StackDialog( + title: "Simplex API error", + message: "${orderResponse.exception?.errorMessage}", + // "${quoteResponse.exception?.errorMessage.substring(8, (quoteResponse.exception?.errorMessage?.length ?? 109) - (8 + 6))}", + rightButton: TextButton( + style: Theme.of(context) + .extension<StackColors>()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Ok", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) .extension<StackColors>()! - .getSecondaryEnabledButtonStyle(context), - child: Text( - "Ok", - style: STextStyles.button(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .accentColorDark), - ), - onPressed: () { - Navigator.of(context).pop(); - Navigator.of(context).pop(); - Navigator.of(context).pop(); // weee - }, - ), - ); - } - }, + .accentColorDark), + ), + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); // weee + }, + ), ); } }, - ), - icon: SizedBox( - width: 64, - height: 32, - child: SvgPicture.asset( - Assets.buy.simplexLogo(context), + ); + } + } + + @override + void initState() { + order = widget.order; + isDesktop = Util.isDesktop; + super.initState(); + } + + @override + Widget build(BuildContext context) { + if (isDesktop) { + return DesktopDialog( + maxWidth: 580, + maxHeight: 350, + child: Padding( + padding: const EdgeInsets.all(32), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + title, + style: STextStyles.desktopH3(context), + ), + SizedBox( + width: 64, + height: 32, + child: SvgPicture.asset( + Assets.buy.simplexLogo(context), + ), + ), + ], + ), + const Spacer(), + Text( + message, + style: STextStyles.desktopTextSmall(context), + ), + const Spacer( + flex: 2, + ), + Row( + children: [ + Expanded( + child: SecondaryButton( + label: "Cancel", + buttonHeight: ButtonHeight.l, + onPressed: + Navigator.of(context, rootNavigator: isDesktop).pop, + ), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.l, + label: "Continue", + onPressed: onContinue, + ), + ), + ], + ) + ], + ), ), - ), - ); + ); + } else { + return StackDialog( + title: title, + message: message, + leftButton: SecondaryButton( + label: "Cancel", + onPressed: Navigator.of(context, rootNavigator: isDesktop).pop, + ), + rightButton: PrimaryButton( + label: "Continue", + onPressed: onContinue, + ), + icon: SizedBox( + width: 64, + height: 32, + child: SvgPicture.asset( + Assets.buy.simplexLogo(context), + ), + ), + ); + } } } 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 238499c5f..86db9171a 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 @@ -189,8 +189,8 @@ class _Step2ViewState extends ConsumerState<Step2View> { style: STextStyles.smallMed12(context), ), if (isStackCoin(model.receiveTicker)) - BlueTextButton( - text: "Choose from stack", + CustomTextButton( + text: "Choose from Stack", onTap: () { try { final coin = @@ -448,8 +448,8 @@ class _Step2ViewState extends ConsumerState<Step2View> { style: STextStyles.smallMed12(context), ), if (isStackCoin(model.sendTicker)) - BlueTextButton( - text: "Choose from stack", + CustomTextButton( + text: "Choose from Stack", onTap: () { try { final coin = diff --git a/lib/pages/exchange_view/trade_details_view.dart b/lib/pages/exchange_view/trade_details_view.dart index 9d8a1d223..4e42ff888 100644 --- a/lib/pages/exchange_view/trade_details_view.dart +++ b/lib/pages/exchange_view/trade_details_view.dart @@ -516,7 +516,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> { const SizedBox( height: 10, ), - BlueTextButton( + CustomTextButton( text: "View transaction", onTap: () { final Coin coin = diff --git a/lib/pages/home_view/home_view.dart b/lib/pages/home_view/home_view.dart index 5a09203cb..9ba14c692 100644 --- a/lib/pages/home_view/home_view.dart +++ b/lib/pages/home_view/home_view.dart @@ -50,7 +50,7 @@ class _HomeViewState extends ConsumerState<HomeView> { Future<bool> _onWillPop() async { // go to home view when tapping back on the main exchange view - if (ref.read(homeViewPageIndexStateProvider.state).state == 1) { + if (ref.read(homeViewPageIndexStateProvider.state).state != 0) { ref.read(homeViewPageIndexStateProvider.state).state = 0; return false; } diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart index 72c4a2f46..729ed5941 100644 --- a/lib/pages/paynym/dialogs/paynym_details_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart @@ -5,16 +5,17 @@ import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:qr_flutter/qr_flutter.dart'; +import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart'; import 'package:stackwallet/pages/paynym/paynym_home_view.dart'; import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; +import 'package:stackwallet/pages/send_view/send_view.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/route_generator.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; @@ -25,6 +26,7 @@ import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/loading_indicator.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; +import 'package:tuple/tuple.dart'; class PaynymDetailsPopup extends ConsumerStatefulWidget { const PaynymDetailsPopup({ @@ -43,6 +45,19 @@ class PaynymDetailsPopup extends ConsumerStatefulWidget { class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { bool _showInsufficientFundsInfo = false; + Future<void> _onSend() async { + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + await Navigator.of(context).pushNamed( + SendView.routeName, + arguments: Tuple3( + manager.walletId, + manager.coin, + widget.accountLite, + ), + ); + } + Future<void> _onConnectPressed() async { bool canPop = false; unawaited( @@ -57,30 +72,24 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { ), ); - final wallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); - // sanity check to prevent second notifcation tx - if (wallet.hasConnectedConfirmed(widget.accountLite.code)) { - canPop = true; - Navigator.of(context).pop(); - // TODO show info popup - return; - } else if (wallet.hasConnected(widget.accountLite.code)) { + final wallet = manager.wallet as PaynymWalletInterface; + + if (await wallet.hasConnected(widget.accountLite.code)) { canPop = true; Navigator.of(context).pop(); // TODO show info popup return; } - final rates = await wallet.fees; + final rates = await manager.fees; Map<String, dynamic> preparedTx; try { - preparedTx = await wallet.buildNotificationTx( + preparedTx = await wallet.prepareNotificationTx( selectedTxFeeRate: rates.medium, targetPaymentCodeString: widget.accountLite.code, ); @@ -117,7 +126,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { Navigator.of(context).push( RouteGenerator.getRoute( builder: (_) => ConfirmTransactionView( - walletId: wallet.walletId, + walletId: manager.walletId, routeOnSuccessName: PaynymHomeView.routeName, isPaynymNotificationTransaction: true, transactionInfo: { @@ -133,7 +142,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { ); }, amount: (preparedTx["amount"] as int) + (preparedTx["fee"] as int), - coin: wallet.coin, + coin: manager.coin, ), ); } @@ -141,6 +150,11 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { @override Widget build(BuildContext context) { + final manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId))); + + final wallet = manager.wallet as PaynymWalletInterface; + return DesktopDialog( maxWidth: MediaQuery.of(context).size.width - 32, maxHeight: double.infinity, @@ -162,31 +176,97 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { children: [ PayNymBot( paymentCodeString: widget.accountLite.code, - size: 32, + size: 36, ), const SizedBox( width: 12, ), - Text( - widget.accountLite.nymName, - style: STextStyles.w600_12(context), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.accountLite.nymName, + style: STextStyles.w600_14(context), + ), + FutureBuilder( + future: + wallet.hasConnected(widget.accountLite.code), + builder: (context, AsyncSnapshot<bool> snapshot) { + if (snapshot.connectionState == + ConnectionState.done && + snapshot.data == true) { + return Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 2, + ), + Text( + "Connected", + style: STextStyles.w500_12(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorGreen, + ), + ) + ], + ); + } else { + return Container(); + } + }, + ), + ], ), ], ), - PrimaryButton( - label: "Connect", - buttonHeight: ButtonHeight.l, - icon: SvgPicture.asset( - Assets.svg.circlePlusFilled, - width: 10, - height: 10, - color: Theme.of(context) - .extension<StackColors>()! - .buttonTextPrimary, - ), - iconSpacing: 4, - width: 86, - onPressed: _onConnectPressed, + FutureBuilder( + future: wallet.hasConnected(widget.accountLite.code), + builder: (context, AsyncSnapshot<bool> snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + if (snapshot.data!) { + return PrimaryButton( + label: "Send", + buttonHeight: ButtonHeight.xl, + icon: SvgPicture.asset( + Assets.svg.circleArrowUpRight, + width: 14, + height: 14, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + iconSpacing: 8, + width: 100, + onPressed: _onSend, + ); + } else { + return PrimaryButton( + label: "Connect", + buttonHeight: ButtonHeight.xl, + icon: SvgPicture.asset( + Assets.svg.circlePlusFilled, + width: 13, + height: 13, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + iconSpacing: 8, + width: 128, + onPressed: _onConnectPressed, + ); + } + } else { + return const SizedBox( + height: 32, + child: LoadingIndicator(), + ); + } + }, ), ], ), @@ -211,6 +291,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { color: Theme.of(context) .extension<StackColors>()! .warningForeground, + fontSize: 12, ), ), ), @@ -241,7 +322,9 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { children: [ Text( "PayNym address", - style: STextStyles.infoSmall(context), + style: STextStyles.infoSmall(context).copyWith( + fontSize: 12, + ), ), const SizedBox( height: 6, @@ -252,6 +335,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { color: Theme.of(context) .extension<StackColors>()! .textDark, + fontSize: 12, ), ), const SizedBox( @@ -266,7 +350,7 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { ), QrImage( padding: const EdgeInsets.all(0), - size: 86, + size: 100, data: widget.accountLite.code, foregroundColor: Theme.of(context).extension<StackColors>()!.textDark, @@ -295,16 +379,16 @@ class _PaynymDetailsPopupState extends ConsumerState<PaynymDetailsPopup> { Expanded( child: SecondaryButton( label: "Copy", - buttonHeight: ButtonHeight.l, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: SvgPicture.asset( Assets.svg.copy, - width: 10, - height: 10, + width: 12, + height: 12, color: Theme.of(context) .extension<StackColors>()! .buttonTextSecondary, ), - iconSpacing: 4, onPressed: () async { await Clipboard.setData( ClipboardData( diff --git a/lib/pages/paynym/dialogs/paynym_qr_popup.dart b/lib/pages/paynym/dialogs/paynym_qr_popup.dart index 4ff6d9ca0..3ad985472 100644 --- a/lib/pages/paynym/dialogs/paynym_qr_popup.dart +++ b/lib/pages/paynym/dialogs/paynym_qr_popup.dart @@ -56,7 +56,7 @@ class PaynymQrPopup extends StatelessWidget { children: [ PayNymBot( paymentCodeString: paynymAccount.codes.first.code, - size: isDesktop ? 56 : 32, + size: isDesktop ? 56 : 36, ), const SizedBox( width: 12, @@ -65,7 +65,7 @@ class PaynymQrPopup extends StatelessWidget { paynymAccount.nymName, style: isDesktop ? STextStyles.w500_24(context) - : STextStyles.w600_12(context), + : STextStyles.w600_14(context), ), ], ), @@ -87,7 +87,7 @@ class PaynymQrPopup extends StatelessWidget { children: [ Expanded( child: ConstrainedBox( - constraints: const BoxConstraints(minHeight: 107), + constraints: const BoxConstraints(minHeight: 130), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -100,7 +100,9 @@ class PaynymQrPopup extends StatelessWidget { .extension<StackColors>()! .textSubtitle1, ) - : STextStyles.infoSmall(context), + : STextStyles.infoSmall(context).copyWith( + fontSize: 12, + ), ), const SizedBox( height: 6, @@ -113,14 +115,15 @@ class PaynymQrPopup extends StatelessWidget { color: Theme.of(context) .extension<StackColors>()! .textDark, + fontSize: 12, ), ), const SizedBox( height: 6, ), - BlueTextButton( + CustomTextButton( text: "Copy", - textSize: isDesktop ? 18 : 10, + textSize: isDesktop ? 18 : 14, onTap: () async { await Clipboard.setData( ClipboardData( @@ -146,7 +149,7 @@ class PaynymQrPopup extends StatelessWidget { ), QrImage( padding: const EdgeInsets.all(0), - size: 107, + size: 130, data: paynymAccount.codes.first.code, foregroundColor: Theme.of(context).extension<StackColors>()!.textDark, diff --git a/lib/pages/paynym/paynym_claim_view.dart b/lib/pages/paynym/paynym_claim_view.dart index cf5ffc671..326983a78 100644 --- a/lib/pages/paynym/paynym_claim_view.dart +++ b/lib/pages/paynym/paynym_claim_view.dart @@ -9,9 +9,9 @@ import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; @@ -117,7 +117,7 @@ class _PaynymClaimViewState extends ConsumerState<PaynymClaimView> { ), Image( image: AssetImage( - Assets.png.stack, + Assets.png.unclaimedPaynym, ), width: MediaQuery.of(context).size.width / 2, ), @@ -159,16 +159,18 @@ class _PaynymClaimViewState extends ConsumerState<PaynymClaimView> { ).then((value) => shouldCancel = value == true), ); - // get wallet to access paynym calls - final wallet = ref + final manager = ref .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + .getManager(widget.walletId); + + // get wallet to access paynym calls + final wallet = manager.wallet as PaynymWalletInterface; if (shouldCancel) return; // get payment code - final pCode = await wallet.getPaymentCode(); + final pCode = await wallet.getPaymentCode( + DerivePathTypeExt.primaryFor(manager.coin)); if (shouldCancel) return; diff --git a/lib/pages/paynym/paynym_home_view.dart b/lib/pages/paynym/paynym_home_view.dart index 4d4efeb0d..9292b8acb 100644 --- a/lib/pages/paynym/paynym_home_view.dart +++ b/lib/pages/paynym/paynym_home_view.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:share_plus/share_plus.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/paynym/add_new_paynym_follow_view.dart'; import 'package:stackwallet/pages/paynym/dialogs/paynym_qr_popup.dart'; @@ -200,7 +201,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { height: 20, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .accentColorDark, ), onPressed: () { Navigator.of(context).pushNamed( @@ -222,7 +223,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { height: 20, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .accentColorDark, ), onPressed: () { // todo info ? @@ -302,7 +303,9 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { .code, 12, 5), - style: STextStyles.label(context), + style: STextStyles.label(context).copyWith( + fontSize: 14, + ), ), const SizedBox( height: 11, @@ -312,14 +315,14 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { Expanded( child: SecondaryButton( label: "Copy", - buttonHeight: ButtonHeight.l, - iconSpacing: 4, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: CopyIcon( - width: 10, - height: 10, + width: 12, + height: 12, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .buttonTextSecondary, ), onPressed: () async { await Clipboard.setData( @@ -349,17 +352,34 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { Expanded( child: SecondaryButton( label: "Share", - buttonHeight: ButtonHeight.l, - iconSpacing: 4, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: ShareIcon( - width: 10, - height: 10, + width: 12, + height: 12, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .buttonTextSecondary, ), - onPressed: () { - // copy to clipboard + onPressed: () async { + Rect? sharePositionOrigin; + if (await Util.isIPad) { + final box = + context.findRenderObject() as RenderBox?; + if (box != null) { + sharePositionOrigin = + box.localToGlobal(Offset.zero) & box.size; + } + } + + await Share.share( + ref + .read(myPaynymAccountStateProvider.state) + .state! + .codes + .first + .code, + sharePositionOrigin: sharePositionOrigin); }, ), ), @@ -369,14 +389,14 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { Expanded( child: SecondaryButton( label: "Address", - buttonHeight: ButtonHeight.l, - iconSpacing: 4, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: QrCodeIcon( - width: 10, - height: 10, + width: 12, + height: 12, color: Theme.of(context) .extension<StackColors>()! - .textDark, + .buttonTextSecondary, ), onPressed: () { showDialog<void>( @@ -536,7 +556,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> { child: child, ), child: SizedBox( - height: isDesktop ? 56 : 40, + height: isDesktop ? 56 : 48, width: isDesktop ? 490 : null, child: Toggle( onColor: Theme.of(context).extension<StackColors>()!.popupBG, diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart index d51a0fecd..2f7f05e9a 100644 --- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart +++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart @@ -5,14 +5,14 @@ import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:qr_flutter/qr_flutter.dart'; +import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart'; import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; @@ -57,30 +57,24 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { ), ); - final wallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); - // sanity check to prevent second notification tx - if (wallet.hasConnectedConfirmed(widget.accountLite.code)) { - canPop = true; - Navigator.of(context, rootNavigator: true).pop(); - // TODO show info popup - return; - } else if (wallet.hasConnected(widget.accountLite.code)) { + final wallet = manager.wallet as PaynymWalletInterface; + + if (await wallet.hasConnected(widget.accountLite.code)) { canPop = true; Navigator.of(context, rootNavigator: true).pop(); // TODO show info popup return; } - final rates = await wallet.fees; + final rates = await manager.fees; Map<String, dynamic> preparedTx; try { - preparedTx = await wallet.buildNotificationTx( + preparedTx = await wallet.prepareNotificationTx( selectedTxFeeRate: rates.medium, targetPaymentCodeString: widget.accountLite.code, ); @@ -118,7 +112,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { maxHeight: double.infinity, maxWidth: 580, child: ConfirmTransactionView( - walletId: wallet.walletId, + walletId: manager.walletId, isPaynymNotificationTransaction: true, transactionInfo: { "hex": preparedTx["hex"], @@ -147,7 +141,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { ); }, amount: (preparedTx["amount"] as int) + (preparedTx["fee"] as int), - coin: wallet.coin, + coin: manager.coin, ), ); } @@ -159,10 +153,11 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { @override Widget build(BuildContext context) { - final wallet = ref - .watch(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId))); + + final wallet = manager.wallet as PaynymWalletInterface; + return RoundedWhiteContainer( padding: const EdgeInsets.all(0), child: Column( @@ -176,14 +171,47 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { children: [ PayNymBot( paymentCodeString: widget.accountLite.code, - size: 32, + size: 36, ), const SizedBox( width: 12, ), - Text( - widget.accountLite.nymName, - style: STextStyles.desktopTextSmall(context), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.accountLite.nymName, + style: STextStyles.desktopTextSmall(context), + ), + FutureBuilder( + future: wallet.hasConnected(widget.accountLite.code), + builder: (context, AsyncSnapshot<bool> snapshot) { + if (snapshot.connectionState == + ConnectionState.done && + snapshot.data == true) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 2, + ), + Text( + "Connected", + style: STextStyles.desktopTextSmall(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorGreen, + ), + ) + ], + ); + } else { + return Container(); + } + }, + ), + ], ), ], ), @@ -192,40 +220,53 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { ), Row( children: [ - if (!wallet.hasConnected(widget.accountLite.code)) - Expanded( - child: PrimaryButton( - label: "Connect", - buttonHeight: ButtonHeight.s, - icon: SvgPicture.asset( - Assets.svg.circlePlusFilled, - width: 16, - height: 16, - color: Theme.of(context) - .extension<StackColors>()! - .buttonTextPrimary, - ), - iconSpacing: 6, - onPressed: _onConnectPressed, - ), - ), - if (wallet.hasConnected(widget.accountLite.code)) - Expanded( - child: PrimaryButton( - label: "Send", - buttonHeight: ButtonHeight.s, - icon: SvgPicture.asset( - Assets.svg.circleArrowUpRight, - width: 16, - height: 16, - color: Theme.of(context) - .extension<StackColors>()! - .buttonTextPrimary, - ), - iconSpacing: 6, - onPressed: _onSend, - ), + Expanded( + child: FutureBuilder( + future: wallet.hasConnected(widget.accountLite.code), + builder: (context, AsyncSnapshot<bool> snapshot) { + if (snapshot.connectionState == + ConnectionState.done && + snapshot.hasData) { + if (snapshot.data!) { + return PrimaryButton( + label: "Send", + buttonHeight: ButtonHeight.s, + icon: SvgPicture.asset( + Assets.svg.circleArrowUpRight, + width: 16, + height: 16, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + iconSpacing: 6, + onPressed: _onSend, + ); + } else { + return PrimaryButton( + label: "Connect", + buttonHeight: ButtonHeight.s, + icon: SvgPicture.asset( + Assets.svg.circlePlusFilled, + width: 16, + height: 16, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + iconSpacing: 6, + onPressed: _onConnectPressed, + ); + } + } else { + return const SizedBox( + height: 100, + child: LoadingIndicator(), + ); + } + }, ), + ), const SizedBox( width: 20, ), @@ -316,7 +357,7 @@ class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> { const SizedBox( height: 8, ), - BlueTextButton( + CustomTextButton( text: "Copy", onTap: () async { await Clipboard.setData( diff --git a/lib/pages/paynym/subwidgets/paynym_card.dart b/lib/pages/paynym/subwidgets/paynym_card.dart index be989a588..644e9e9bf 100644 --- a/lib/pages/paynym/subwidgets/paynym_card.dart +++ b/lib/pages/paynym/subwidgets/paynym_card.dart @@ -37,7 +37,7 @@ class _PaynymCardState extends State<PaynymCard> { child: Row( children: [ PayNymBot( - size: 32, + size: 36, paymentCodeString: widget.paymentCodeString, ), const SizedBox( @@ -56,7 +56,7 @@ class _PaynymCardState extends State<PaynymCard> { .extension<StackColors>()! .textFieldActiveText, ) - : STextStyles.w500_12(context), + : STextStyles.w500_14(context), ), const SizedBox( height: 2, @@ -65,7 +65,7 @@ class _PaynymCardState extends State<PaynymCard> { Format.shorten(widget.paymentCodeString, 12, 5), style: isDesktop ? STextStyles.desktopTextExtraExtraSmall(context) - : STextStyles.w500_12(context).copyWith( + : STextStyles.w500_14(context).copyWith( color: Theme.of(context) .extension<StackColors>()! .textSubtitle1, diff --git a/lib/pages/paynym/subwidgets/paynym_card_button.dart b/lib/pages/paynym/subwidgets/paynym_card_button.dart index 75c4d2cc0..6e51c85f8 100644 --- a/lib/pages/paynym/subwidgets/paynym_card_button.dart +++ b/lib/pages/paynym/subwidgets/paynym_card_button.dart @@ -77,7 +77,7 @@ class _PaynymCardButtonState extends ConsumerState<PaynymCardButton> { child: Row( children: [ PayNymBot( - size: 32, + size: 36, paymentCodeString: widget.accountLite.code, ), const SizedBox( @@ -96,7 +96,7 @@ class _PaynymCardButtonState extends ConsumerState<PaynymCardButton> { .extension<StackColors>()! .textFieldActiveText, ) - : STextStyles.w500_12(context), + : STextStyles.w500_14(context), ), const SizedBox( height: 2, @@ -105,7 +105,7 @@ class _PaynymCardButtonState extends ConsumerState<PaynymCardButton> { Format.shorten(widget.accountLite.code, 12, 5), style: isDesktop ? STextStyles.desktopTextExtraExtraSmall(context) - : STextStyles.w500_12(context).copyWith( + : STextStyles.w500_14(context).copyWith( color: Theme.of(context) .extension<StackColors>()! .textSubtitle1, diff --git a/lib/pages/paynym/subwidgets/paynym_followers_list.dart b/lib/pages/paynym/subwidgets/paynym_followers_list.dart index dbec19692..d8583954d 100644 --- a/lib/pages/paynym/subwidgets/paynym_followers_list.dart +++ b/lib/pages/paynym/subwidgets/paynym_followers_list.dart @@ -3,11 +3,17 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages/paynym/subwidgets/paynym_card_button.dart'; +import 'package:stackwallet/providers/global/paynym_api_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; class PaynymFollowersList extends ConsumerStatefulWidget { @@ -54,61 +60,97 @@ class _PaynymFollowersListState extends ConsumerState<PaynymFollowersList> { ref.watch(myPaynymAccountStateProvider.state).state?.followers; final count = followers?.length ?? 0; - return ListView.separated( - itemCount: max(count, 1), - separatorBuilder: (BuildContext context, int index) => Container( - height: 1.5, - color: Colors.transparent, - ), - itemBuilder: (BuildContext context, int index) { - if (count == 0) { - return RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Your PayNym followers will appear here", - style: isDesktop - ? STextStyles.desktopTextExtraExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle1, - ) - : STextStyles.label(context), - ), - ], - ), - ); - } else if (count == 1) { - return RoundedWhiteContainer( - padding: const EdgeInsets.all(0), - child: PaynymCardButton( - walletId: widget.walletId, - accountLite: followers![0], - ), - ); - } else { - BorderRadius? borderRadius; - if (index == 0) { - borderRadius = _borderRadiusFirst; - } else if (index == count - 1) { - borderRadius = _borderRadiusLast; - } + return ConditionalParent( + condition: !isDesktop, + builder: (child) => RefreshIndicator( + child: child, + onRefresh: () async { + try { + final manager = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId); - return Container( - key: Key("paynymCardKey_${followers![index].nymId}"), - decoration: BoxDecoration( - borderRadius: borderRadius, - color: Theme.of(context).extension<StackColors>()!.popupBG, - ), - child: PaynymCardButton( - walletId: widget.walletId, - accountLite: followers[index], - ), - ); - } - }, + // get wallet to access paynym calls + final wallet = manager.wallet as PaynymWalletInterface; + + // get payment code + final pCode = await wallet.getPaymentCode( + DerivePathTypeExt.primaryFor(manager.coin), + ); + + // get account from api + final account = + await ref.read(paynymAPIProvider).nym(pCode.toString()); + + // update my account + if (account.value != null) { + ref.read(myPaynymAccountStateProvider.state).state = + account.value!; + } + } catch (e) { + Logging.instance.log( + "Failed pull down refresh of paynym home page: $e", + level: LogLevel.Warning, + ); + } + }, + ), + child: ListView.separated( + itemCount: max(count, 1), + separatorBuilder: (BuildContext context, int index) => Container( + height: 1.5, + color: Colors.transparent, + ), + itemBuilder: (BuildContext context, int index) { + if (count == 0) { + return RoundedWhiteContainer( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Your PayNym followers will appear here", + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ) + : STextStyles.label(context), + ), + ], + ), + ); + } else if (count == 1) { + return RoundedWhiteContainer( + padding: const EdgeInsets.all(0), + child: PaynymCardButton( + walletId: widget.walletId, + accountLite: followers![0], + ), + ); + } else { + BorderRadius? borderRadius; + if (index == 0) { + borderRadius = _borderRadiusFirst; + } else if (index == count - 1) { + borderRadius = _borderRadiusLast; + } + + return Container( + key: Key("paynymCardKey_${followers![index].nymId}"), + decoration: BoxDecoration( + borderRadius: borderRadius, + color: Theme.of(context).extension<StackColors>()!.popupBG, + ), + child: PaynymCardButton( + walletId: widget.walletId, + accountLite: followers[index], + ), + ); + } + }, + ), ); } } diff --git a/lib/pages/paynym/subwidgets/paynym_following_list.dart b/lib/pages/paynym/subwidgets/paynym_following_list.dart index 754fd6a45..4d9df16ac 100644 --- a/lib/pages/paynym/subwidgets/paynym_following_list.dart +++ b/lib/pages/paynym/subwidgets/paynym_following_list.dart @@ -3,11 +3,17 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages/paynym/subwidgets/paynym_card_button.dart'; +import 'package:stackwallet/providers/global/paynym_api_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; class PaynymFollowingList extends ConsumerStatefulWidget { @@ -54,61 +60,97 @@ class _PaynymFollowingListState extends ConsumerState<PaynymFollowingList> { ref.watch(myPaynymAccountStateProvider.state).state?.following; final count = following?.length ?? 0; - return ListView.separated( - itemCount: max(count, 1), - separatorBuilder: (BuildContext context, int index) => Container( - height: 1.5, - color: Colors.transparent, - ), - itemBuilder: (BuildContext context, int index) { - if (count == 0) { - return RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Your PayNym contacts will appear here", - style: isDesktop - ? STextStyles.desktopTextExtraExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle1, - ) - : STextStyles.label(context), - ), - ], - ), - ); - } else if (count == 1) { - return RoundedWhiteContainer( - padding: const EdgeInsets.all(0), - child: PaynymCardButton( - walletId: widget.walletId, - accountLite: following![0], - ), - ); - } else { - BorderRadius? borderRadius; - if (index == 0) { - borderRadius = _borderRadiusFirst; - } else if (index == count - 1) { - borderRadius = _borderRadiusLast; - } + return ConditionalParent( + condition: !isDesktop, + builder: (child) => RefreshIndicator( + child: child, + onRefresh: () async { + try { + final manager = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId); - return Container( - key: Key("paynymCardKey_${following![index].nymId}"), - decoration: BoxDecoration( - borderRadius: borderRadius, - color: Theme.of(context).extension<StackColors>()!.popupBG, - ), - child: PaynymCardButton( - walletId: widget.walletId, - accountLite: following[index], - ), - ); - } - }, + // get wallet to access paynym calls + final wallet = manager.wallet as PaynymWalletInterface; + + // get payment code + final pCode = await wallet.getPaymentCode( + DerivePathTypeExt.primaryFor(manager.coin), + ); + + // get account from api + final account = + await ref.read(paynymAPIProvider).nym(pCode.toString()); + + // update my account + if (account.value != null) { + ref.read(myPaynymAccountStateProvider.state).state = + account.value!; + } + } catch (e) { + Logging.instance.log( + "Failed pull down refresh of paynym home page: $e", + level: LogLevel.Warning, + ); + } + }, + ), + child: ListView.separated( + itemCount: max(count, 1), + separatorBuilder: (BuildContext context, int index) => Container( + height: 1.5, + color: Colors.transparent, + ), + itemBuilder: (BuildContext context, int index) { + if (count == 0) { + return RoundedWhiteContainer( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Your PayNym contacts will appear here", + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ) + : STextStyles.label(context), + ), + ], + ), + ); + } else if (count == 1) { + return RoundedWhiteContainer( + padding: const EdgeInsets.all(0), + child: PaynymCardButton( + walletId: widget.walletId, + accountLite: following![0], + ), + ); + } else { + BorderRadius? borderRadius; + if (index == 0) { + borderRadius = _borderRadiusFirst; + } else if (index == count - 1) { + borderRadius = _borderRadiusLast; + } + + return Container( + key: Key("paynymCardKey_${following![index].nymId}"), + decoration: BoxDecoration( + borderRadius: borderRadius, + color: Theme.of(context).extension<StackColors>()!.popupBG, + ), + child: PaynymCardButton( + walletId: widget.walletId, + accountLite: following[index], + ), + ); + } + }, + ), ); } } diff --git a/lib/pages/receive_view/addresses/address_card.dart b/lib/pages/receive_view/addresses/address_card.dart new file mode 100644 index 000000000..1a47c256c --- /dev/null +++ b/lib/pages/receive_view/addresses/address_card.dart @@ -0,0 +1,132 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/pages/receive_view/addresses/address_qr_popup.dart'; +import 'package:stackwallet/pages/receive_view/addresses/edit_address_label_view.dart'; +import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/icon_widgets/copy_icon.dart'; +import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:tuple/tuple.dart'; + +class AddressCard extends StatelessWidget { + const AddressCard({ + Key? key, + required this.address, + required this.walletId, + required this.coin, + this.clipboard = const ClipboardWrapper(), + }) : super(key: key); + + final Address address; + final String walletId; + final Coin coin; + final ClipboardInterface clipboard; + + @override + Widget build(BuildContext context) { + return RoundedWhiteContainer( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "TODO: label", + style: STextStyles.itemSubtitle(context), + ), + CustomTextButton( + text: "Edit label", + textSize: 14, + onTap: () { + Navigator.of(context).pushNamed( + EditAddressLabelView.routeName, + arguments: Tuple2( + address, + walletId, + ), + ); + }, + ), + ], + ), + const SizedBox( + height: 8, + ), + Row( + children: [ + Expanded( + child: SelectableText( + address.value, + style: STextStyles.itemSubtitle12(context), + ), + ) + ], + ), + const SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: SecondaryButton( + label: "Copy address", + icon: CopyIcon( + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextSecondary, + ), + onPressed: () async { + await clipboard.setData( + ClipboardData( + text: address.value, + ), + ); + unawaited( + showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + context: context, + ), + ); + }, + ), + ), + const SizedBox( + width: 12, + ), + Expanded( + child: SecondaryButton( + label: "Show QR Code", + icon: QrCodeIcon( + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextSecondary, + ), + onPressed: () { + showDialog<void>( + context: context, + builder: (context) => AddressQrPopup( + address: address, + coin: coin, + clipboard: clipboard, + ), + ); + }, + ), + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/pages/receive_view/addresses/address_qr_popup.dart b/lib/pages/receive_view/addresses/address_qr_popup.dart new file mode 100644 index 000000000..75b3509de --- /dev/null +++ b/lib/pages/receive_view/addresses/address_qr_popup.dart @@ -0,0 +1,193 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:ui' as ui; + +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'package:share_plus/share_plus.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/utilities/address_utils.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/stack_dialog.dart'; + +class AddressQrPopup extends StatefulWidget { + const AddressQrPopup({ + Key? key, + required this.address, + required this.coin, + this.clipboard = const ClipboardWrapper(), + }) : super(key: key); + + final Address address; + final Coin coin; + final ClipboardInterface clipboard; + + @override + State<AddressQrPopup> createState() => _AddressQrPopupState(); +} + +class _AddressQrPopupState extends State<AddressQrPopup> { + final _qrKey = GlobalKey(); + final isDesktop = Util.isDesktop; + + Future<void> _capturePng(bool shouldSaveInsteadOfShare) async { + try { + RenderRepaintBoundary boundary = + _qrKey.currentContext?.findRenderObject() as RenderRepaintBoundary; + ui.Image image = await boundary.toImage(); + ByteData? byteData = + await image.toByteData(format: ui.ImageByteFormat.png); + Uint8List pngBytes = byteData!.buffer.asUint8List(); + + if (shouldSaveInsteadOfShare) { + if (isDesktop) { + final dir = Directory("${Platform.environment['HOME']}"); + if (!dir.existsSync()) { + throw Exception( + "Home dir not found while trying to open filepicker on QR image save"); + } + final path = await FilePicker.platform.saveFile( + fileName: "qrcode.png", + initialDirectory: dir.path, + ); + + if (path != null) { + final file = File(path); + if (file.existsSync()) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.warning, + message: "$path already exists!", + context: context, + ), + ); + } else { + await file.writeAsBytes(pngBytes); + unawaited( + showFloatingFlushBar( + type: FlushBarType.success, + message: "$path saved!", + context: context, + ), + ); + } + } + } else { + // await DocumentFileSavePlus.saveFile( + // pngBytes, + // "receive_qr_code_${DateTime.now().toLocal().toIso8601String()}.png", + // "image/png"); + } + } else { + final tempDir = await getTemporaryDirectory(); + final file = await File("${tempDir.path}/qrcode.png").create(); + await file.writeAsBytes(pngBytes); + + await Share.shareFiles(["${tempDir.path}/qrcode.png"], + text: "Receive URI QR Code"); + } + } catch (e) { + //todo: comeback to this + debugPrint(e.toString()); + } + } + + @override + Widget build(BuildContext context) { + return StackDialogBase( + child: Column( + children: [ + Text( + "todo: custom label", + style: STextStyles.pageTitleH2(context), + ), + const SizedBox( + height: 8, + ), + Text( + widget.address.value, + style: STextStyles.itemSubtitle(context), + ), + const SizedBox( + height: 16, + ), + Center( + child: RepaintBoundary( + key: _qrKey, + child: QrImage( + data: AddressUtils.buildUriString( + widget.coin, + widget.address.value, + {}, + ), + size: 220, + backgroundColor: + Theme.of(context).extension<StackColors>()!.popupBG, + foregroundColor: + Theme.of(context).extension<StackColors>()!.accentColorDark, + ), + ), + ), + const SizedBox( + height: 16, + ), + Row( + children: [ + Expanded( + child: SecondaryButton( + width: 170, + buttonHeight: isDesktop ? ButtonHeight.l : null, + onPressed: () async { + await _capturePng(false); + }, + label: "Share", + icon: SvgPicture.asset( + Assets.svg.share, + width: 20, + height: 20, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextSecondary, + ), + ), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: PrimaryButton( + width: 170, + onPressed: () async { + await _capturePng(true); + }, + label: "Save", + icon: SvgPicture.asset( + Assets.svg.arrowDown, + width: 20, + height: 20, + color: Theme.of(context) + .extension<StackColors>()! + .buttonTextPrimary, + ), + ), + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/pages/receive_view/addresses/edit_address_label_view.dart b/lib/pages/receive_view/addresses/edit_address_label_view.dart new file mode 100644 index 000000000..d44b61686 --- /dev/null +++ b/lib/pages/receive_view/addresses/edit_address_label_view.dart @@ -0,0 +1,241 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/models/isar/models/address/address.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; +import 'package:stackwallet/widgets/stack_text_field.dart'; +import 'package:stackwallet/widgets/textfield_icon_button.dart'; + +class EditAddressLabelView extends ConsumerStatefulWidget { + const EditAddressLabelView({ + Key? key, + required this.address, + required this.walletId, + }) : super(key: key); + + static const String routeName = "/editAddressLabel"; + + final Address address; + final String walletId; + + @override + ConsumerState<EditAddressLabelView> createState() => + _EditAddressLabelViewState(); +} + +class _EditAddressLabelViewState extends ConsumerState<EditAddressLabelView> { + late final TextEditingController _labelFieldController; + final labelFieldFocusNode = FocusNode(); + + late final bool isDesktop; + + @override + void initState() { + isDesktop = Util.isDesktop; + _labelFieldController = TextEditingController(); + _labelFieldController.text = "todo: address.label"; + super.initState(); + } + + @override + void dispose() { + _labelFieldController.dispose(); + labelFieldFocusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ConditionalParent( + condition: !isDesktop, + builder: (child) => Background( + child: child, + ), + child: Scaffold( + backgroundColor: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.background, + appBar: isDesktop + ? null + : AppBar( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + leading: AppBarBackButton( + onPressed: () async { + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future<void>.delayed( + const Duration(milliseconds: 75)); + } + if (mounted) { + Navigator.of(context).pop(); + } + }, + ), + title: Text( + "Edit label", + style: STextStyles.navBarTitle(context), + ), + ), + body: ConditionalParent( + condition: !isDesktop, + builder: (child) => Padding( + padding: const EdgeInsets.all(12), + child: LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(4), + child: child, + ), + ), + ), + ); + }, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (isDesktop) + Padding( + padding: const EdgeInsets.only( + left: 32, + bottom: 12, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Edit label", + style: STextStyles.desktopH3(context), + ), + const DesktopDialogCloseButton(), + ], + ), + ), + Padding( + padding: isDesktop + ? const EdgeInsets.symmetric( + horizontal: 32, + ) + : const EdgeInsets.all(0), + child: ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: Util.isDesktop ? false : true, + enableSuggestions: Util.isDesktop ? false : true, + controller: _labelFieldController, + style: isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textFieldActiveText, + height: 1.8, + ) + : STextStyles.field(context), + focusNode: labelFieldFocusNode, + decoration: standardInputDecoration( + "Address label", + labelFieldFocusNode, + context, + desktopMed: isDesktop, + ).copyWith( + contentPadding: isDesktop + ? const EdgeInsets.only( + left: 16, + top: 11, + bottom: 12, + right: 5, + ) + : null, + suffixIcon: _labelFieldController.text.isNotEmpty + ? Padding( + padding: const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + children: [ + TextFieldIconButton( + child: const XIcon(), + onTap: () async { + setState(() { + _labelFieldController.text = ""; + }); + }, + ), + ], + ), + ), + ) + : null, + ), + ), + ), + ), + // if (!isDesktop) + const Spacer(), + if (isDesktop) + Padding( + padding: const EdgeInsets.all(32), + child: PrimaryButton( + label: "Save", + onPressed: () async { + // todo: update address + // await ref + // .read(notesServiceChangeNotifierProvider( + // widget.walletId)) + // .editOrAddNote( + // txid: widget.txid, + // note: _labelFieldController.text, + // ); + // if (mounted) { + // Navigator.of(context).pop(); + // } + }, + ), + ), + if (!isDesktop) + TextButton( + onPressed: () async { + // todo: update address + // await ref + // .read( + // notesServiceChangeNotifierProvider(widget.walletId)) + // .editOrAddNote( + // txid: widget.txid, + // note: _labelFieldController.text, + // ); + // if (mounted) { + // Navigator.of(context).pop(); + // } + }, + style: Theme.of(context) + .extension<StackColors>()! + .getPrimaryEnabledButtonStyle(context), + child: Text( + "Save", + style: STextStyles.button(context), + ), + ) + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/receive_view/addresses/receiving_addresses_view.dart b/lib/pages/receive_view/addresses/receiving_addresses_view.dart new file mode 100644 index 000000000..927043373 --- /dev/null +++ b/lib/pages/receive_view/addresses/receiving_addresses_view.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:isar/isar.dart'; +import 'package:stackwallet/db/main_db.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/pages/receive_view/addresses/address_card.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/loading_indicator.dart'; + +class ReceivingAddressesView extends ConsumerWidget { + const ReceivingAddressesView({ + Key? key, + required this.walletId, + required this.isDesktop, + this.clipboard = const ClipboardWrapper(), + }) : super(key: key); + + static const String routeName = "/receivingAddressesView"; + + final String walletId; + final bool isDesktop; + final ClipboardInterface clipboard; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final coin = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).coin)); + return ConditionalParent( + condition: !isDesktop, + builder: (child) => Background( + child: Scaffold( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + appBar: AppBar( + backgroundColor: + Theme.of(context).extension<StackColors>()!.backgroundAppBar, + leading: AppBarBackButton( + onPressed: () { + Navigator.of(context).pop(); + }, + ), + title: Text( + "Receiving addresses", + style: STextStyles.navBarTitle(context), + ), + ), + body: Padding( + padding: const EdgeInsets.all(16), + child: child, + ), + ), + ), + child: FutureBuilder( + future: MainDB.instance + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.receiving) + .and() + .not() + .typeEqualTo(AddressType.nonWallet) + .sortByDerivationIndexDesc() + .findAll(), + builder: (context, AsyncSnapshot<List<Address>> snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.data != null) { + // listview + return ListView.separated( + itemCount: snapshot.data!.length, + separatorBuilder: (_, __) => Container( + height: 10, + ), + itemBuilder: (_, index) => AddressCard( + walletId: walletId, + address: snapshot.data![index], + coin: coin, + ), + ); + } else { + return const Center( + child: LoadingIndicator( + height: 200, + width: 200, + ), + ); + } + }, + ), + ); + } +} diff --git a/lib/pages/receive_view/receive_view.dart b/lib/pages/receive_view/receive_view.dart index c43964779..52283111c 100644 --- a/lib/pages/receive_view/receive_view.dart +++ b/lib/pages/receive_view/receive_view.dart @@ -6,11 +6,13 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/pages/receive_view/addresses/receiving_addresses_view.dart'; import 'package:stackwallet/pages/receive_view/generate_receiving_uri_qr_code_view.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; @@ -19,6 +21,7 @@ import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/custom_loading_overlay.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:tuple/tuple.dart'; class ReceiveView extends ConsumerStatefulWidget { const ReceiveView({ @@ -128,6 +131,94 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> { "Receive ${coin.ticker}", style: STextStyles.navBarTitle(context), ), + actions: [ + Padding( + padding: const EdgeInsets.only( + top: 10, + bottom: 10, + right: 10, + ), + child: AspectRatio( + aspectRatio: 1, + child: AppBarIconButton( + key: const Key("walletNetworkSettingsAddNewNodeViewButton"), + size: 36, + shadows: const [], + color: Theme.of(context).extension<StackColors>()!.background, + icon: SvgPicture.asset( + Assets.svg.verticalEllipsis, + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark, + width: 20, + height: 20, + ), + onPressed: () { + showDialog<dynamic>( + barrierColor: Colors.transparent, + barrierDismissible: true, + context: context, + builder: (_) { + return Stack( + children: [ + Positioned( + top: 9, + right: 10, + child: Container( + decoration: BoxDecoration( + color: Theme.of(context) + .extension<StackColors>()! + .popupBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + // boxShadow: [CFColors.standardBoxShadow], + boxShadow: const [], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GestureDetector( + onTap: () { + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + ReceivingAddressesView.routeName, + arguments: Tuple2(walletId, false), + ); + }, + child: RoundedWhiteContainer( + boxShadow: [ + Theme.of(context) + .extension<StackColors>()! + .standardBoxShadow, + ], + child: Material( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12, + ), + child: Text( + "Address list", + style: STextStyles.field(context), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ], + ); + }, + ); + }, + ), + ), + ), + ], ), body: Padding( padding: const EdgeInsets.all(12), @@ -233,7 +324,7 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> { const SizedBox( height: 20, ), - BlueTextButton( + CustomTextButton( text: "Create new QR code", onTap: () async { unawaited(Navigator.of(context).push( diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index 24bce86e5..f56911a63 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -4,6 +4,7 @@ import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart'; import 'package:stackwallet/pages/send_view/sub_widgets/sending_transaction_dialog.dart'; @@ -12,10 +13,9 @@ import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart'; import 'package:stackwallet/route_generator.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -92,11 +92,10 @@ class _ConfirmTransactionViewState try { String txid; if (widget.isPaynymNotificationTransaction) { - txid = await (manager.wallet as DogecoinWallet) - .confirmNotificationTx(preparedTx: transactionInfo); + txid = await (manager.wallet as PaynymWalletInterface) + .broadcastNotificationTx(preparedTx: transactionInfo); } else if (widget.isPaynymTransaction) { - // - throw UnimplementedError("paynym send not implemented yet"); + txid = await manager.confirmSend(txData: transactionInfo); } else { final coin = manager.coin; if ((coin == Coin.firo || coin == Coin.firoTestNet) && @@ -334,14 +333,20 @@ class _ConfirmTransactionViewState crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( - "Recipient", + widget.isPaynymTransaction + ? "PayNym recipient" + : "Recipient", style: STextStyles.smallMed12(context), ), const SizedBox( height: 4, ), Text( - "${transactionInfo["address"] ?? "ERROR"}", + widget.isPaynymTransaction + ? (transactionInfo["paynymAccountLite"] + as PaynymAccountLite) + .nymName + : "${transactionInfo["address"] ?? "ERROR"}", style: STextStyles.itemSubtitle12(context), ), ], diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index f687ab9a6..eab3d0638 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -1,11 +1,13 @@ import 'dart:async'; +import 'package:bip47/bip47.dart'; import 'package:cw_core/monero_transaction_priority.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/models/send_view_auto_fill_data.dart'; import 'package:stackwallet/pages/address_book_views/address_book_view.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; @@ -19,6 +21,7 @@ import 'package:stackwallet/providers/wallet/public_private_balance_state_provid import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; import 'package:stackwallet/services/coins/manager.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/address_utils.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/barcode_scanner_interface.dart'; @@ -52,6 +55,7 @@ class SendView extends ConsumerStatefulWidget { this.autoFillData, this.clipboard = const ClipboardWrapper(), this.barcodeScanner = const BarcodeScannerWrapper(), + this.accountLite, }) : super(key: key); static const String routeName = "/sendView"; @@ -61,6 +65,7 @@ class SendView extends ConsumerStatefulWidget { final SendViewAutoFillData? autoFillData; final ClipboardInterface clipboard; final BarcodeScannerInterface barcodeScanner; + final PaynymAccountLite? accountLite; @override ConsumerState<SendView> createState() => _SendViewState(); @@ -159,12 +164,17 @@ class _SendViewState extends ConsumerState<SendView> { } void _updatePreviewButtonState(String? address, Decimal? amount) { - final isValidAddress = ref - .read(walletsChangeNotifierProvider) - .getManager(walletId) - .validateAddress(address ?? ""); - ref.read(previewTxButtonStateProvider.state).state = - (isValidAddress && amount != null && amount > Decimal.zero); + if (isPaynymSend) { + ref.read(previewTxButtonStateProvider.state).state = + (amount != null && amount > Decimal.zero); + } else { + final isValidAddress = ref + .read(walletsChangeNotifierProvider) + .getManager(walletId) + .validateAddress(address ?? ""); + ref.read(previewTxButtonStateProvider.state).state = + (isValidAddress && amount != null && amount > Decimal.zero); + } } late Future<String> _calculateFeesFuture; @@ -266,9 +276,9 @@ class _SendViewState extends ConsumerState<SendView> { Decimal? balance; if (ref.read(publicPrivateBalanceStateProvider.state).state == "Private") { - balance = await wallet.availablePrivateBalance(); + balance = wallet.availablePrivateBalance(); } else { - balance = await wallet.availablePublicBalance(); + balance = wallet.availablePublicBalance(); } return Format.localizedStringAsFixed( @@ -278,6 +288,228 @@ class _SendViewState extends ConsumerState<SendView> { return null; } + Future<void> _previewTransaction() async { + // wait for keyboard to disappear + FocusScope.of(context).unfocus(); + await Future<void>.delayed( + const Duration(milliseconds: 100), + ); + final manager = + ref.read(walletsChangeNotifierProvider).getManager(walletId); + + // // TODO: remove the need for this!! + // final bool isOwnAddress = + // await manager.isOwnAddress(_address!); + // if (isOwnAddress && coin != Coin.dogecoinTestNet) { + // await showDialog<dynamic>( + // context: context, + // useSafeArea: false, + // barrierDismissible: true, + // builder: (context) { + // return StackDialog( + // title: "Transaction failed", + // message: + // "Sending to self is currently disabled", + // rightButton: TextButton( + // style: Theme.of(context) + // .extension<StackColors>()! + // .getSecondaryEnabledButtonColor( + // context), + // child: Text( + // "Ok", + // style: STextStyles.button( + // context) + // .copyWith( + // color: Theme.of(context) + // .extension< + // StackColors>()! + // .accentColorDark), + // ), + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ); + // }, + // ); + // return; + // } + + final amount = Format.decimalAmountToSatoshis(_amountToSend!, coin); + int availableBalance; + if ((coin == Coin.firo || coin == Coin.firoTestNet)) { + if (ref.read(publicPrivateBalanceStateProvider.state).state == + "Private") { + availableBalance = Format.decimalAmountToSatoshis( + (manager.wallet as FiroWallet).availablePrivateBalance(), coin); + } else { + availableBalance = Format.decimalAmountToSatoshis( + (manager.wallet as FiroWallet).availablePublicBalance(), coin); + } + } else { + availableBalance = + Format.decimalAmountToSatoshis(manager.balance.getSpendable(), coin); + } + + // confirm send all + if (amount == availableBalance) { + final bool? shouldSendAll = await showDialog<bool>( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return StackDialog( + title: "Confirm send all", + message: + "You are about to send your entire balance. Would you like to continue?", + leftButton: TextButton( + style: Theme.of(context) + .extension<StackColors>()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Cancel", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark), + ), + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + rightButton: TextButton( + style: Theme.of(context) + .extension<StackColors>()! + .getPrimaryEnabledButtonStyle(context), + child: Text( + "Yes", + style: STextStyles.button(context), + ), + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ); + }, + ); + + if (shouldSendAll == null || shouldSendAll == false) { + // cancel preview + return; + } + } + + try { + bool wasCancelled = false; + + unawaited( + showDialog<dynamic>( + context: context, + useSafeArea: false, + barrierDismissible: false, + builder: (context) { + return BuildingTransactionDialog( + onCancel: () { + wasCancelled = true; + + Navigator.of(context).pop(); + }, + ); + }, + ), + ); + + Map<String, dynamic> txData; + + if (isPaynymSend) { + final wallet = manager.wallet as PaynymWalletInterface; + final paymentCode = PaymentCode.fromPaymentCode( + widget.accountLite!.code, + wallet.networkType, + ); + final feeRate = ref.read(feeRateTypeStateProvider); + txData = await wallet.preparePaymentCodeSend( + paymentCode: paymentCode, + satoshiAmount: amount, + args: {"feeRate": feeRate}, + ); + } else if ((coin == Coin.firo || coin == Coin.firoTestNet) && + ref.read(publicPrivateBalanceStateProvider.state).state != + "Private") { + txData = await (manager.wallet as FiroWallet).prepareSendPublic( + address: _address!, + satoshiAmount: amount, + args: {"feeRate": ref.read(feeRateTypeStateProvider)}, + ); + } else { + txData = await manager.prepareSend( + address: _address!, + satoshiAmount: amount, + args: {"feeRate": ref.read(feeRateTypeStateProvider)}, + ); + } + + if (!wasCancelled && mounted) { + // pop building dialog + Navigator.of(context).pop(); + txData["note"] = noteController.text; + if (isPaynymSend) { + txData["paynymAccountLite"] = widget.accountLite!; + } else { + txData["address"] = _address; + } + + unawaited(Navigator.of(context).push( + RouteGenerator.getRoute( + shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute, + builder: (_) => ConfirmTransactionView( + transactionInfo: txData, + walletId: walletId, + isPaynymTransaction: isPaynymSend, + ), + settings: const RouteSettings( + name: ConfirmTransactionView.routeName, + ), + ), + )); + } + } catch (e) { + if (mounted) { + // pop building dialog + Navigator.of(context).pop(); + + unawaited(showDialog<dynamic>( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return StackDialog( + title: "Transaction failed", + message: e.toString(), + rightButton: TextButton( + style: Theme.of(context) + .extension<StackColors>()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Ok", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark), + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ); + }, + )); + } + } + } + + bool get isPaynymSend => widget.accountLite != null; + @override void initState() { ref.refresh(feeSheetSessionCacheProvider); @@ -307,6 +539,11 @@ class _SendViewState extends ConsumerState<SendView> { _addressToggleFlag = true; } + if (isPaynymSend) { + sendToController.text = widget.accountLite!.nymName; + noteController.text = "PayNym send"; + } + if (coin != Coin.epicCash) { _cryptoFocus.addListener(() { if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) { @@ -442,48 +679,38 @@ class _SendViewState extends ConsumerState<SendView> { const SizedBox( width: 6, ), - if (coin != Coin.firo && - coin != Coin.firoTestNet) - Expanded( - child: Text( + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( ref.watch(provider.select( (value) => value.walletName)), - style: STextStyles.titleBold12(context), + style: STextStyles.titleBold12(context) + .copyWith(fontSize: 14), overflow: TextOverflow.ellipsis, maxLines: 1, ), - ), - if (coin == Coin.firo || - coin == Coin.firoTestNet) - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - ref.watch(provider.select( - (value) => value.walletName)), - style: - STextStyles.titleBold12(context) - .copyWith(fontSize: 14), - ), - // const SizedBox( - // height: 2, - // ), + // const SizedBox( + // height: 2, + // ), + if (coin == Coin.firo || + coin == Coin.firoTestNet) Text( "${ref.watch(publicPrivateBalanceStateProvider.state).state} balance", style: STextStyles.label(context) .copyWith(fontSize: 10), ), - ], - ), - if (coin != Coin.firo && - coin != Coin.firoTestNet) - const SizedBox( - width: 10, - ), - if (coin == Coin.firo || - coin == Coin.firoTestNet) - const Spacer(), + if (coin != Coin.firo && + coin != Coin.firoTestNet) + Text( + "Available balance", + style: STextStyles.label(context) + .copyWith(fontSize: 10), + ), + ], + ), + const Spacer(), FutureBuilder( // TODO redo this widget now that its not actually a future future: (coin != Coin.firo && @@ -609,102 +836,253 @@ class _SendViewState extends ConsumerState<SendView> { height: 16, ), Text( - "Send to", + isPaynymSend ? "Send to PayNym address" : "Send to", style: STextStyles.smallMed12(context), textAlign: TextAlign.left, ), const SizedBox( height: 8, ), - ClipRRect( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - child: TextField( - key: const Key("sendViewAddressFieldKey"), + if (isPaynymSend) + TextField( + key: const Key("sendViewPaynymAddressFieldKey"), controller: sendToController, - readOnly: false, - autocorrect: false, - enableSuggestions: false, - // inputFormatters: <TextInputFormatter>[ - // FilteringTextInputFormatter.allow( - // RegExp("[a-zA-Z0-9]{34}")), - // ], - toolbarOptions: const ToolbarOptions( - copy: false, - cut: false, - paste: true, - selectAll: false, + enabled: false, + readOnly: true, + style: STextStyles.fieldLabel(context), + ), + if (!isPaynymSend) + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, ), - onChanged: (newValue) { - _address = newValue; - _updatePreviewButtonState( - _address, _amountToSend); - - setState(() { - _addressToggleFlag = newValue.isNotEmpty; - }); - }, - focusNode: _addressFocusNode, - style: STextStyles.field(context), - decoration: standardInputDecoration( - "Enter ${coin.ticker} address", - _addressFocusNode, - context, - ).copyWith( - contentPadding: const EdgeInsets.only( - left: 16, - top: 6, - bottom: 8, - right: 5, + child: TextField( + key: const Key("sendViewAddressFieldKey"), + controller: sendToController, + readOnly: false, + autocorrect: false, + enableSuggestions: false, + // inputFormatters: <TextInputFormatter>[ + // FilteringTextInputFormatter.allow( + // RegExp("[a-zA-Z0-9]{34}")), + // ], + toolbarOptions: const ToolbarOptions( + copy: false, + cut: false, + paste: true, + selectAll: false, ), - suffixIcon: Padding( - padding: sendToController.text.isEmpty - ? const EdgeInsets.only(right: 8) - : const EdgeInsets.only(right: 0), - child: UnconstrainedBox( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceAround, - children: [ - _addressToggleFlag - ? TextFieldIconButton( - key: const Key( - "sendViewClearAddressFieldButtonKey"), - onTap: () { - sendToController.text = ""; - _address = ""; - _updatePreviewButtonState( - _address, _amountToSend); - setState(() { - _addressToggleFlag = false; - }); - }, - child: const XIcon(), - ) - : TextFieldIconButton( - key: const Key( - "sendViewPasteAddressFieldButtonKey"), - onTap: () async { - final ClipboardData? data = - await clipboard.getData( - Clipboard.kTextPlain); - if (data?.text != null && - data!.text!.isNotEmpty) { - String content = - data.text!.trim(); - if (content - .contains("\n")) { - content = - content.substring( - 0, - content.indexOf( - "\n")); + onChanged: (newValue) { + _address = newValue; + _updatePreviewButtonState( + _address, _amountToSend); + + setState(() { + _addressToggleFlag = newValue.isNotEmpty; + }); + }, + focusNode: _addressFocusNode, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Enter ${coin.ticker} address", + _addressFocusNode, + context, + ).copyWith( + contentPadding: const EdgeInsets.only( + left: 16, + top: 6, + bottom: 8, + right: 5, + ), + suffixIcon: Padding( + padding: sendToController.text.isEmpty + ? const EdgeInsets.only(right: 8) + : const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + _addressToggleFlag + ? TextFieldIconButton( + key: const Key( + "sendViewClearAddressFieldButtonKey"), + onTap: () { + sendToController.text = ""; + _address = ""; + _updatePreviewButtonState( + _address, + _amountToSend); + setState(() { + _addressToggleFlag = + false; + }); + }, + child: const XIcon(), + ) + : TextFieldIconButton( + key: const Key( + "sendViewPasteAddressFieldButtonKey"), + onTap: () async { + final ClipboardData? data = + await clipboard.getData( + Clipboard + .kTextPlain); + if (data?.text != null && + data! + .text!.isNotEmpty) { + String content = + data.text!.trim(); + if (content + .contains("\n")) { + content = + content.substring( + 0, + content.indexOf( + "\n")); + } + + sendToController.text = + content; + _address = content; + + _updatePreviewButtonState( + _address, + _amountToSend); + setState(() { + _addressToggleFlag = + sendToController + .text + .isNotEmpty; + }); + } + }, + child: sendToController + .text.isEmpty + ? const ClipboardIcon() + : const XIcon(), + ), + if (sendToController.text.isEmpty) + TextFieldIconButton( + key: const Key( + "sendViewAddressBookButtonKey"), + onTap: () { + Navigator.of(context).pushNamed( + AddressBookView.routeName, + arguments: widget.coin, + ); + }, + child: const AddressBookIcon(), + ), + if (sendToController.text.isEmpty) + TextFieldIconButton( + key: const Key( + "sendViewScanQrButtonKey"), + onTap: () async { + try { + // ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = false; + if (FocusScope.of(context) + .hasFocus) { + FocusScope.of(context) + .unfocus(); + await Future<void>.delayed( + const Duration( + milliseconds: 75)); + } + + final qrResult = + await scanner.scan(); + + // Future<void>.delayed( + // const Duration(seconds: 2), + // () => ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = true, + // ); + + 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) { + noteController.text = + results["message"]!; + } else if (results[ + "label"] != + null) { + noteController.text = + results["label"]!; } + // autofill amount field + if (results["amount"] != + null) { + final amount = + Decimal.parse(results[ + "amount"]!); + cryptoAmountController + .text = + Format + .localizedStringAsFixed( + value: amount, + locale: ref + .read( + localeServiceChangeNotifierProvider) + .locale, + decimalPlaces: Constants + .decimalPlacesForCoin( + coin), + ); + amount.toString(); + _amountToSend = amount; + } + + _updatePreviewButtonState( + _address, + _amountToSend); + setState(() { + _addressToggleFlag = + sendToController + .text.isNotEmpty; + }); + + // now check for non standard encoded basic address + } else if (ref + .read( + walletsChangeNotifierProvider) + .getManager(walletId) + .validateAddress(qrResult + .rawContent)) { + _address = + qrResult.rawContent; sendToController.text = - content; - _address = content; + _address ?? ""; _updatePreviewButtonState( _address, @@ -715,161 +1093,28 @@ class _SendViewState extends ConsumerState<SendView> { .text.isNotEmpty; }); } - }, - child: sendToController - .text.isEmpty - ? const ClipboardIcon() - : const XIcon(), - ), - if (sendToController.text.isEmpty) - TextFieldIconButton( - key: const Key( - "sendViewAddressBookButtonKey"), - onTap: () { - Navigator.of(context).pushNamed( - AddressBookView.routeName, - arguments: widget.coin, - ); - }, - child: const AddressBookIcon(), - ), - if (sendToController.text.isEmpty) - TextFieldIconButton( - key: const Key( - "sendViewScanQrButtonKey"), - onTap: () async { - try { - // ref - // .read( - // shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = false; - if (FocusScope.of(context) - .hasFocus) { - FocusScope.of(context) - .unfocus(); - await Future<void>.delayed( - const Duration( - milliseconds: 75)); + } on PlatformException catch (e, s) { + // ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = true; + // 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); } - - final qrResult = - await scanner.scan(); - - // Future<void>.delayed( - // const Duration(seconds: 2), - // () => ref - // .read( - // shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = true, - // ); - - 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) { - noteController.text = - results["message"]!; - } else if (results["label"] != - null) { - noteController.text = - results["label"]!; - } - - // autofill amount field - if (results["amount"] != - null) { - final amount = - Decimal.parse( - results["amount"]!); - cryptoAmountController - .text = - Format - .localizedStringAsFixed( - value: amount, - locale: ref - .read( - localeServiceChangeNotifierProvider) - .locale, - decimalPlaces: Constants - .decimalPlacesForCoin( - coin), - ); - amount.toString(); - _amountToSend = amount; - } - - _updatePreviewButtonState( - _address, _amountToSend); - setState(() { - _addressToggleFlag = - sendToController - .text.isNotEmpty; - }); - - // now check for non standard encoded basic address - } else if (ref - .read( - walletsChangeNotifierProvider) - .getManager(walletId) - .validateAddress( - qrResult.rawContent)) { - _address = - qrResult.rawContent; - sendToController.text = - _address ?? ""; - - _updatePreviewButtonState( - _address, _amountToSend); - setState(() { - _addressToggleFlag = - sendToController - .text.isNotEmpty; - }); - } - } on PlatformException catch (e, s) { - // ref - // .read( - // shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = true; - // 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); - } - }, - child: const QrCodeIcon(), - ) - ], + }, + child: const QrCodeIcon(), + ) + ], + ), ), ), ), ), ), - ), Builder( builder: (_) { final error = _updateInvalidAddressText( @@ -1059,7 +1304,7 @@ class _SendViewState extends ConsumerState<SendView> { style: STextStyles.smallMed12(context), textAlign: TextAlign.left, ), - BlueTextButton( + CustomTextButton( text: "Send all ${coin.ticker}", onTap: () async { if (coin == Coin.firo || @@ -1072,17 +1317,17 @@ class _SendViewState extends ConsumerState<SendView> { .state) .state == "Private") { - cryptoAmountController.text = - (await firoWallet - .availablePrivateBalance()) - .toStringAsFixed(Constants - .decimalPlacesForCoin(coin)); + cryptoAmountController.text = firoWallet + .availablePrivateBalance() + .toStringAsFixed( + Constants.decimalPlacesForCoin( + coin)); } else { - cryptoAmountController.text = - (await firoWallet - .availablePublicBalance()) - .toStringAsFixed(Constants - .decimalPlacesForCoin(coin)); + cryptoAmountController.text = firoWallet + .availablePublicBalance() + .toStringAsFixed( + Constants.decimalPlacesForCoin( + coin)); } } else { cryptoAmountController.text = (ref @@ -1093,6 +1338,7 @@ class _SendViewState extends ConsumerState<SendView> { Constants.decimalPlacesForCoin( coin)); } + _cryptoAmountChanged(); }, ), ], @@ -1514,253 +1760,7 @@ class _SendViewState extends ConsumerState<SendView> { onPressed: ref .watch(previewTxButtonStateProvider.state) .state - ? () async { - // wait for keyboard to disappear - FocusScope.of(context).unfocus(); - await Future<void>.delayed( - const Duration(milliseconds: 100), - ); - final manager = ref - .read(walletsChangeNotifierProvider) - .getManager(walletId); - - // // TODO: remove the need for this!! - // final bool isOwnAddress = - // await manager.isOwnAddress(_address!); - // if (isOwnAddress && coin != Coin.dogecoinTestNet) { - // await showDialog<dynamic>( - // context: context, - // useSafeArea: false, - // barrierDismissible: true, - // builder: (context) { - // return StackDialog( - // title: "Transaction failed", - // message: - // "Sending to self is currently disabled", - // rightButton: TextButton( - // style: Theme.of(context) - // .extension<StackColors>()! - // .getSecondaryEnabledButtonColor( - // context), - // child: Text( - // "Ok", - // style: STextStyles.button( - // context) - // .copyWith( - // color: Theme.of(context) - // .extension< - // StackColors>()! - // .accentColorDark), - // ), - // onPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // }, - // ); - // return; - // } - - final amount = - Format.decimalAmountToSatoshis( - _amountToSend!, coin); - int availableBalance; - if ((coin == Coin.firo || - coin == Coin.firoTestNet)) { - if (ref - .read( - publicPrivateBalanceStateProvider - .state) - .state == - "Private") { - availableBalance = - Format.decimalAmountToSatoshis( - (manager.wallet as FiroWallet) - .availablePrivateBalance(), - coin); - } else { - availableBalance = - Format.decimalAmountToSatoshis( - (manager.wallet as FiroWallet) - .availablePublicBalance(), - coin); - } - } else { - availableBalance = - Format.decimalAmountToSatoshis( - manager.balance.getSpendable(), - coin); - } - - // confirm send all - if (amount == availableBalance) { - final bool? shouldSendAll = - await showDialog<bool>( - context: context, - useSafeArea: false, - barrierDismissible: true, - builder: (context) { - return StackDialog( - title: "Confirm send all", - message: - "You are about to send your entire balance. Would you like to continue?", - leftButton: TextButton( - style: Theme.of(context) - .extension<StackColors>()! - .getSecondaryEnabledButtonStyle( - context), - child: Text( - "Cancel", - style: STextStyles.button( - context) - .copyWith( - color: Theme.of(context) - .extension< - StackColors>()! - .accentColorDark), - ), - onPressed: () { - Navigator.of(context) - .pop(false); - }, - ), - rightButton: TextButton( - style: Theme.of(context) - .extension<StackColors>()! - .getPrimaryEnabledButtonStyle( - context), - child: Text( - "Yes", - style: - STextStyles.button(context), - ), - onPressed: () { - Navigator.of(context).pop(true); - }, - ), - ); - }, - ); - - if (shouldSendAll == null || - shouldSendAll == false) { - // cancel preview - return; - } - } - - try { - bool wasCancelled = false; - - unawaited(showDialog<dynamic>( - context: context, - useSafeArea: false, - barrierDismissible: false, - builder: (context) { - return BuildingTransactionDialog( - onCancel: () { - wasCancelled = true; - - Navigator.of(context).pop(); - }, - ); - }, - )); - - Map<String, dynamic> txData; - - if ((coin == Coin.firo || - coin == Coin.firoTestNet) && - ref - .read( - publicPrivateBalanceStateProvider - .state) - .state != - "Private") { - txData = - await (manager.wallet as FiroWallet) - .prepareSendPublic( - address: _address!, - satoshiAmount: amount, - args: { - "feeRate": ref - .read(feeRateTypeStateProvider) - }, - ); - } else { - txData = await manager.prepareSend( - address: _address!, - satoshiAmount: amount, - args: { - "feeRate": ref - .read(feeRateTypeStateProvider) - }, - ); - } - - if (!wasCancelled && mounted) { - // pop building dialog - Navigator.of(context).pop(); - txData["note"] = noteController.text; - txData["address"] = _address; - - unawaited(Navigator.of(context).push( - RouteGenerator.getRoute( - shouldUseMaterialRoute: - RouteGenerator - .useMaterialPageRoute, - builder: (_) => - ConfirmTransactionView( - transactionInfo: txData, - walletId: walletId, - ), - settings: const RouteSettings( - name: ConfirmTransactionView - .routeName, - ), - ), - )); - } - } catch (e) { - if (mounted) { - // pop building dialog - Navigator.of(context).pop(); - - unawaited(showDialog<dynamic>( - context: context, - useSafeArea: false, - barrierDismissible: true, - builder: (context) { - return StackDialog( - title: "Transaction failed", - message: e.toString(), - rightButton: TextButton( - style: Theme.of(context) - .extension<StackColors>()! - .getSecondaryEnabledButtonStyle( - context), - child: Text( - "Ok", - style: STextStyles.button( - context) - .copyWith( - color: Theme.of( - context) - .extension< - StackColors>()! - .accentColorDark), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ); - }, - )); - } - } - } + ? _previewTransaction : null, style: ref .watch(previewTxButtonStateProvider.state) 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 a1e78ba7d..bf0f4a507 100644 --- a/lib/pages/settings_views/global_settings_view/about_view.dart +++ b/lib/pages/settings_views/global_settings_view/about_view.dart @@ -484,7 +484,7 @@ class AboutView extends ConsumerWidget { const SizedBox( height: 4, ), - BlueTextButton( + CustomTextButton( text: "https://stackwallet.com", onTap: () { launchUrl( 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 5c12fb1ad..d86dbe272 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 @@ -282,7 +282,7 @@ class _DebugViewState extends ConsumerState<DebugView> { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BlueTextButton( + CustomTextButton( text: "Save Debug Info to clipboard", onTap: () async { try { @@ -350,7 +350,7 @@ class _DebugViewState extends ConsumerState<DebugView> { }, ), const Spacer(), - BlueTextButton( + CustomTextButton( text: "Save logs to file", onTap: () async { final systemfile = SWBFileSystem(); diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart index 91e6871f3..85d28eb66 100644 --- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart +++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart @@ -92,7 +92,7 @@ class _CoinNodesViewState extends ConsumerState<CoinNodesView> { ), textAlign: TextAlign.left, ), - BlueTextButton( + CustomTextButton( text: "Add new node", onTap: () { Navigator.of(context).pushNamed( diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart index 85fd9c1e9..6a43d963e 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart @@ -327,7 +327,7 @@ class _AutoBackupViewState extends ConsumerState<AutoBackupView> { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - BlueTextButton( + CustomTextButton( text: "Back up now", onTap: () { ref.read(autoSWBServiceProvider).doBackup(); @@ -448,7 +448,7 @@ class _AutoBackupViewState extends ConsumerState<AutoBackupView> { height: 20, ), Center( - child: BlueTextButton( + child: CustomTextButton( text: "Edit Auto Backup", onTap: () async { Navigator.of(context) diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart index da39b1017..0435d023b 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart @@ -2,6 +2,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/stack_dialog.dart'; class RescanningDialog extends StatefulWidget { @@ -21,9 +24,12 @@ class _RescanningDialogState extends State<RescanningDialog> late AnimationController? _spinController; late Animation<double> _spinAnimation; + late final bool isDesktop; + // late final VoidCallback onCancel; @override void initState() { + isDesktop = Util.isDesktop; // onCancel = widget.onCancel; _spinController = AnimationController( @@ -53,33 +59,42 @@ class _RescanningDialogState extends State<RescanningDialog> onWillPop: () async { return false; }, - child: StackDialog( - title: "Rescanning blockchain", - message: "This may take a while. Please do not exit this screen.", - icon: RotationTransition( - turns: _spinAnimation, - child: SvgPicture.asset( - Assets.svg.arrowRotate3, - width: 24, - height: 24, - color: Theme.of(context).extension<StackColors>()!.accentColorDark, - ), + child: ConditionalParent( + condition: isDesktop, + builder: (child) => DesktopDialog( + maxHeight: 200, + maxWidth: 500, + child: child, + ), + child: StackDialog( + title: "Rescanning blockchain", + message: "This may take a while. Please do not exit this screen.", + icon: RotationTransition( + turns: _spinAnimation, + child: SvgPicture.asset( + Assets.svg.arrowRotate3, + width: 24, + height: 24, + color: + Theme.of(context).extension<StackColors>()!.accentColorDark, + ), + ), + // rightButton: TextButton( + // style: Theme.of(context).textButtonTheme.style?.copyWith( + // backgroundColor: MaterialStateProperty.all<Color>( + // CFColors.buttonGray, + // ), + // ), + // child: Text( + // "Cancel", + // style: STextStyles.itemSubtitle12(context), + // ), + // onPressed: () { + // Navigator.of(context).pop(); + // onCancel.call(); + // }, + // ), ), - // rightButton: TextButton( - // style: Theme.of(context).textButtonTheme.style?.copyWith( - // backgroundColor: MaterialStateProperty.all<Color>( - // CFColors.buttonGray, - // ), - // ), - // child: Text( - // "Cancel", - // style: STextStyles.itemSubtitle12(context), - // ), - // onPressed: () { - // Navigator.of(context).pop(); - // onCancel.call(); - // }, - // ), ), ); } 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 cc552279c..526ef0e79 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 @@ -76,6 +76,8 @@ class _WalletNetworkSettingsViewState StreamSubscription<dynamic>? _blocksRemainingSubscription; // late StreamSubscription _nodeStatusSubscription; + late final bool isDesktop; + late double _percent; late int _blocksRemaining; bool _advancedIsExpanded = false; @@ -114,7 +116,7 @@ class _WalletNetworkSettingsViewState if (mounted) { // pop rescanning dialog - Navigator.pop(context); + Navigator.of(context, rootNavigator: isDesktop).pop(); // show success await showDialog<dynamic>( @@ -132,7 +134,7 @@ class _WalletNetworkSettingsViewState style: STextStyles.itemSubtitle12(context), ), onPressed: () { - Navigator.of(context).pop(); + Navigator.of(context, rootNavigator: isDesktop).pop(); }, ), ), @@ -143,7 +145,7 @@ class _WalletNetworkSettingsViewState if (mounted) { // pop rescanning dialog - Navigator.pop(context); + Navigator.of(context, rootNavigator: isDesktop).pop(); // show error await showDialog<dynamic>( @@ -162,7 +164,7 @@ class _WalletNetworkSettingsViewState style: STextStyles.itemSubtitle12(context), ), onPressed: () { - Navigator.of(context).pop(); + Navigator.of(context, rootNavigator: isDesktop).pop(); }, ), ), @@ -183,6 +185,7 @@ class _WalletNetworkSettingsViewState @override void initState() { + isDesktop = Util.isDesktop; _currentSyncStatus = widget.initialSyncStatus; // _currentNodeStatus = widget.initialNodeStatus; if (_currentSyncStatus == WalletSyncStatus.synced) { @@ -270,7 +273,6 @@ class _WalletNetworkSettingsViewState @override Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; - final bool isDesktop = Util.isDesktop; final progressLength = isDesktop ? 430.0 @@ -747,7 +749,7 @@ class _WalletNetworkSettingsViewState ? STextStyles.desktopTextExtraExtraSmall(context) : STextStyles.smallMed12(context), ), - BlueTextButton( + CustomTextButton( text: "Add new node", onTap: () { Navigator.of(context).pushNamed( @@ -878,7 +880,7 @@ class _WalletNetworkSettingsViewState top: 16, bottom: 6, ), - child: BlueTextButton( + child: CustomTextButton( text: "Rescan", onTap: () async { await Navigator.of(context).push( diff --git a/lib/pages/wallet_view/sub_widgets/transactions_list.dart b/lib/pages/wallet_view/sub_widgets/transactions_list.dart index 71f56ccad..0c48e69b6 100644 --- a/lib/pages/wallet_view/sub_widgets/transactions_list.dart +++ b/lib/pages/wallet_view/sub_widgets/transactions_list.dart @@ -5,7 +5,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/pages/exchange_view/trade_details_view.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart'; -import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart'; import 'package:stackwallet/providers/global/trades_service_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/route_generator.dart'; @@ -21,6 +20,8 @@ import 'package:stackwallet/widgets/trade_card.dart'; import 'package:stackwallet/widgets/transaction_card.dart'; import 'package:tuple/tuple.dart'; +import '../../../utilities/enums/coin_enum.dart'; + class TransactionsList extends ConsumerStatefulWidget { const TransactionsList({ Key? key, @@ -68,11 +69,18 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { BuildContext context, Transaction tx, BorderRadius? radius, + Coin coin, ) { final matchingTrades = ref .read(tradesServiceProvider) .trades .where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid); + + final isConfirmed = tx.isConfirmed( + ref.watch( + widget.managerProvider.select((value) => value.currentHeight)), + coin.requiredConfirmations); + if (tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) { final trade = matchingTrades.first; return Container( @@ -85,7 +93,9 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { children: [ TransactionCard( // this may mess with combined firo transactions - key: Key(tx.txid + tx.type.name + tx.address.value.toString()), // + key: isConfirmed + ? Key(tx.txid + tx.type.name + tx.address.value.toString()) + : UniqueKey(), // transaction: tx, walletId: widget.walletId, ), @@ -180,7 +190,9 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { ), child: TransactionCard( // this may mess with combined firo transactions - key: Key(tx.txid + tx.type.name + tx.address.value.toString()), // + key: isConfirmed + ? Key(tx.txid + tx.type.name + tx.address.value.toString()) + : UniqueKey(), transaction: tx, walletId: widget.walletId, ), @@ -188,13 +200,6 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { } } - void updateHeightProvider(Manager manager) { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - ref.read(currentHeightProvider(manager.coin).state).state = - manager.currentHeight; - }); - } - @override void initState() { managerProvider = widget.managerProvider; @@ -203,14 +208,9 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { @override Widget build(BuildContext context) { - // final managerProvider = ref - // .watch(walletsChangeNotifierProvider) - // .getManagerProvider(widget.walletId); - final manager = ref.watch(walletsChangeNotifierProvider .select((value) => value.getManager(widget.walletId))); - updateHeightProvider(manager); return FutureBuilder( future: manager.transactions, builder: (fbContext, AsyncSnapshot<List<Transaction>> snapshot) { @@ -264,7 +264,7 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { radius = _borderRadiusFirst; } final tx = _transactions2[index]; - return itemBuilder(context, tx, radius); + return itemBuilder(context, tx, radius, manager.coin); }, separatorBuilder: (context, index) { return Container( @@ -291,7 +291,7 @@ class _TransactionsListState extends ConsumerState<TransactionsList> { radius = _borderRadiusFirst; } final tx = _transactions2[index]; - return itemBuilder(context, tx, radius); + return itemBuilder(context, tx, radius, manager.coin); }, ), ); diff --git a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart index 2b7441584..19a785de5 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_navigation_bar.dart @@ -8,16 +8,16 @@ import 'package:stackwallet/pages/paynym/paynym_home_view.dart'; import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/widgets/loading_indicator.dart'; -class WalletNavigationBar extends StatefulWidget { +class WalletNavigationBar extends ConsumerStatefulWidget { const WalletNavigationBar({ Key? key, required this.onReceivePressed, @@ -40,10 +40,11 @@ class WalletNavigationBar extends StatefulWidget { final String walletId; @override - State<WalletNavigationBar> createState() => _WalletNavigationBarState(); + ConsumerState<WalletNavigationBar> createState() => + _WalletNavigationBarState(); } -class _WalletNavigationBarState extends State<WalletNavigationBar> { +class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> { double scale = 0; final duration = const Duration(milliseconds: 200); @@ -61,41 +62,41 @@ class _WalletNavigationBarState extends State<WalletNavigationBar> { child: Column( mainAxisSize: MainAxisSize.min, children: [ - AnimatedOpacity( - opacity: scale, - duration: duration, - child: GestureDetector( - onTap: () {}, - child: Container( - padding: const EdgeInsets.all(16), - width: 146, - decoration: BoxDecoration( - color: - Theme.of(context).extension<StackColors>()!.popupBG, - boxShadow: [ - Theme.of(context) - .extension<StackColors>()! - .standardBoxShadow - ], - borderRadius: BorderRadius.circular( - widget.height / 2.0, - ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Whirlpool", - style: STextStyles.w600_12(context), - ), - ], - ), - ), - ), - ), - const SizedBox( - height: 8, - ), + // AnimatedOpacity( + // opacity: scale, + // duration: duration, + // child: GestureDetector( + // onTap: () {}, + // child: Container( + // padding: const EdgeInsets.all(16), + // width: 146, + // decoration: BoxDecoration( + // color: + // Theme.of(context).extension<StackColors>()!.popupBG, + // boxShadow: [ + // Theme.of(context) + // .extension<StackColors>()! + // .standardBoxShadow + // ], + // borderRadius: BorderRadius.circular( + // widget.height / 2.0, + // ), + // ), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Text( + // "Whirlpool", + // style: STextStyles.w600_12(context), + // ), + // ], + // ), + // ), + // ), + // ), + // const SizedBox( + // height: 8, + // ), AnimatedOpacity( opacity: scale, duration: duration, @@ -114,13 +115,15 @@ class _WalletNavigationBarState extends State<WalletNavigationBar> { ), ); - // todo make generic and not doge specific - final wallet = (ref + final manager = ref .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet); + .getManager(widget.walletId); - final code = await wallet.getPaymentCode(); + final paynymInterface = + manager.wallet as PaynymWalletInterface; + + final code = await paynymInterface.getPaymentCode( + DerivePathTypeExt.primaryFor(manager.coin)); final account = await ref .read(paynymAPIProvider) @@ -172,7 +175,18 @@ class _WalletNavigationBarState extends State<WalletNavigationBar> { children: [ Text( "Paynym", - style: STextStyles.w600_12(context), + style: STextStyles.buttonSmall(context), + ), + const SizedBox( + width: 16, + ), + SvgPicture.asset( + Assets.svg.robotHead, + height: 20, + width: 20, + color: Theme.of(context) + .extension<StackColors>()! + .bottomNavIconIcon, ), ], ), @@ -357,61 +371,6 @@ class _WalletNavigationBarState extends State<WalletNavigationBar> { ), ), ), - if (widget.coin.hasPaynymSupport) - RawMaterialButton( - constraints: const BoxConstraints( - minWidth: 66, - ), - onPressed: () { - if (scale == 0) { - setState(() { - scale = 1; - }); - } else if (scale == 1) { - setState(() { - scale = 0; - }); - } - }, - splashColor: - Theme.of(context).extension<StackColors>()!.highlight, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - widget.height / 2.0, - ), - ), - child: Container( - color: Colors.transparent, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 2.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Spacer(), - const SizedBox( - height: 2, - ), - SvgPicture.asset( - Assets.svg.bars, - width: 20, - height: 20, - ), - const SizedBox( - height: 6, - ), - Text( - "More", - style: STextStyles.buttonSmall(context), - ), - const Spacer(), - ], - ), - ), - ), - ), - const SizedBox( - width: 12, - ), if (widget.coin.hasBuySupport) RawMaterialButton( constraints: const BoxConstraints( @@ -451,10 +410,65 @@ class _WalletNavigationBarState extends State<WalletNavigationBar> { ), ), ), - if (widget.coin.hasBuySupport) - const SizedBox( - width: 12, + if (ref.watch(walletsChangeNotifierProvider.select((value) => + value.getManager(widget.walletId).hasPaynymSupport))) + RawMaterialButton( + constraints: const BoxConstraints( + minWidth: 66, + ), + onPressed: () { + if (scale == 0) { + setState(() { + scale = 1; + }); + } else if (scale == 1) { + setState(() { + scale = 0; + }); + } + }, + splashColor: + Theme.of(context).extension<StackColors>()!.highlight, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + widget.height / 2.0, + ), + ), + child: Container( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 2.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Spacer(), + const SizedBox( + height: 2, + ), + SvgPicture.asset( + Assets.svg.bars, + width: 20, + height: 20, + color: Theme.of(context) + .extension<StackColors>()! + .bottomNavIconIcon, + ), + const SizedBox( + height: 6, + ), + Text( + "More", + style: STextStyles.buttonSmall(context), + ), + const Spacer(), + ], + ), + ), + ), ), + const SizedBox( + width: 12, + ), ], ), ), diff --git a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart index 6ebb5bd1c..c9ba6181b 100644 --- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart +++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart @@ -10,7 +10,6 @@ import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart'; -import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart'; import 'package:stackwallet/providers/global/address_book_service_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/ui/transaction_filter_provider.dart'; @@ -131,7 +130,9 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> { // check if address book name contains contains |= contacts .where((e) => - e.addresses.where((a) => a.address == tx.address).isNotEmpty && + e.addresses + .where((a) => a.address == tx.address.value?.value) + .isNotEmpty && e.name.toLowerCase().contains(keyword)) .isNotEmpty; @@ -853,7 +854,8 @@ class _DesktopTransactionCardRowState prefix = ""; } - final currentHeight = ref.watch(currentHeightProvider(coin).state).state; + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); return Material( color: Theme.of(context).extension<StackColors>()!.popupBG, diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart index f2755f547..5b737a939 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart @@ -11,7 +11,6 @@ import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/dialogs/cancelling_transaction_progress_dialog.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart'; import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; -import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart'; import 'package:stackwallet/providers/global/address_book_service_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'; @@ -298,7 +297,8 @@ class _TransactionDetailsViewState @override Widget build(BuildContext context) { - final currentHeight = ref.watch(currentHeightProvider(coin).state).state; + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); return ConditionalParent( condition: !isDesktop, @@ -1092,7 +1092,7 @@ class _TransactionDetailsViewState height: 8, ), if (coin != Coin.epicCash) - BlueTextButton( + CustomTextButton( text: "Open in block explorer", onTap: () async { final uri = diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart index fd5473b11..04817a843 100644 --- a/lib/pages/wallet_view/wallet_view.dart +++ b/lib/pages/wallet_view/wallet_view.dart @@ -649,7 +649,7 @@ class _WalletViewState extends ConsumerState<WalletView> { .textDark3, ), ), - BlueTextButton( + CustomTextButton( text: "See all", onTap: () { Navigator.of(context).pushNamed( diff --git a/lib/pages/wallets_view/sub_widgets/all_wallets.dart b/lib/pages/wallets_view/sub_widgets/all_wallets.dart index eae7374bf..b63e8eb6e 100644 --- a/lib/pages/wallets_view/sub_widgets/all_wallets.dart +++ b/lib/pages/wallets_view/sub_widgets/all_wallets.dart @@ -24,7 +24,7 @@ class AllWallets extends StatelessWidget { color: Theme.of(context).extension<StackColors>()!.textDark, ), ), - BlueTextButton( + CustomTextButton( text: "Add new", onTap: () { Navigator.of(context).pushNamed(AddWalletView.routeName); diff --git a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart index ad9310df2..518e593b0 100644 --- a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart +++ b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart @@ -66,7 +66,7 @@ class DesktopAddressCard extends StatelessWidget { ), Row( children: [ - BlueTextButton( + CustomTextButton( text: "Copy", onTap: () { clipboard.setData( @@ -87,7 +87,7 @@ class DesktopAddressCard extends StatelessWidget { if (contactId != "default") Consumer( builder: (context, ref, child) { - return BlueTextButton( + return CustomTextButton( text: "Edit", onTap: () async { ref.refresh( diff --git a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_contact_details.dart index 98fce4a0b..4b2eb33a8 100644 --- a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_contact_details.dart +++ b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_contact_details.dart @@ -182,7 +182,7 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> { style: STextStyles.desktopTextExtraExtraSmall(context), ), - BlueTextButton( + CustomTextButton( text: "Add new", onTap: () async { ref.refresh( diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart index 027de6cd7..c4371d4e8 100644 --- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart +++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart @@ -300,8 +300,8 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> { ), if (isStackCoin(ref.watch(desktopExchangeModelProvider .select((value) => value!.receiveTicker)))) - BlueTextButton( - text: "Choose from stack", + CustomTextButton( + text: "Choose from Stack", onTap: selectRecipientAddressFromStack, ), ], @@ -432,8 +432,8 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> { ), if (isStackCoin(ref.watch(desktopExchangeModelProvider .select((value) => value!.sendTicker)))) - BlueTextButton( - text: "Choose from stack", + CustomTextButton( + text: "Choose from Stack", onTap: selectRefundAddressFromStack, ), ], diff --git a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart index 3216949b0..2c1d8a44d 100644 --- a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart +++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart @@ -221,7 +221,7 @@ class _DesktopChooseFromStackState const SizedBox( width: 80, ), - BlueTextButton( + CustomTextButton( text: "Select wallet", onTap: () async { final address = diff --git a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart index 296847d71..b87ca6c6b 100644 --- a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart +++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart @@ -72,7 +72,7 @@ class _DesktopTradeHistoryState extends ConsumerState<DesktopTradeHistory> { "Recent trades", style: STextStyles.desktopTextExtraExtraSmall(context), ), - BlueTextButton( + CustomTextButton( text: "See all", onTap: () { Navigator.of(context) diff --git a/lib/pages_desktop_specific/my_stack_view/desktop_favorite_wallets.dart b/lib/pages_desktop_specific/my_stack_view/desktop_favorite_wallets.dart index 91130fe19..5694c66ed 100644 --- a/lib/pages_desktop_specific/my_stack_view/desktop_favorite_wallets.dart +++ b/lib/pages_desktop_specific/my_stack_view/desktop_favorite_wallets.dart @@ -39,7 +39,7 @@ class DesktopFavoriteWallets extends ConsumerWidget { .textFieldActiveSearchIconRight, ), ), - BlueTextButton( + CustomTextButton( text: "Edit", onTap: () { Navigator.of(context).pushNamed(ManageFavoritesView.routeName); diff --git a/lib/pages_desktop_specific/my_stack_view/my_wallets.dart b/lib/pages_desktop_specific/my_stack_view/my_wallets.dart index 41d0f0ce5..1dd345f74 100644 --- a/lib/pages_desktop_specific/my_stack_view/my_wallets.dart +++ b/lib/pages_desktop_specific/my_stack_view/my_wallets.dart @@ -38,7 +38,7 @@ class _MyWalletsState extends ConsumerState<MyWallets> { ), ), const Spacer(), - BlueTextButton( + CustomTextButton( text: "Add new wallet", onTap: () { Navigator.of( 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 b638d72a1..9b98d4aa8 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 @@ -46,10 +46,15 @@ class _WalletTableState extends ConsumerState<WalletSummaryTable> { VoidCallback? expandOverride; if (providers.length == 1) { - expandOverride = () { - Navigator.of(context).pushNamed( + expandOverride = () async { + final manager = ref.read(providers.first); + if (manager.coin == Coin.monero || + manager.coin == Coin.wownero) { + await manager.initializeExisting(); + } + await Navigator.of(context).pushNamed( DesktopWalletView.routeName, - arguments: ref.read(providers.first).walletId, + arguments: manager.walletId, ); }; } 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 18a9de5a7..8b8a65b58 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 @@ -19,14 +19,14 @@ import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/ui/transaction_filter_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; @@ -209,13 +209,13 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> { ), ); - // todo make generic and not doge specific - final wallet = (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet); + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); - final code = await wallet.getPaymentCode(); + final wallet = manager.wallet as PaynymWalletInterface; + + final code = + await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(manager.coin)); final account = await ref.read(paynymAPIProvider).nym(code.toString()); @@ -445,7 +445,8 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> { ); }, ), - if (coin.hasPaynymSupport) + if (ref.watch(walletsChangeNotifierProvider.select((value) => + value.getManager(widget.walletId).hasPaynymSupport))) SecondaryButton( label: "PayNym", width: 160, diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart index 1277c5c0f..7ae3c51e4 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart @@ -133,7 +133,7 @@ class _ContactListItemState extends ConsumerState<ContactListItem> { ], ), ), - BlueTextButton( + CustomTextButton( text: "Select wallet", onTap: () { Navigator.of(context).pop(e); 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 c4f7eee34..cc63c67a8 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 @@ -987,7 +987,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> { ), textAlign: TextAlign.left, ), - BlueTextButton( + CustomTextButton( text: "Send all ${coin.ticker}", onTap: sendAllTapped, ), diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart index 59e01f0b7..dca501e25 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart @@ -37,7 +37,7 @@ class _RecentDesktopTransactionsState .textFieldActiveSearchIconLeft, ), ), - BlueTextButton( + CustomTextButton( text: "See all", onTap: () { Navigator.of(context).pushNamed( diff --git a/lib/pages_desktop_specific/password/desktop_login_view.dart b/lib/pages_desktop_specific/password/desktop_login_view.dart index 67eab0903..05ad2d2ad 100644 --- a/lib/pages_desktop_specific/password/desktop_login_view.dart +++ b/lib/pages_desktop_specific/password/desktop_login_view.dart @@ -261,7 +261,7 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> { const SizedBox( height: 60, ), - BlueTextButton( + CustomTextButton( text: "Forgot password?", textSize: 20, onTap: () { diff --git a/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart index 37b40b004..e3f086746 100644 --- a/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart +++ b/lib/pages_desktop_specific/settings/settings_menu/backup_and_restore/backup_and_restore_settings.dart @@ -450,7 +450,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> { STextStyles.itemSubtitle( context), ), - BlueTextButton( + CustomTextButton( text: "Back up now", onTap: () { ref 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 18988cb68..242fbfd9f 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 @@ -678,7 +678,7 @@ class DesktopAboutView extends ConsumerWidget { const SizedBox( height: 2, ), - BlueTextButton( + CustomTextButton( text: "https://stackwallet.com", onTap: () { diff --git a/lib/providers/blockchain/dogecoin/current_height_provider.dart b/lib/providers/blockchain/dogecoin/current_height_provider.dart deleted file mode 100644 index 22b6711db..000000000 --- a/lib/providers/blockchain/dogecoin/current_height_provider.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:dart_numerics/dart_numerics.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:stackwallet/utilities/enums/coin_enum.dart'; - -final currentHeightProvider = - StateProvider.family<int, Coin>((ref, coin) => int64MaxValue); diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 371b52311..d1ed6a4bd 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -6,6 +6,8 @@ import 'package:stackwallet/models/buy/response_objects/quote.dart'; import 'package:stackwallet/models/contact_address_entry.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart'; +import 'package:stackwallet/models/isar/models/address/address.dart'; +import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/models/send_view_auto_fill_data.dart'; import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart'; import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart'; @@ -43,6 +45,8 @@ import 'package:stackwallet/pages/paynym/add_new_paynym_follow_view.dart'; import 'package:stackwallet/pages/paynym/paynym_claim_view.dart'; import 'package:stackwallet/pages/paynym/paynym_home_view.dart'; import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart'; +import 'package:stackwallet/pages/receive_view/addresses/edit_address_label_view.dart'; +import 'package:stackwallet/pages/receive_view/addresses/receiving_addresses_view.dart'; import 'package:stackwallet/pages/receive_view/generate_receiving_uri_qr_code_view.dart'; import 'package:stackwallet/pages/receive_view/receive_view.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; @@ -472,6 +476,21 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case EditAddressLabelView.routeName: + if (args is Tuple2<Address, String>) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => EditAddressLabelView( + address: args.item1, + walletId: args.item2, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case EditTradeNoteView.routeName: if (args is Tuple2<String, String>) { return getRoute( @@ -819,6 +838,21 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case ReceivingAddressesView.routeName: + if (args is Tuple2<String, bool>) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => ReceivingAddressesView( + walletId: args.item1, + isDesktop: args.item2, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case SendView.routeName: if (args is Tuple2<String, Coin>) { return getRoute( @@ -843,6 +877,18 @@ class RouteGenerator { name: settings.name, ), ); + } else if (args is Tuple3<String, Coin, PaynymAccountLite>) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => SendView( + walletId: args.item1, + coin: args.item2, + accountLite: args.item3, + ), + settings: RouteSettings( + name: settings.name, + ), + ); } return _routeError("${settings.name} invalid args: ${args.toString()}"); diff --git a/lib/services/buy/buy_response.dart b/lib/services/buy/buy_response.dart index 3198d0a19..6510ece4c 100644 --- a/lib/services/buy/buy_response.dart +++ b/lib/services/buy/buy_response.dart @@ -1,4 +1,8 @@ -enum BuyExceptionType { generic, serializeResponseError } +enum BuyExceptionType { + generic, + serializeResponseError, + cryptoAmountOutOfRange, +} class BuyException implements Exception { String errorMessage; diff --git a/lib/services/buy/simplex/simplex_api.dart b/lib/services/buy/simplex/simplex_api.dart index 4060567f0..37417fcbf 100644 --- a/lib/services/buy/simplex/simplex_api.dart +++ b/lib/services/buy/simplex/simplex_api.dart @@ -210,7 +210,20 @@ class SimplexAPI { BuyResponse<SimplexQuote> _parseQuote(dynamic jsonArray) { try { - String cryptoAmount = "${jsonArray['digital_money']['amount']}"; + // final Map<String, dynamic> lol = + // Map<String, dynamic>.from(jsonArray as Map); + + double? cryptoAmount = jsonArray['digital_money']?['amount'] as double?; + + if (cryptoAmount == null) { + String error = jsonArray['error'] as String; + return BuyResponse( + exception: BuyException( + error, + BuyExceptionType.cryptoAmountOutOfRange, + ), + ); + } SimplexQuote quote = jsonArray['quote'] as SimplexQuote; final SimplexQuote _quote = SimplexQuote( @@ -277,9 +290,9 @@ class SimplexAPI { } final jsonArray = jsonDecode(res.body); // TODO check if valid json if (jsonArray.containsKey('error') as bool) { - if (jsonArray['error'] == true || jsonArray['error'] == 'true') { - throw Exception(jsonArray['message']); - } + if (jsonArray['error'] == true || jsonArray['error'] == 'true') { + throw Exception(jsonArray['message']); + } } SimplexOrder _order = SimplexOrder( diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 595c089eb..60ba85895 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'dart:math'; import 'package:bech32/bech32.dart'; import 'package:bip32/bip32.dart' as bip32; @@ -13,16 +14,18 @@ import 'package:isar/isar.dart'; import 'package:stackwallet/db/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -33,10 +36,12 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; +import 'package:stackwallet/utilities/paynym_is_api.dart'; import 'package:stackwallet/utilities/prefs.dart'; import 'package:tuple/tuple.dart'; import 'package:uuid/uuid.dart'; @@ -50,8 +55,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"; -enum DerivePathType { bip44, bip49, bip84 } - bip32.BIP32 getBip32Node( int chain, int index, @@ -103,7 +106,7 @@ bip32.BIP32 getBip32NodeFromRoot( case DerivePathType.bip84: return root.derivePath("m/84'/$coinType'/0'/$chain/$index"); default: - throw Exception("DerivePathType must not be null."); + throw Exception("DerivePathType $derivePathType not supported"); } } @@ -138,7 +141,8 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { return getBip32Root(args.item1, args.item2); } -class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { +class BitcoinWallet extends CoinServiceAPI + with WalletCache, WalletDB, ElectrumXParsing, PaynymWalletInterface { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); @@ -178,8 +182,16 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { Future<List<isar_models.UTXO>> get utxos => db.getUTXOs(walletId).findAll(); @override - Future<List<isar_models.Transaction>> get transactions => - db.getTransactions(walletId).sortByTimestampDesc().findAll(); + Future<List<isar_models.Transaction>> get transactions => db + .getTransactions(walletId) + .filter() + .not() + .group((q) => q + .subTypeEqualTo(isar_models.TransactionSubType.bip47Notification) + .and() + .typeEqualTo(isar_models.TransactionType.incoming)) + .sortByTimestampDesc() + .findAll(); @override Future<String> get currentReceivingAddress async => @@ -193,7 +205,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip84); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -206,7 +218,20 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip84); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); + + Future<String> get currentChangeAddressP2PKH async => + (await _currentChangeAddressP2PKH).value; + + Future<isar_models.Address> get _currentChangeAddressP2PKH async => + (await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2pkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .sortByDerivationIndexDesc() + .findFirst()) ?? + await _generateAddressForChain(1, 0, DerivePathType.bip44); @override Future<void> exit() async { @@ -241,6 +266,14 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", @@ -403,7 +436,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2wpkh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } final address = isar_models.Address( @@ -491,6 +524,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -664,14 +698,49 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { p2wpkhChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2wpkhReceiveAddressArray, - ...p2wpkhChangeAddressArray, - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } + + // get own payment code + final myCode = await getPaymentCode(DerivePathType.bip44); + + // refresh transactions to pick up any received notification transactions + await _refreshTransactions(); + + final Set<String> codesToCheck = {}; + final nym = await PaynymIsApi().nym(myCode.toString()); + if (nym.value != null) { + for (final follower in nym.value!.followers) { + codesToCheck.add(follower.code); + } + for (final following in nym.value!.following) { + codesToCheck.add(following.code); + } + } + + // restore paynym transactions + await restoreAllHistory( + maxUnusedAddressGap: maxUnusedAddressGap, + maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + paymentCodeStrings: codesToCheck, + ); await _updateUTXOs(); @@ -737,6 +806,13 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } return needsRefresh; + } on NoSuchTransactionException catch (e) { + // TODO: move direct transactions elsewhere + await db.isar.writeTxn(() async { + await db.isar.transactions.deleteByTxidWalletId(e.txid, walletId); + }); + await txTracker.deleteTransaction(e.txid); + return true; } catch (e, s) { Logging.instance.log( "Exception caught in refreshIfThereIsNewData: $e\n$s", @@ -890,6 +966,17 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.0, walletId)); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.1, walletId)); + final myCode = await getPaymentCode(DerivePathType.bip44); + final Set<String> codesToCheck = {}; + final nym = await PaynymIsApi().nym(myCode.toString()); + if (nym.value != null) { + for (final follower in nym.value!.followers) { + codesToCheck.add(follower.code); + } + for (final following in nym.value!.following) { + codesToCheck.add(following.code); + } + } final currentHeight = await chainHeight; const storedHeight = 1; //await storedChainHeight; @@ -906,6 +993,9 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId)); await _checkCurrentReceivingAddressesForTransactions(); + GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.4, walletId)); + await checkAllCurrentReceivingPaynymAddressesForTransactions(); + final fetchFuture = _refreshTransactions(); final utxosRefreshFuture = _updateUTXOs(); GlobalEventBus.instance @@ -924,6 +1014,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .fire(RefreshPercentChangedEvent(0.80, walletId)); await fetchFuture; + await checkForNotificationTransactionsTo(codesToCheck); await getAllTxsToWatch(); GlobalEventBus.instance .fire(RefreshPercentChangedEvent(0.90, walletId)); @@ -1176,46 +1267,31 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _fetchTransactionData(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override @@ -1264,6 +1340,29 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { _secureStore = secureStore; initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); + initPaynymWalletInterface( + walletId: walletId, + walletName: walletName, + network: _network, + coin: coin, + db: db, + electrumXClient: electrumXClient, + secureStorage: secureStore, + getMnemonic: () => mnemonic, + getChainHeight: () => chainHeight, + getCurrentChangeAddress: () => currentChangeAddressP2PKH, + estimateTxFee: estimateTxFee, + prepareSend: prepareSend, + getTxCount: getTxCount, + fetchBuildTxData: fetchBuildTxData, + refresh: refresh, + checkChangeAddressForTransactions: + _checkP2PKHChangeAddressForTransactions, + addDerivation: addDerivation, + addDerivations: addDerivations, + dustLimitP2PKH: DUST_LIMIT_P2PKH, + minConfirms: MINIMUM_CONFIRMATIONS, + ); } @override @@ -1324,62 +1423,11 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .getAddresses(walletId) .filter() .not() - .typeEqualTo(isar_models.AddressType.unknown) - .and() - .not() .typeEqualTo(isar_models.AddressType.nonWallet) .and() - .group((q) => q - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .or() - .subTypeEqualTo(isar_models.AddressSubType.change)) + .not() + .subTypeEqualTo(isar_models.AddressSubType.nonWallet) .findAll(); - // final List<String> allAddresses = []; - // final receivingAddresses = DB.instance.get<dynamic>( - // boxName: walletId, key: 'receivingAddressesP2WPKH') as List<dynamic>; - // final changeAddresses = DB.instance.get<dynamic>( - // boxName: walletId, key: 'changeAddressesP2WPKH') as List<dynamic>; - // final receivingAddressesP2PKH = DB.instance.get<dynamic>( - // boxName: walletId, key: 'receivingAddressesP2PKH') as List<dynamic>; - // final changeAddressesP2PKH = - // DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2PKH') - // as List<dynamic>; - // final receivingAddressesP2SH = DB.instance.get<dynamic>( - // boxName: walletId, key: 'receivingAddressesP2SH') as List<dynamic>; - // final changeAddressesP2SH = - // DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2SH') - // as List<dynamic>; - // - // for (var i = 0; i < receivingAddresses.length; i++) { - // if (!allAddresses.contains(receivingAddresses[i])) { - // allAddresses.add(receivingAddresses[i] as String); - // } - // } - // for (var i = 0; i < changeAddresses.length; i++) { - // if (!allAddresses.contains(changeAddresses[i])) { - // allAddresses.add(changeAddresses[i] as String); - // } - // } - // for (var i = 0; i < receivingAddressesP2PKH.length; i++) { - // if (!allAddresses.contains(receivingAddressesP2PKH[i])) { - // allAddresses.add(receivingAddressesP2PKH[i] as String); - // } - // } - // for (var i = 0; i < changeAddressesP2PKH.length; i++) { - // if (!allAddresses.contains(changeAddressesP2PKH[i])) { - // allAddresses.add(changeAddressesP2PKH[i] as String); - // } - // } - // for (var i = 0; i < receivingAddressesP2SH.length; i++) { - // if (!allAddresses.contains(receivingAddressesP2SH[i])) { - // allAddresses.add(receivingAddressesP2SH[i] as String); - // } - // } - // for (var i = 0; i < changeAddressesP2SH.length; i++) { - // if (!allAddresses.contains(changeAddressesP2SH[i])) { - // allAddresses.add(changeAddressesP2SH[i] as String); - // } - // } return allAddresses; } @@ -1509,6 +1557,8 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { address = P2WPKH(network: _network, data: data).data.address!; addrType = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType $derivePathType not supported"); } // add generated address & info to derivations @@ -1555,6 +1605,8 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: type = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType unsupported"); } address = await db .getAddresses(walletId) @@ -1582,6 +1634,8 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: key = "${walletId}_${chainId}DerivationsP2WPKH"; break; + default: + throw Exception("DerivePathType unsupported"); } return key; } @@ -1754,15 +1808,34 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { coin: coin, ); - // todo check here if we should mark as blocked + // fetch stored tx to see if paynym notification tx and block utxo + final storedTx = await db.getTransaction( + walletId, + fetchedUtxoList[i][j]["tx_hash"] as String, + ); + + bool shouldBlock = false; + String? blockReason; + + if (storedTx?.subType == + isar_models.TransactionSubType.bip47Notification && + storedTx?.type == isar_models.TransactionType.incoming) { + // probably safe to assume this is an incoming tx as it is a utxo + // belonging to this wallet. The extra check may be redundant but + // just in case... + + shouldBlock = true; + blockReason = "Incoming paynym notification transaction."; + } + final utxo = isar_models.UTXO( walletId: walletId, txid: txn["txid"] as String, vout: fetchedUtxoList[i][j]["tx_pos"] as int, value: fetchedUtxoList[i][j]["value"] as int, name: "", - isBlocked: false, - blockedReason: null, + isBlocked: shouldBlock, + blockedReason: blockReason, isCoinbase: txn["is_coinbase"] as bool? ?? false, blockHash: txn["blockhash"] as String?, blockHeight: fetchedUtxoList[i][j]["height"] as int?, @@ -1790,7 +1863,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); @@ -1868,7 +1941,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1887,7 +1960,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1907,7 +1980,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip84); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1926,12 +1999,56 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", + level: LogLevel.Error); + rethrow; + } + } + + Future<void> _checkP2PKHChangeAddressForTransactions() async { + try { + final currentChange = await _currentChangeAddressP2PKH; + final int txCount = await getTxCount(address: currentChange.value); + Logging.instance.log( + 'Number of txs for current change address $currentChange: $txCount', + level: LogLevel.Info); + + if (txCount >= 1 || currentChange.derivationIndex < 0) { + // First increment the change index + final newChangeIndex = currentChange.derivationIndex + 1; + + // Use new index to derive a new change address + final newChangeAddress = await _generateAddressForChain( + 1, newChangeIndex, DerivePathType.bip44); + + final existing = await db + .getAddresses(walletId) + .filter() + .valueEqualTo(newChangeAddress.value) + .findFirst(); + if (existing == null) { + // Add that new change address + await db.putAddress(newChangeAddress); + } else { + // we need to update the address + await db.updateAddress(existing, newChangeAddress); + } + // keep checking until address with no tx history is set as current + await _checkP2PKHChangeAddressForTransactions(); + } + } on SocketException catch (se, s) { + Logging.instance.log( + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $se\n$s", + level: LogLevel.Error); + return; + } catch (e, s) { + Logging.instance.log( + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2166,6 +2283,8 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { Logging.instance.log("spendableOutputs.length: ${spendableOutputs.length}", level: LogLevel.Info); + Logging.instance.log("availableOutputs.length: ${availableOutputs.length}", + level: LogLevel.Info); Logging.instance .log("spendableOutputs: $spendableOutputs", level: LogLevel.Info); Logging.instance.log("spendableSatoshiValue: $spendableSatoshiValue", @@ -2258,24 +2377,38 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { return transactionObject; } - final int vSizeForOneOutput = (await buildTransaction( - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - recipients: [_recipientAddress], - satoshiAmounts: [satoshisBeingUsed - 1], - ))["vSize"] as int; - final int vSizeForTwoOutPuts = (await buildTransaction( - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - recipients: [ - _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip84), - ], - satoshiAmounts: [ - satoshiAmountToSend, - satoshisBeingUsed - satoshiAmountToSend - 1 - ], // dust limit is the minimum amount a change output should be - ))["vSize"] as int; + final int vSizeForOneOutput; + try { + vSizeForOneOutput = (await buildTransaction( + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + recipients: [_recipientAddress], + satoshiAmounts: [satoshisBeingUsed - 1], + ))["vSize"] as int; + } catch (e) { + Logging.instance.log("vSizeForOneOutput: $e", level: LogLevel.Error); + rethrow; + } + + final int vSizeForTwoOutPuts; + try { + vSizeForTwoOutPuts = (await buildTransaction( + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + recipients: [ + _recipientAddress, + await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)), + ], + satoshiAmounts: [ + satoshiAmountToSend, + max(0, satoshisBeingUsed - satoshiAmountToSend - 1), + ], + ))["vSize"] as int; + } catch (e) { + Logging.instance.log("vSizeForTwoOutPuts: $e", level: LogLevel.Error); + rethrow; + } // Assume 1 output, only for recipient and no change final feeForOneOutput = estimateTxFee( @@ -2308,8 +2441,8 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip84); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -2515,6 +2648,8 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: addressesP2WPKH.add(address); break; + default: + throw Exception("DerivePathType unsupported"); } } } @@ -2794,6 +2929,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; @@ -3035,7 +3171,7 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 70e3a5d55..1963c89bc 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -34,6 +34,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -50,8 +51,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"; -enum DerivePathType { bip44, bip49 } - bip32.BIP32 getBip32Node(int chain, int index, String mnemonic, NetworkType network, DerivePathType derivePathType) { final root = getBip32Root(mnemonic, network); @@ -78,7 +77,8 @@ bip32.BIP32 getBip32NodeFromRoot( String coinType; switch (root.network.wif) { case 0x80: // bch mainnet wif - coinType = "145"; // bch mainnet + coinType = + derivePathType == DerivePathType.bch44 ? "145" : "0"; // bch mainnet break; case 0xef: // bch testnet wif coinType = "1"; // bch testnet @@ -88,6 +88,7 @@ bip32.BIP32 getBip32NodeFromRoot( } switch (derivePathType) { case DerivePathType.bip44: + case DerivePathType.bch44: return root.derivePath("m/44'/$coinType'/0'/$chain/$index"); case DerivePathType.bip49: return root.derivePath("m/49'/$coinType'/0'/$chain/$index"); @@ -170,7 +171,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip44); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -183,7 +184,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip44); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -218,6 +219,14 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", @@ -322,6 +331,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic.trim(), maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + coin: coin, ); } catch (e, s) { Logging.instance.log( @@ -380,6 +390,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2pkh; addressString = bitbox.Address.toCashAddress(addressString); break; + case DerivePathType.bch44: + addressString = P2PKH(data: data, network: _network).data.address!; + addrType = isar_models.AddressType.unknown; + addressString = bitbox.Address.toCashAddress(addressString); + break; case DerivePathType.bip49: addressString = P2SH( data: PaymentData( @@ -390,7 +405,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2sh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } final address = isar_models.Address( @@ -480,24 +495,32 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, + Coin? coin, }) async { longMutex = true; - Map<String, Map<String, String>> p2pkhReceiveDerivations = {}; + Map<String, Map<String, String>> bip44P2pkhReceiveDerivations = {}; + Map<String, Map<String, String>> bch44P2pkhReceiveDerivations = {}; Map<String, Map<String, String>> p2shReceiveDerivations = {}; - Map<String, Map<String, String>> p2pkhChangeDerivations = {}; + Map<String, Map<String, String>> bip44P2pkhChangeDerivations = {}; + Map<String, Map<String, String>> bch44P2pkhChangeDerivations = {}; Map<String, Map<String, String>> p2shChangeDerivations = {}; final root = await compute(getBip32RootWrapper, Tuple2(mnemonic, _network)); - List<isar_models.Address> p2pkhReceiveAddressArray = []; + List<isar_models.Address> bip44P2pkhReceiveAddressArray = []; + List<isar_models.Address> bch44P2pkhReceiveAddressArray = []; List<isar_models.Address> p2shReceiveAddressArray = []; - int p2pkhReceiveIndex = -1; + int bch44P2pkhReceiveIndex = -1; + int bip44P2pkhReceiveIndex = -1; int p2shReceiveIndex = -1; - List<isar_models.Address> p2pkhChangeAddressArray = []; + List<isar_models.Address> bip44P2pkhChangeAddressArray = []; + List<isar_models.Address> bch44P2pkhChangeAddressArray = []; List<isar_models.Address> p2shChangeAddressArray = []; - int p2pkhChangeIndex = -1; + int bch44P2pkhChangeIndex = -1; + int bip44P2pkhChangeIndex = -1; int p2shChangeIndex = -1; // The gap limit will be capped at [maxUnusedAddressGap] @@ -508,10 +531,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { const txCountBatchSize = 12; try { + bool testnet = ((coin ?? null) == Coin.bitcoincashTestnet) ? true : false; // receiving addresses Logging.instance .log("checking receiving addresses...", level: LogLevel.Info); - final resultReceive44 = _checkGaps(maxNumberOfIndexesToCheck, + final resultReceiveBip44 = _checkGaps(maxNumberOfIndexesToCheck, maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip44, 0); final resultReceive49 = _checkGaps(maxNumberOfIndexesToCheck, @@ -520,23 +544,23 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { Logging.instance .log("checking change addresses...", level: LogLevel.Info); // change addresses - final resultChange44 = _checkGaps(maxNumberOfIndexesToCheck, + final bip44ResultChange = _checkGaps(maxNumberOfIndexesToCheck, maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip44, 1); final resultChange49 = _checkGaps(maxNumberOfIndexesToCheck, maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 1); await Future.wait([ - resultReceive44, + resultReceiveBip44, resultReceive49, - resultChange44, + bip44ResultChange, resultChange49, ]); - p2pkhReceiveAddressArray = - (await resultReceive44)['addressArray'] as List<isar_models.Address>; - p2pkhReceiveIndex = (await resultReceive44)['index'] as int; - p2pkhReceiveDerivations = (await resultReceive44)['derivations'] + bip44P2pkhReceiveAddressArray = (await resultReceiveBip44)['addressArray'] + as List<isar_models.Address>; + bip44P2pkhReceiveIndex = (await resultReceiveBip44)['index'] as int; + bip44P2pkhReceiveDerivations = (await resultReceiveBip44)['derivations'] as Map<String, Map<String, String>>; p2shReceiveAddressArray = @@ -545,10 +569,10 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { p2shReceiveDerivations = (await resultReceive49)['derivations'] as Map<String, Map<String, String>>; - p2pkhChangeAddressArray = - (await resultChange44)['addressArray'] as List<isar_models.Address>; - p2pkhChangeIndex = (await resultChange44)['index'] as int; - p2pkhChangeDerivations = (await resultChange44)['derivations'] + bip44P2pkhChangeAddressArray = (await bip44ResultChange)['addressArray'] + as List<isar_models.Address>; + bip44P2pkhChangeIndex = (await bip44ResultChange)['index'] as int; + bip44P2pkhChangeDerivations = (await bip44ResultChange)['derivations'] as Map<String, Map<String, String>>; p2shChangeAddressArray = @@ -558,11 +582,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { as Map<String, Map<String, String>>; // save the derivations (if any) - if (p2pkhReceiveDerivations.isNotEmpty) { + if (bip44P2pkhReceiveDerivations.isNotEmpty) { await addDerivations( chain: 0, derivePathType: DerivePathType.bip44, - derivationsToAdd: p2pkhReceiveDerivations); + derivationsToAdd: bip44P2pkhReceiveDerivations); } if (p2shReceiveDerivations.isNotEmpty) { await addDerivations( @@ -570,11 +594,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { derivePathType: DerivePathType.bip49, derivationsToAdd: p2shReceiveDerivations); } - if (p2pkhChangeDerivations.isNotEmpty) { + if (bip44P2pkhChangeDerivations.isNotEmpty) { await addDerivations( chain: 1, derivePathType: DerivePathType.bip44, - derivationsToAdd: p2pkhChangeDerivations); + derivationsToAdd: bip44P2pkhChangeDerivations); } if (p2shChangeDerivations.isNotEmpty) { await addDerivations( @@ -585,10 +609,10 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // If restoring a wallet that never received any funds, then set receivingArray manually // If we didn't do this, it'd store an empty array - if (p2pkhReceiveIndex == -1) { + if (bip44P2pkhReceiveIndex == -1) { final address = await _generateAddressForChain(0, 0, DerivePathType.bip44); - p2pkhReceiveAddressArray.add(address); + bip44P2pkhReceiveAddressArray.add(address); } if (p2shReceiveIndex == -1) { final address = @@ -598,10 +622,10 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // 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. - if (p2pkhChangeIndex == -1) { + if (bip44P2pkhChangeIndex == -1) { final address = await _generateAddressForChain(1, 0, DerivePathType.bip44); - p2pkhChangeAddressArray.add(address); + bip44P2pkhChangeAddressArray.add(address); } if (p2shChangeIndex == -1) { final address = @@ -609,12 +633,82 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { p2shChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, + final addressesToStore = [ + ...bip44P2pkhReceiveAddressArray, + ...bip44P2pkhChangeAddressArray, ...p2shReceiveAddressArray, ...p2shChangeAddressArray, - ]); + ]; + + if (!testnet) { + final resultReceiveBch44 = _checkGaps( + maxNumberOfIndexesToCheck, + maxUnusedAddressGap, + txCountBatchSize, + root, + DerivePathType.bch44, + 0); + final Future<Map<String, dynamic>> bch44ResultChange = _checkGaps( + maxNumberOfIndexesToCheck, + maxUnusedAddressGap, + txCountBatchSize, + root, + DerivePathType.bch44, + 1); + await Future.wait([ + resultReceiveBch44, + bch44ResultChange, + ]); + + bch44P2pkhReceiveAddressArray = + (await resultReceiveBch44)['addressArray'] + as List<isar_models.Address>; + bch44P2pkhReceiveIndex = (await resultReceiveBch44)['index'] as int; + bch44P2pkhReceiveDerivations = (await resultReceiveBch44)['derivations'] + as Map<String, Map<String, String>>; + + bch44P2pkhChangeAddressArray = (await bch44ResultChange)['addressArray'] + as List<isar_models.Address>; + bch44P2pkhChangeIndex = (await bch44ResultChange)['index'] as int; + bch44P2pkhChangeDerivations = (await bch44ResultChange)['derivations'] + as Map<String, Map<String, String>>; + + if (bch44P2pkhReceiveDerivations.isNotEmpty) { + await addDerivations( + chain: 0, + derivePathType: DerivePathType.bch44, + derivationsToAdd: bch44P2pkhReceiveDerivations); + } + if (bch44P2pkhChangeDerivations.isNotEmpty) { + await addDerivations( + chain: 1, + derivePathType: DerivePathType.bch44, + derivationsToAdd: bch44P2pkhChangeDerivations); + } + + if (bch44P2pkhReceiveIndex == -1) { + final address = + await _generateAddressForChain(0, 0, DerivePathType.bch44); + bch44P2pkhReceiveAddressArray.add(address); + } + + if (bch44P2pkhChangeIndex == -1) { + final address = + await _generateAddressForChain(1, 0, DerivePathType.bch44); + bch44P2pkhChangeAddressArray.add(address); + } + + addressesToStore.addAll([ + ...bch44P2pkhReceiveAddressArray, + ...bch44P2pkhChangeAddressArray, + ]); + } + + if (isRescan) { + await db.updateOrPutAddresses(addressesToStore); + } else { + await db.putAddresses(addressesToStore); + } await _updateUTXOs(); @@ -1106,46 +1200,31 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _fetchTransactionData(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } bool validateCashAddr(String cashAddr) { @@ -1403,6 +1482,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { ), ); final data = PaymentData(pubkey: node.publicKey); + String address; isar_models.AddressType addrType; @@ -1412,6 +1492,11 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2pkh; address = bitbox.Address.toCashAddress(address); break; + case DerivePathType.bch44: + address = P2PKH(data: data, network: _network).data.address!; + addrType = isar_models.AddressType.unknown; + address = bitbox.Address.toCashAddress(address); + break; case DerivePathType.bip49: address = P2SH( data: PaymentData( @@ -1421,9 +1506,10 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .address!; addrType = isar_models.AddressType.p2sh; break; - // default: - // // should never hit this due to all enum cases handled - // return null; + case DerivePathType.bip84: + throw UnsupportedError("bip84 not supported by BCH"); + default: + throw Exception("DerivePathType $derivePathType not supported"); } // add generated address & info to derivations @@ -1463,9 +1549,16 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip44: type = isar_models.AddressType.p2pkh; break; + case DerivePathType.bch44: + type = isar_models.AddressType.unknown; + break; case DerivePathType.bip49: type = isar_models.AddressType.p2sh; break; + case DerivePathType.bip84: + throw UnsupportedError("bip84 not supported by BCH"); + default: + throw Exception("DerivePathType $derivePathType not supported"); } final address = await db @@ -1488,9 +1581,14 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip44: key = "${walletId}_${chainId}DerivationsP2PKH"; break; + case DerivePathType.bch44: + key = "${walletId}_${chainId}DerivationsBch44P2PKH"; + break; case DerivePathType.bip49: key = "${walletId}_${chainId}DerivationsP2SH"; break; + case DerivePathType.bip84: + throw UnsupportedError("bip84 not supported by BCH"); } return key; } @@ -1663,7 +1761,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); @@ -1752,7 +1850,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip44); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1771,12 +1869,12 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1796,7 +1894,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip44); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1815,12 +1913,12 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip44}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1951,7 +2049,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .where((e) => e.subType == isar_models.AddressSubType.receiving) .map((e) { if (bitbox.Address.detectFormat(e.value) == bitbox.Address.formatLegacy && - addressType(address: e.value) == DerivePathType.bip44) { + (addressType(address: e.value) == DerivePathType.bip44 || + addressType(address: e.value) == DerivePathType.bch44)) { return bitbox.Address.toCashAddress(e.value); } else { return e.value; @@ -1962,7 +2061,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { .where((e) => e.subType == isar_models.AddressSubType.change) .map((e) { if (bitbox.Address.detectFormat(e.value) == bitbox.Address.formatLegacy && - addressType(address: e.value) == DerivePathType.bip44) { + (addressType(address: e.value) == DerivePathType.bip44 || + addressType(address: e.value) == DerivePathType.bch44)) { return bitbox.Address.toCashAddress(e.value); } else { return e.value; @@ -2346,7 +2446,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip44), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2399,8 +2499,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip44); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -2591,13 +2691,12 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { final n = output["n"]; if (n != null && n == utxosToUse[i].vout) { String address = output["scriptPubKey"]["addresses"][0] as String; - if (bitbox.Address.detectFormat(address) == + if (bitbox.Address.detectFormat(address) != bitbox.Address.formatCashAddr) { - if (validateCashAddr(address)) { - address = bitbox.Address.toLegacyAddress(address); - } else { - throw Exception( - "Unsupported address found during fetchBuildTxData(): $address"); + try { + address = bitbox.Address.toCashAddress(address); + } catch (_) { + rethrow; } } if (!addressTxid.containsKey(address)) { @@ -2606,11 +2705,14 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { (addressTxid[address] as List).add(txid); switch (addressType(address: address)) { case DerivePathType.bip44: + case DerivePathType.bch44: addressesP2PKH.add(address); break; case DerivePathType.bip49: addressesP2SH.add(address); break; + case DerivePathType.bip84: + throw UnsupportedError("bip84 not supported by BCH"); } } } @@ -2619,19 +2721,28 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // p2pkh / bip44 final p2pkhLength = addressesP2PKH.length; if (p2pkhLength > 0) { - final receiveDerivations = await _fetchDerivations( + final receiveDerivationsBip44 = await _fetchDerivations( chain: 0, derivePathType: DerivePathType.bip44, ); - final changeDerivations = await _fetchDerivations( + final changeDerivationsBip44 = await _fetchDerivations( chain: 1, derivePathType: DerivePathType.bip44, ); + final receiveDerivationsBch44 = await _fetchDerivations( + chain: 0, + derivePathType: DerivePathType.bch44, + ); + final changeDerivationsBch44 = await _fetchDerivations( + chain: 1, + derivePathType: DerivePathType.bch44, + ); for (int i = 0; i < p2pkhLength; i++) { String address = addressesP2PKH[i]; // receives - final receiveDerivation = receiveDerivations[address]; + final receiveDerivation = receiveDerivationsBip44[address] ?? + receiveDerivationsBch44[address]; // if a match exists it will not be null if (receiveDerivation != null) { final data = P2PKH( @@ -2652,7 +2763,8 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { } } else { // if its not a receive, check change - final changeDerivation = changeDerivations[address]; + final changeDerivation = changeDerivationsBip44[address] ?? + changeDerivationsBch44[address]; // if a match exists it will not be null if (changeDerivation != null) { final data = P2PKH( @@ -2863,6 +2975,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; @@ -2997,7 +3110,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip44); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/coins/coin_paynym_extension.dart b/lib/services/coins/coin_paynym_extension.dart index a5e8a07d5..082976f67 100644 --- a/lib/services/coins/coin_paynym_extension.dart +++ b/lib/services/coins/coin_paynym_extension.dart @@ -1,756 +1,815 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:bip47/bip47.dart'; -import 'package:bip47/src/util.dart'; -import 'package:bitcoindart/bitcoindart.dart' as btc_dart; -import 'package:bitcoindart/src/utils/constants/op.dart' as op; -import 'package:bitcoindart/src/utils/script.dart' as bscript; -import 'package:decimal/decimal.dart'; -import 'package:isar/isar.dart'; -import 'package:pointycastle/digests/sha256.dart'; -import 'package:stackwallet/hive/db.dart'; -import 'package:stackwallet/models/isar/models/isar_models.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; -import 'package:stackwallet/utilities/address_utils.dart'; -import 'package:stackwallet/utilities/enums/coin_enum.dart'; -import 'package:stackwallet/utilities/format.dart'; -import 'package:stackwallet/utilities/logger.dart'; -import 'package:tuple/tuple.dart'; - -class SWException with Exception { - SWException(this.message); - - final String message; - - @override - toString() => message; -} - -class InsufficientBalanceException extends SWException { - InsufficientBalanceException(super.message); -} - -class PaynymSendException extends SWException { - PaynymSendException(super.message); -} - -extension PayNym on DogecoinWallet { - // fetch or generate this wallet's bip47 payment code - Future<PaymentCode> getPaymentCode() async { - final paymentCodeString = DB.instance - .get<dynamic>(boxName: walletId, key: "paymentCodeString") as String?; - PaymentCode paymentCode; - if (paymentCodeString == null) { - final node = getBip32Root((await mnemonic).join(" "), network) - .derivePath("m/47'/0'/0'"); - paymentCode = - PaymentCode.initFromPubKey(node.publicKey, node.chainCode, network); - await DB.instance.put<dynamic>( - boxName: walletId, - key: "paymentCodeString", - value: paymentCode.toString()); - } else { - paymentCode = PaymentCode.fromPaymentCode(paymentCodeString, network); - } - return paymentCode; - } - - Future<Uint8List> signWithNotificationKey(Uint8List data) async { - final node = getBip32Root((await mnemonic).join(" "), network) - .derivePath("m/47'/0'/0'"); - final pair = - btc_dart.ECPair.fromPrivateKey(node.privateKey!, network: network); - final signed = pair.sign(SHA256Digest().process(data)); - return signed; - } - - Future<String> signStringWithNotificationKey(String data) async { - final bytes = - await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); - return Format.uint8listToString(bytes); - // final bytes = - // await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); - // return Format.uint8listToString(bytes); - } - - /// Update cached lists of notification transaction IDs. - /// Returns true if there are new notification transactions found since last - /// checked. - Future<bool> checkForNotificationTransactions() async { - final myPCode = await getPaymentCode(); - - final transactionIds = await electrumXClient.getHistory( - scripthash: AddressUtils.convertToScriptHash( - myPCode.notificationAddress(), - network, - ), - ); - - final confirmedNotificationTransactionIds = DB.instance.get<dynamic>( - boxName: walletId, - key: "confirmedNotificationTransactionIds", - ) as Set? ?? - {}; - - final unconfirmedNotificationTransactionIds = DB.instance.get<dynamic>( - boxName: walletId, - key: "unconfirmedNotificationTransactionIds", - ) as Set? ?? - {}; - - // since we are only checking for newly found transactions here we can use the sum - final totalCount = confirmedNotificationTransactionIds.length + - unconfirmedNotificationTransactionIds.length; - - for (final entry in transactionIds) { - final txid = entry["tx_hash"] as String; - - final tx = await cachedElectrumXClient.getTransaction( - txHash: txid, - coin: coin, - ); - - // check if tx is confirmed - if ((tx["confirmations"] as int? ?? 0) > MINIMUM_CONFIRMATIONS) { - // remove it from unconfirmed set - unconfirmedNotificationTransactionIds.remove(txid); - - // add it to confirmed set - confirmedNotificationTransactionIds.add(txid); - } else { - // otherwise add it to the unconfirmed set - unconfirmedNotificationTransactionIds.add(txid); - } - } - - final newTotalCount = confirmedNotificationTransactionIds.length + - unconfirmedNotificationTransactionIds.length; - - return newTotalCount > totalCount; - } - - /// return the notification tx sent from my wallet if it exists - Future<Transaction?> hasSentNotificationTx(PaymentCode pCode) async { - final tx = await db - .getTransactions(walletId) - .filter() - .address((q) => q.valueEqualTo(pCode.notificationAddress())) - .findFirst(); - return tx; - } - - void preparePaymentCodeSend(PaymentCode pCode) async { - final notifTx = await hasSentNotificationTx(pCode); - final currentHeight = await chainHeight; - - if (notifTx == null) { - throw PaynymSendException("No notification transaction sent to $pCode"); - } else if (!notifTx.isConfirmed(currentHeight, MINIMUM_CONFIRMATIONS)) { - throw PaynymSendException( - "Notification transaction sent to $pCode has not confirmed yet"); - } else { - final node = getBip32Root((await mnemonic).join(" "), network) - .derivePath("m/47'/0'/0'"); - final sendToAddress = await nextUnusedSendAddressFrom( - pCode, - node.derive(0).privateKey!, - ); - - // todo: Actual transaction build - } - } - - /// get the next unused address to send to given the receiver's payment code - /// and your own private key - Future<String> nextUnusedSendAddressFrom( - PaymentCode pCode, - Uint8List privateKey, - ) async { - // https://en.bitcoin.it/wiki/BIP_0047#Path_levels - const maxCount = 2147483647; - - final paymentAddress = PaymentAddress.initWithPrivateKey( - privateKey, - pCode, - 0, // initial index to check - ); - - for (paymentAddress.index = 0; - paymentAddress.index <= maxCount; - paymentAddress.index++) { - final address = paymentAddress.getSendAddress(); - - final transactionIds = await electrumXClient.getHistory( - scripthash: AddressUtils.convertToScriptHash( - address, - network, - ), - ); - - if (transactionIds.isEmpty) { - return address; - } - } - - throw PaynymSendException("Exhausted unused send addresses!"); - } - - /// get your receiving addresses given the sender's payment code and your own - /// private key - List<String> deriveReceivingAddressesFor( - PaymentCode pCode, - Uint8List privateKey, - int count, - ) { - // https://en.bitcoin.it/wiki/BIP_0047#Path_levels - const maxCount = 2147483647; - assert(count <= maxCount); - - final paymentAddress = PaymentAddress.initWithPrivateKey( - privateKey, - pCode, - 0, // initial index - ); - - final List<String> result = []; - for (paymentAddress.index = 0; - paymentAddress.index < count; - paymentAddress.index++) { - final address = paymentAddress.getReceiveAddress(); - - result.add(address); - } - - return result; - } - - Future<Map<String, dynamic>> buildNotificationTx({ - required int selectedTxFeeRate, - required String targetPaymentCodeString, - int additionalOutputs = 0, - List<UTXO>? utxos, - }) async { - const amountToSend = DUST_LIMIT; - final List<UTXO> availableOutputs = utxos ?? await this.utxos; - final List<UTXO> spendableOutputs = []; - int spendableSatoshiValue = 0; - - // Build list of spendable outputs and totaling their satoshi amount - for (var i = 0; i < availableOutputs.length; i++) { - if (availableOutputs[i].isBlocked == false && - availableOutputs[i] - .isConfirmed(await chainHeight, MINIMUM_CONFIRMATIONS) == - true) { - spendableOutputs.add(availableOutputs[i]); - spendableSatoshiValue += availableOutputs[i].value; - } - } - - if (spendableSatoshiValue < amountToSend) { - // insufficient balance - throw InsufficientBalanceException( - "Spendable balance is less than the minimum required for a notification transaction."); - } else if (spendableSatoshiValue == amountToSend) { - // insufficient balance due to missing amount to cover fee - throw InsufficientBalanceException( - "Remaining balance does not cover the network fee."); - } - - // sort spendable by age (oldest first) - spendableOutputs.sort((a, b) => b.blockTime!.compareTo(a.blockTime!)); - - int satoshisBeingUsed = 0; - int outputsBeingUsed = 0; - List<UTXO> utxoObjectsToUse = []; - - for (int i = 0; - satoshisBeingUsed < amountToSend && i < spendableOutputs.length; - i++) { - utxoObjectsToUse.add(spendableOutputs[i]); - satoshisBeingUsed += spendableOutputs[i].value; - outputsBeingUsed += 1; - } - - // add additional outputs if required - for (int i = 0; - i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; - i++) { - utxoObjectsToUse.add(spendableOutputs[outputsBeingUsed]); - satoshisBeingUsed += spendableOutputs[outputsBeingUsed].value; - outputsBeingUsed += 1; - } - - // gather required signing data - final utxoSigningData = await fetchBuildTxData(utxoObjectsToUse); - - final int vSizeForNoChange = (await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: 0)) - .item2; - - final int vSizeForWithChange = (await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: satoshisBeingUsed - amountToSend)) - .item2; - - // Assume 2 outputs, for recipient and payment code script - int feeForNoChange = estimateTxFee( - vSize: vSizeForNoChange, - feeRatePerKB: selectedTxFeeRate, - ); - - // Assume 3 outputs, for recipient, payment code script, and change - int feeForWithChange = estimateTxFee( - vSize: vSizeForWithChange, - feeRatePerKB: selectedTxFeeRate, - ); - - if (feeForNoChange < vSizeForNoChange * 1000) { - feeForNoChange = vSizeForNoChange * 1000; - } - if (feeForWithChange < vSizeForWithChange * 1000) { - feeForWithChange = vSizeForWithChange * 1000; - } - - if (satoshisBeingUsed - amountToSend > feeForNoChange + DUST_LIMIT) { - // try to add change output due to "left over" amount being greater than - // the estimated fee + the dust limit - int changeAmount = satoshisBeingUsed - amountToSend - feeForWithChange; - - // check estimates are correct and build notification tx - if (changeAmount >= DUST_LIMIT && - satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { - final txn = await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: changeAmount, - ); - - int feeBeingPaid = satoshisBeingUsed - amountToSend - changeAmount; - - Map<String, dynamic> transactionObject = { - "hex": txn.item1, - "recipientPaynym": targetPaymentCodeString, - "amount": amountToSend, - "fee": feeBeingPaid, - "vSize": txn.item2, - }; - return transactionObject; - } else { - // something broke during fee estimation or the change amount is smaller - // than the dust limit. Try without change - final txn = await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: 0, - ); - - int feeBeingPaid = satoshisBeingUsed - amountToSend; - - Map<String, dynamic> transactionObject = { - "hex": txn.item1, - "recipientPaynym": targetPaymentCodeString, - "amount": amountToSend, - "fee": feeBeingPaid, - "vSize": txn.item2, - }; - return transactionObject; - } - } else if (satoshisBeingUsed - amountToSend >= feeForNoChange) { - // since we already checked if we need to add a change output we can just - // build without change here - final txn = await _createNotificationTx( - targetPaymentCodeString: targetPaymentCodeString, - utxosToUse: utxoObjectsToUse, - utxoSigningData: utxoSigningData, - change: 0, - ); - - int feeBeingPaid = satoshisBeingUsed - amountToSend; - - Map<String, dynamic> transactionObject = { - "hex": txn.item1, - "recipientPaynym": targetPaymentCodeString, - "amount": amountToSend, - "fee": feeBeingPaid, - "vSize": txn.item2, - }; - return transactionObject; - } else { - // if we get here we do not have enough funds to cover the tx total so we - // check if we have any more available outputs and try again - if (spendableOutputs.length > outputsBeingUsed) { - return buildNotificationTx( - selectedTxFeeRate: selectedTxFeeRate, - targetPaymentCodeString: targetPaymentCodeString, - additionalOutputs: additionalOutputs + 1, - ); - } else { - throw InsufficientBalanceException( - "Remaining balance does not cover the network fee."); - } - } - } - - // return tuple with string value equal to the raw tx hex and the int value - // equal to its vSize - Future<Tuple2<String, int>> _createNotificationTx({ - required String targetPaymentCodeString, - required List<UTXO> utxosToUse, - required Map<String, dynamic> utxoSigningData, - required int change, - }) async { - final targetPaymentCode = - PaymentCode.fromPaymentCode(targetPaymentCodeString, network); - final myCode = await getPaymentCode(); - - final utxo = utxosToUse.first; - final txPoint = utxo.txid.fromHex.toList(); - final txPointIndex = utxo.vout; - - final rev = Uint8List(txPoint.length + 4); - Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); - final buffer = rev.buffer.asByteData(); - buffer.setUint32(txPoint.length, txPointIndex, Endian.little); - - final myKeyPair = utxoSigningData[utxo.txid]["keyPair"] as btc_dart.ECPair; - - final S = SecretPoint( - myKeyPair.privateKey!, - targetPaymentCode.notificationPublicKey(), - ); - - final blindingMask = PaymentCode.getMask(S.ecdhSecret(), rev); - - final blindedPaymentCode = PaymentCode.blind( - myCode.getPayload(), - blindingMask, - ); - - final opReturnScript = bscript.compile([ - (op.OPS["OP_RETURN"] as int), - blindedPaymentCode, - ]); - - // build a notification tx - final txb = btc_dart.TransactionBuilder(network: network); - txb.setVersion(1); - - txb.addInput( - utxo.txid, - txPointIndex, - ); - - txb.addOutput(targetPaymentCode.notificationAddress(), DUST_LIMIT); - txb.addOutput(opReturnScript, 0); - - // TODO: add possible change output and mark output as dangerous - if (change > 0) { - // generate new change address if current change address has been used - await checkChangeAddressForTransactions(); - final String changeAddress = await currentChangeAddress; - txb.addOutput(changeAddress, change); - } - - txb.sign( - vin: 0, - keyPair: myKeyPair, - ); - - // sign rest of possible inputs - for (var i = 1; i < utxosToUse.length - 1; i++) { - final txid = utxosToUse[i].txid; - txb.sign( - vin: i, - keyPair: utxoSigningData[txid]["keyPair"] as btc_dart.ECPair, - // witnessValue: utxosToUse[i].value, - ); - } - - final builtTx = txb.build(); - - return Tuple2(builtTx.toHex(), builtTx.virtualSize()); - } - - Future<String> confirmNotificationTx( - {required Map<String, dynamic> preparedTx}) async { - try { - Logging.instance.log("confirmNotificationTx txData: $preparedTx", - level: LogLevel.Info); - final txHash = await electrumXClient.broadcastTransaction( - rawTx: preparedTx["hex"] as String); - Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); - - await updatePaynymNotificationInfo( - txid: txHash, - confirmed: false, - paymentCodeString: preparedTx["address"] as String, - ); - return txHash; - } catch (e, s) { - Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s", - level: LogLevel.Error); - rethrow; - } - } - - // Future<bool> hasConfirmedNotificationTxSentTo( - // String paymentCodeString) async { - // final targetPaymentCode = - // PaymentCode.fromPaymentCode(paymentCodeString, network); - // final targetNotificationAddress = targetPaymentCode.notificationAddress(); - // - // final myTxHistory = (await transactionData) - // .getAllTransactions() - // .entries - // .map((e) => e.value) - // .where((e) => - // e.txType == "Sent" && e.address == targetNotificationAddress); - // - // return myTxHistory.isNotEmpty; - // } - - bool hasConnected(String paymentCodeString) { - return getPaynymNotificationTxInfo() - .values - .where((e) => e["paymentCodeString"] == paymentCodeString) - .isNotEmpty; - } - - bool hasConnectedConfirmed(String paymentCodeString) { - return getPaynymNotificationTxInfo() - .values - .where((e) => - e["paymentCodeString"] == paymentCodeString && - e["confirmed"] == true) - .isNotEmpty; - } - - // fetch paynym notification tx meta data - Map<String, dynamic> getPaynymNotificationTxInfo() { - final map = DB.instance.get<dynamic>( - boxName: walletId, key: "paynymNotificationTxInfo") as Map? ?? - {}; - - return Map<String, dynamic>.from(map); - } - - // add/update paynym notification tx meta data entry - Future<void> updatePaynymNotificationInfo({ - required String txid, - required bool confirmed, - required String paymentCodeString, - }) async { - final data = getPaynymNotificationTxInfo(); - data[txid] = { - "txid": txid, - "confirmed": confirmed, - "paymentCodeString": paymentCodeString, - }; - await DB.instance.put<dynamic>( - boxName: walletId, - key: "paynymNotificationTxInfo", - value: data, - ); - } -} - -Future<Tuple4<Transaction, List<Output>, List<Input>, Address>> - parseTransaction( - Map<String, dynamic> txData, - dynamic electrumxClient, - List<Address> myAddresses, - Coin coin, - int minConfirms, - String walletId, -) async { - Set<String> receivingAddresses = myAddresses - .where((e) => e.subType == AddressSubType.receiving) - .map((e) => e.value) - .toSet(); - Set<String> changeAddresses = myAddresses - .where((e) => e.subType == AddressSubType.change) - .map((e) => e.value) - .toSet(); - - Set<String> inputAddresses = {}; - Set<String> outputAddresses = {}; - - int totalInputValue = 0; - int totalOutputValue = 0; - - int amountSentFromWallet = 0; - int amountReceivedInWallet = 0; - int changeAmount = 0; - - // parse inputs - for (final input in txData["vin"] as List) { - final prevTxid = input["txid"] as String; - final prevOut = input["vout"] as int; - - // fetch input tx to get address - final inputTx = await electrumxClient.getTransaction( - txHash: prevTxid, - coin: coin, - ); - - for (final output in inputTx["vout"] as List) { - // check matching output - if (prevOut == output["n"]) { - // get value - final value = Format.decimalAmountToSatoshis( - Decimal.parse(output["value"].toString()), - coin, - ); - - // add value to total - totalInputValue += value; - - // get input(prevOut) address - final address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? - output["scriptPubKey"]?["address"] as String?; - - if (address != null) { - inputAddresses.add(address); - - // if input was from my wallet, add value to amount sent - if (receivingAddresses.contains(address) || - changeAddresses.contains(address)) { - amountSentFromWallet += value; - } - } - } - } - } - - // parse outputs - for (final output in txData["vout"] as List) { - // get value - final value = Format.decimalAmountToSatoshis( - Decimal.parse(output["value"].toString()), - coin, - ); - - // add value to total - totalOutputValue += value; - - // get output address - final address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? - output["scriptPubKey"]?["address"] as String?; - if (address != null) { - outputAddresses.add(address); - - // if output was to my wallet, add value to amount received - if (receivingAddresses.contains(address)) { - amountReceivedInWallet += value; - } else if (changeAddresses.contains(address)) { - changeAmount += value; - } - } - } - - final mySentFromAddresses = [ - ...receivingAddresses.intersection(inputAddresses), - ...changeAddresses.intersection(inputAddresses) - ]; - final myReceivedOnAddresses = - receivingAddresses.intersection(outputAddresses); - final myChangeReceivedOnAddresses = - changeAddresses.intersection(outputAddresses); - - final fee = totalInputValue - totalOutputValue; - - // this is the address initially used to fetch the txid - Address transactionAddress = txData["address"] as Address; - - TransactionType type; - int amount; - if (mySentFromAddresses.isNotEmpty && myReceivedOnAddresses.isNotEmpty) { - // tx is sent to self - type = TransactionType.sentToSelf; - - // should be 0 - amount = amountSentFromWallet - amountReceivedInWallet - fee - changeAmount; - } else if (mySentFromAddresses.isNotEmpty) { - // outgoing tx - type = TransactionType.outgoing; - amount = amountSentFromWallet - changeAmount - fee; - - final possible = - outputAddresses.difference(myChangeReceivedOnAddresses).first; - - if (transactionAddress.value != possible) { - transactionAddress = Address( - walletId: walletId, - value: possible, - derivationIndex: -1, - subType: AddressSubType.nonWallet, - type: AddressType.nonWallet, - publicKey: [], - ); - } - } else { - // incoming tx - type = TransactionType.incoming; - amount = amountReceivedInWallet; - } - - final tx = Transaction( - walletId: walletId, - txid: txData["txid"] as String, - timestamp: txData["blocktime"] as int? ?? - (DateTime.now().millisecondsSinceEpoch ~/ 1000), - type: type, - subType: TransactionSubType.none, - amount: amount, - fee: fee, - height: txData["height"] as int?, - isCancelled: false, - isLelantus: false, - slateId: null, - otherData: null, - ); - - List<Output> outs = []; - List<Input> ins = []; - - for (final json in txData["vin"] as List) { - bool isCoinBase = json['coinbase'] != null; - final input = Input( - walletId: walletId, - txid: json['txid'] as String, - vout: json['vout'] as int? ?? -1, - scriptSig: json['scriptSig']?['hex'] as String?, - scriptSigAsm: json['scriptSig']?['asm'] as String?, - isCoinbase: isCoinBase ? isCoinBase : json['is_coinbase'] as bool?, - sequence: json['sequence'] as int?, - innerRedeemScriptAsm: json['innerRedeemscriptAsm'] as String?, - ); - ins.add(input); - } - - for (final json in txData["vout"] as List) { - final output = Output( - walletId: walletId, - scriptPubKey: json['scriptPubKey']?['hex'] as String?, - scriptPubKeyAsm: json['scriptPubKey']?['asm'] as String?, - scriptPubKeyType: json['scriptPubKey']?['type'] as String?, - scriptPubKeyAddress: json["scriptPubKey"]?["addresses"]?[0] as String? ?? - json['scriptPubKey']['type'] as String, - value: Format.decimalAmountToSatoshis( - Decimal.parse(json["value"].toString()), - coin, - ), - ); - outs.add(output); - } - - return Tuple4(tx, outs, ins, transactionAddress); -} +// import 'dart:convert'; +// import 'dart:typed_data'; +// +// import 'package:bip32/bip32.dart' as bip32; +// import 'package:bip47/bip47.dart'; +// import 'package:bip47/src/util.dart'; +// import 'package:bitcoindart/bitcoindart.dart' as btc_dart; +// import 'package:bitcoindart/src/utils/constants/op.dart' as op; +// import 'package:bitcoindart/src/utils/script.dart' as bscript; +// import 'package:isar/isar.dart'; +// import 'package:pointycastle/digests/sha256.dart'; +// import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; +// import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; +// import 'package:stackwallet/models/isar/models/isar_models.dart'; +// import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +// import 'package:stackwallet/utilities/bip32_utils.dart'; +// import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +// import 'package:stackwallet/utilities/format.dart'; +// import 'package:stackwallet/utilities/logger.dart'; +// import 'package:tuple/tuple.dart'; +// +// const kPaynymDerivePath = "m/47'/0'/0'"; +// +// extension PayNym on DogecoinWallet { +// // generate bip32 payment code root +// Future<bip32.BIP32> getRootNode({ +// required List<String> mnemonic, +// }) async { +// final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), network); +// return root; +// } +// +// Future<Uint8List> deriveNotificationPrivateKey({ +// required List<String> mnemonic, +// }) async { +// final root = await getRootNode(mnemonic: mnemonic); +// final node = root.derivePath(kPaynymDerivePath).derive(0); +// return node.privateKey!; +// } +// +// /// fetch or generate this wallet's bip47 payment code +// Future<PaymentCode> getPaymentCode( +// DerivePathType derivePathType, +// ) async { +// final address = await getMyNotificationAddress(derivePathType); +// final paymentCode = PaymentCode.fromPaymentCode( +// address.otherData!, +// network, +// ); +// return paymentCode; +// } +// +// Future<Uint8List> signWithNotificationKey(Uint8List data) async { +// final privateKey = +// await deriveNotificationPrivateKey(mnemonic: await mnemonic); +// final pair = btc_dart.ECPair.fromPrivateKey(privateKey, network: network); +// final signed = pair.sign(SHA256Digest().process(data)); +// return signed; +// } +// +// Future<String> signStringWithNotificationKey(String data) async { +// final bytes = +// await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); +// return Format.uint8listToString(bytes); +// } +// +// Future<Future<Map<String, dynamic>>> preparePaymentCodeSend( +// {required PaymentCode paymentCode, +// required int satoshiAmount, +// Map<String, dynamic>? args}) async { +// if (!(await hasConnected(paymentCode.notificationAddressP2PKH()))) { +// throw PaynymSendException( +// "No notification transaction sent to $paymentCode"); +// } else { +// final myPrivateKey = +// await deriveNotificationPrivateKey(mnemonic: await mnemonic); +// final sendToAddress = await nextUnusedSendAddressFrom( +// pCode: paymentCode, +// privateKey: myPrivateKey, +// ); +// +// return prepareSend( +// address: sendToAddress.value, satoshiAmount: satoshiAmount); +// } +// } +// +// /// get the next unused address to send to given the receiver's payment code +// /// and your own private key +// Future<Address> nextUnusedSendAddressFrom({ +// required PaymentCode pCode, +// required Uint8List privateKey, +// int startIndex = 0, +// }) async { +// // https://en.bitcoin.it/wiki/BIP_0047#Path_levels +// const maxCount = 2147483647; +// +// for (int i = startIndex; i < maxCount; i++) { +// final address = await db +// .getAddresses(walletId) +// .filter() +// .subTypeEqualTo(AddressSubType.paynymSend) +// .and() +// .otherDataEqualTo(pCode.toString()) +// .and() +// .derivationIndexEqualTo(i) +// .findFirst(); +// +// if (address != null) { +// final count = await getTxCount(address: address.value); +// // return address if unused, otherwise continue to next index +// if (count == 0) { +// return address; +// } +// } else { +// final pair = PaymentAddress.initWithPrivateKey( +// privateKey, +// pCode, +// i, // index to use +// ).getSendAddressKeyPair(); +// +// // add address to local db +// final address = generatePaynymSendAddressFromKeyPair( +// pair: pair, +// derivationIndex: i, +// derivePathType: DerivePathType.bip44, +// toPaymentCode: pCode, +// ); +// await db.putAddress(address); +// +// final count = await getTxCount(address: address.value); +// // return address if unused, otherwise continue to next index +// if (count == 0) { +// return address; +// } +// } +// } +// +// throw PaynymSendException("Exhausted unused send addresses!"); +// } +// +// Future<Map<String, dynamic>> prepareNotificationTx({ +// required int selectedTxFeeRate, +// required String targetPaymentCodeString, +// int additionalOutputs = 0, +// List<UTXO>? utxos, +// }) async { +// const amountToSend = DUST_LIMIT; +// final List<UTXO> availableOutputs = utxos ?? await this.utxos; +// final List<UTXO> spendableOutputs = []; +// int spendableSatoshiValue = 0; +// +// // Build list of spendable outputs and totaling their satoshi amount +// for (var i = 0; i < availableOutputs.length; i++) { +// if (availableOutputs[i].isBlocked == false && +// availableOutputs[i] +// .isConfirmed(await chainHeight, MINIMUM_CONFIRMATIONS) == +// true) { +// spendableOutputs.add(availableOutputs[i]); +// spendableSatoshiValue += availableOutputs[i].value; +// } +// } +// +// if (spendableSatoshiValue < amountToSend) { +// // insufficient balance +// throw InsufficientBalanceException( +// "Spendable balance is less than the minimum required for a notification transaction."); +// } else if (spendableSatoshiValue == amountToSend) { +// // insufficient balance due to missing amount to cover fee +// throw InsufficientBalanceException( +// "Remaining balance does not cover the network fee."); +// } +// +// // sort spendable by age (oldest first) +// spendableOutputs.sort((a, b) => b.blockTime!.compareTo(a.blockTime!)); +// +// int satoshisBeingUsed = 0; +// int outputsBeingUsed = 0; +// List<UTXO> utxoObjectsToUse = []; +// +// for (int i = 0; +// satoshisBeingUsed < amountToSend && i < spendableOutputs.length; +// i++) { +// utxoObjectsToUse.add(spendableOutputs[i]); +// satoshisBeingUsed += spendableOutputs[i].value; +// outputsBeingUsed += 1; +// } +// +// // add additional outputs if required +// for (int i = 0; +// i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; +// i++) { +// utxoObjectsToUse.add(spendableOutputs[outputsBeingUsed]); +// satoshisBeingUsed += spendableOutputs[outputsBeingUsed].value; +// outputsBeingUsed += 1; +// } +// +// // gather required signing data +// final utxoSigningData = await fetchBuildTxData(utxoObjectsToUse); +// +// final int vSizeForNoChange = (await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: 0)) +// .item2; +// +// final int vSizeForWithChange = (await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: satoshisBeingUsed - amountToSend)) +// .item2; +// +// // Assume 2 outputs, for recipient and payment code script +// int feeForNoChange = estimateTxFee( +// vSize: vSizeForNoChange, +// feeRatePerKB: selectedTxFeeRate, +// ); +// +// // Assume 3 outputs, for recipient, payment code script, and change +// int feeForWithChange = estimateTxFee( +// vSize: vSizeForWithChange, +// feeRatePerKB: selectedTxFeeRate, +// ); +// +// if (feeForNoChange < vSizeForNoChange * 1000) { +// feeForNoChange = vSizeForNoChange * 1000; +// } +// if (feeForWithChange < vSizeForWithChange * 1000) { +// feeForWithChange = vSizeForWithChange * 1000; +// } +// +// if (satoshisBeingUsed - amountToSend > feeForNoChange + DUST_LIMIT) { +// // try to add change output due to "left over" amount being greater than +// // the estimated fee + the dust limit +// int changeAmount = satoshisBeingUsed - amountToSend - feeForWithChange; +// +// // check estimates are correct and build notification tx +// if (changeAmount >= DUST_LIMIT && +// satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { +// final txn = await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: changeAmount, +// ); +// +// int feeBeingPaid = satoshisBeingUsed - amountToSend - changeAmount; +// +// Map<String, dynamic> transactionObject = { +// "hex": txn.item1, +// "recipientPaynym": targetPaymentCodeString, +// "amount": amountToSend, +// "fee": feeBeingPaid, +// "vSize": txn.item2, +// }; +// return transactionObject; +// } else { +// // something broke during fee estimation or the change amount is smaller +// // than the dust limit. Try without change +// final txn = await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: 0, +// ); +// +// int feeBeingPaid = satoshisBeingUsed - amountToSend; +// +// Map<String, dynamic> transactionObject = { +// "hex": txn.item1, +// "recipientPaynym": targetPaymentCodeString, +// "amount": amountToSend, +// "fee": feeBeingPaid, +// "vSize": txn.item2, +// }; +// return transactionObject; +// } +// } else if (satoshisBeingUsed - amountToSend >= feeForNoChange) { +// // since we already checked if we need to add a change output we can just +// // build without change here +// final txn = await _createNotificationTx( +// targetPaymentCodeString: targetPaymentCodeString, +// utxosToUse: utxoObjectsToUse, +// utxoSigningData: utxoSigningData, +// change: 0, +// ); +// +// int feeBeingPaid = satoshisBeingUsed - amountToSend; +// +// Map<String, dynamic> transactionObject = { +// "hex": txn.item1, +// "recipientPaynym": targetPaymentCodeString, +// "amount": amountToSend, +// "fee": feeBeingPaid, +// "vSize": txn.item2, +// }; +// return transactionObject; +// } else { +// // if we get here we do not have enough funds to cover the tx total so we +// // check if we have any more available outputs and try again +// if (spendableOutputs.length > outputsBeingUsed) { +// return prepareNotificationTx( +// selectedTxFeeRate: selectedTxFeeRate, +// targetPaymentCodeString: targetPaymentCodeString, +// additionalOutputs: additionalOutputs + 1, +// ); +// } else { +// throw InsufficientBalanceException( +// "Remaining balance does not cover the network fee."); +// } +// } +// } +// +// // return tuple with string value equal to the raw tx hex and the int value +// // equal to its vSize +// Future<Tuple2<String, int>> _createNotificationTx({ +// required String targetPaymentCodeString, +// required List<UTXO> utxosToUse, +// required Map<String, dynamic> utxoSigningData, +// required int change, +// }) async { +// final targetPaymentCode = +// PaymentCode.fromPaymentCode(targetPaymentCodeString, network); +// final myCode = await getPaymentCode(DerivePathType.bip44); +// +// final utxo = utxosToUse.first; +// final txPoint = utxo.txid.fromHex.toList(); +// final txPointIndex = utxo.vout; +// +// final rev = Uint8List(txPoint.length + 4); +// Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); +// final buffer = rev.buffer.asByteData(); +// buffer.setUint32(txPoint.length, txPointIndex, Endian.little); +// +// final myKeyPair = utxoSigningData[utxo.txid]["keyPair"] as btc_dart.ECPair; +// +// final S = SecretPoint( +// myKeyPair.privateKey!, +// targetPaymentCode.notificationPublicKey(), +// ); +// +// final blindingMask = PaymentCode.getMask(S.ecdhSecret(), rev); +// +// final blindedPaymentCode = PaymentCode.blind( +// myCode.getPayload(), +// blindingMask, +// ); +// +// final opReturnScript = bscript.compile([ +// (op.OPS["OP_RETURN"] as int), +// blindedPaymentCode, +// ]); +// +// // build a notification tx +// final txb = btc_dart.TransactionBuilder(network: network); +// txb.setVersion(1); +// +// txb.addInput( +// utxo.txid, +// txPointIndex, +// ); +// +// // todo: modify address once segwit support is in our bip47 +// txb.addOutput(targetPaymentCode.notificationAddressP2PKH(), DUST_LIMIT); +// txb.addOutput(opReturnScript, 0); +// +// // TODO: add possible change output and mark output as dangerous +// if (change > 0) { +// // generate new change address if current change address has been used +// await checkChangeAddressForTransactions(); +// final String changeAddress = await currentChangeAddress; +// txb.addOutput(changeAddress, change); +// } +// +// txb.sign( +// vin: 0, +// keyPair: myKeyPair, +// ); +// +// // sign rest of possible inputs +// for (var i = 1; i < utxosToUse.length - 1; i++) { +// final txid = utxosToUse[i].txid; +// txb.sign( +// vin: i, +// keyPair: utxoSigningData[txid]["keyPair"] as btc_dart.ECPair, +// // witnessValue: utxosToUse[i].value, +// ); +// } +// +// final builtTx = txb.build(); +// +// return Tuple2(builtTx.toHex(), builtTx.virtualSize()); +// } +// +// Future<String> broadcastNotificationTx( +// {required Map<String, dynamic> preparedTx}) async { +// try { +// Logging.instance.log("confirmNotificationTx txData: $preparedTx", +// level: LogLevel.Info); +// final txHash = await electrumXClient.broadcastTransaction( +// rawTx: preparedTx["hex"] as String); +// Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); +// +// // TODO: only refresh transaction data +// try { +// await refresh(); +// } catch (e) { +// Logging.instance.log( +// "refresh() failed in confirmNotificationTx ($walletName::$walletId): $e", +// level: LogLevel.Error, +// ); +// } +// +// return txHash; +// } catch (e, s) { +// Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s", +// level: LogLevel.Error); +// rethrow; +// } +// } +// +// // TODO optimize +// Future<bool> hasConnected(String paymentCodeString) async { +// final myNotificationAddress = +// await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); +// +// final txns = await db +// .getTransactions(walletId) +// .filter() +// .subTypeEqualTo(TransactionSubType.bip47Notification) +// .findAll(); +// +// for (final tx in txns) { +// // quick check that may cause problems? +// if (tx.address.value?.value == myNotificationAddress.value) { +// return true; +// } +// +// final unBlindedPaymentCode = await unBlindedPaymentCodeFromTransaction( +// transaction: tx, +// myNotificationAddress: myNotificationAddress, +// ); +// +// if (paymentCodeString == unBlindedPaymentCode.toString()) { +// return true; +// } +// } +// +// // otherwise return no +// return false; +// } +// +// Future<PaymentCode?> unBlindedPaymentCodeFromTransaction({ +// required Transaction transaction, +// required Address myNotificationAddress, +// }) async { +// if (transaction.address.value != null && +// transaction.address.value!.value != myNotificationAddress.value) { +// return null; +// } +// +// try { +// final blindedCode = +// transaction.outputs.elementAt(1).scriptPubKeyAsm!.split(" ")[1]; +// +// final designatedInput = transaction.inputs.first; +// +// final txPoint = designatedInput.txid.fromHex.toList(); +// final txPointIndex = designatedInput.vout; +// +// final rev = Uint8List(txPoint.length + 4); +// Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); +// final buffer = rev.buffer.asByteData(); +// buffer.setUint32(txPoint.length, txPointIndex, Endian.little); +// +// final pubKey = designatedInput.scriptSigAsm!.split(" ")[1].fromHex; +// +// final myPrivateKey = +// await deriveNotificationPrivateKey(mnemonic: await mnemonic); +// +// final S = SecretPoint(myPrivateKey, pubKey); +// +// final mask = PaymentCode.getMask(S.ecdhSecret(), rev); +// +// final unBlindedPayload = PaymentCode.blind(blindedCode.fromHex, mask); +// +// final unBlindedPaymentCode = +// PaymentCode.initFromPayload(unBlindedPayload); +// +// return unBlindedPaymentCode; +// } catch (e) { +// Logging.instance.log( +// "unBlindedPaymentCodeFromTransaction() failed: $e", +// level: LogLevel.Warning, +// ); +// return null; +// } +// } +// +// Future<List<PaymentCode>> +// getAllPaymentCodesFromNotificationTransactions() async { +// final myAddress = +// await getMyNotificationAddress(DerivePathTypeExt.primaryFor(coin)); +// final txns = await db +// .getTransactions(walletId) +// .filter() +// .subTypeEqualTo(TransactionSubType.bip47Notification) +// .findAll(); +// +// List<PaymentCode> unBlindedList = []; +// +// for (final tx in txns) { +// final unBlinded = await unBlindedPaymentCodeFromTransaction( +// transaction: tx, +// myNotificationAddress: myAddress, +// ); +// if (unBlinded != null) { +// unBlindedList.add(unBlinded); +// } +// } +// +// return unBlindedList; +// } +// +// Future<void> restoreHistoryWith( +// PaymentCode other, +// int maxUnusedAddressGap, +// int maxNumberOfIndexesToCheck, +// ) async { +// // https://en.bitcoin.it/wiki/BIP_0047#Path_levels +// const maxCount = 2147483647; +// assert(maxNumberOfIndexesToCheck < maxCount); +// +// final myPrivateKey = +// await deriveNotificationPrivateKey(mnemonic: await mnemonic); +// +// List<Address> addresses = []; +// int receivingGapCounter = 0; +// int outgoingGapCounter = 0; +// +// for (int i = 0; +// i < maxNumberOfIndexesToCheck && +// (receivingGapCounter < maxUnusedAddressGap || +// outgoingGapCounter < maxUnusedAddressGap); +// i++) { +// final paymentAddress = PaymentAddress.initWithPrivateKey( +// myPrivateKey, +// other, +// i, // index to use +// ); +// +// if (receivingGapCounter < maxUnusedAddressGap) { +// final pair = paymentAddress.getSendAddressKeyPair(); +// final address = generatePaynymSendAddressFromKeyPair( +// pair: pair, +// derivationIndex: i, +// derivePathType: DerivePathType.bip44, +// toPaymentCode: other, +// ); +// addresses.add(address); +// +// final count = await getTxCount(address: address.value); +// +// if (count > 0) { +// receivingGapCounter++; +// } else { +// receivingGapCounter = 0; +// } +// } +// +// if (outgoingGapCounter < maxUnusedAddressGap) { +// final pair = paymentAddress.getReceiveAddressKeyPair(); +// final address = generatePaynymReceivingAddressFromKeyPair( +// pair: pair, +// derivationIndex: i, +// derivePathType: DerivePathType.bip44, +// fromPaymentCode: other, +// ); +// addresses.add(address); +// +// final count = await getTxCount(address: address.value); +// +// if (count > 0) { +// outgoingGapCounter++; +// } else { +// outgoingGapCounter = 0; +// } +// } +// } +// await db.putAddresses(addresses); +// } +// +// Address generatePaynymSendAddressFromKeyPair({ +// required btc_dart.ECPair pair, +// required int derivationIndex, +// required DerivePathType derivePathType, +// required PaymentCode toPaymentCode, +// }) { +// final data = btc_dart.PaymentData(pubkey: pair.publicKey); +// +// String addressString; +// switch (derivePathType) { +// case DerivePathType.bip44: +// addressString = +// btc_dart.P2PKH(data: data, network: network).data.address!; +// break; +// +// // The following doesn't apply currently +// // case DerivePathType.bip49: +// // addressString = btc_dart +// // .P2SH( +// // data: btc_dart.PaymentData( +// // redeem: btc_dart +// // .P2WPKH( +// // data: data, +// // network: network, +// // ) +// // .data), +// // network: network, +// // ) +// // .data +// // .address!; +// // break; +// // +// // case DerivePathType.bip84: +// // addressString = btc_dart +// // .P2WPKH( +// // network: network, +// // data: data, +// // ) +// // .data +// // .address!; +// // break; +// default: +// throw UnimplementedError("segwit paynyms not implemented yet"); +// } +// +// final address = Address( +// walletId: walletId, +// value: addressString, +// publicKey: pair.publicKey, +// derivationIndex: derivationIndex, +// type: AddressType.nonWallet, +// subType: AddressSubType.paynymSend, +// otherData: toPaymentCode.toString(), +// ); +// +// return address; +// } +// +// Address generatePaynymReceivingAddressFromKeyPair({ +// required btc_dart.ECPair pair, +// required int derivationIndex, +// required DerivePathType derivePathType, +// required PaymentCode fromPaymentCode, +// }) { +// final data = btc_dart.PaymentData(pubkey: pair.publicKey); +// +// String addressString; +// AddressType addrType; +// switch (derivePathType) { +// case DerivePathType.bip44: +// addressString = btc_dart +// .P2PKH( +// data: data, +// network: network, +// ) +// .data +// .address!; +// addrType = AddressType.p2pkh; +// break; +// +// // The following doesn't apply currently +// // case DerivePathType.bip49: +// // addressString = btc_dart +// // .P2SH( +// // data: btc_dart.PaymentData( +// // redeem: btc_dart +// // .P2WPKH( +// // data: data, +// // network: network, +// // ) +// // .data), +// // network: network, +// // ) +// // .data +// // .address!; +// // addrType = AddressType.p2sh; +// // break; +// // +// // case DerivePathType.bip84: +// // addressString = btc_dart +// // .P2WPKH( +// // network: network, +// // data: data, +// // ) +// // .data +// // .address!; +// // addrType = AddressType.p2wpkh; +// // break; +// default: +// throw UnimplementedError("segwit paynyms not implemented yet"); +// } +// +// final address = Address( +// walletId: walletId, +// value: addressString, +// publicKey: pair.publicKey, +// derivationIndex: derivationIndex, +// type: addrType, +// subType: AddressSubType.paynymReceive, +// otherData: fromPaymentCode.toString(), +// ); +// +// return address; +// } +// +// Future<Address> getMyNotificationAddress( +// DerivePathType derivePathType, +// ) async { +// // TODO: fix when segwit is here +// derivePathType = DerivePathType.bip44; +// +// AddressType type; +// switch (derivePathType) { +// case DerivePathType.bip44: +// type = AddressType.p2pkh; +// break; +// case DerivePathType.bip49: +// type = AddressType.p2sh; +// break; +// case DerivePathType.bip84: +// type = AddressType.p2wpkh; +// break; +// } +// +// final storedAddress = await db +// .getAddresses(walletId) +// .filter() +// .subTypeEqualTo(AddressSubType.paynymNotification) +// .and() +// .typeEqualTo(type) +// .and() +// .not() +// .typeEqualTo(AddressType.nonWallet) +// .findFirst(); +// +// if (storedAddress != null) { +// return storedAddress; +// } else { +// final root = await getRootNode(mnemonic: await mnemonic); +// final node = root.derivePath(kPaynymDerivePath); +// final paymentCode = PaymentCode.initFromPubKey( +// node.publicKey, +// node.chainCode, +// network, +// ); +// +// String addressString; +// final data = +// btc_dart.PaymentData(pubkey: paymentCode.notificationPublicKey()); +// switch (derivePathType) { +// case DerivePathType.bip44: +// addressString = btc_dart +// .P2PKH( +// data: data, +// network: network, +// ) +// .data +// .address!; +// break; +// // case DerivePathType.bip49: +// // addressString = btc_dart +// // .P2SH( +// // data: btc_dart.PaymentData( +// // redeem: btc_dart +// // .P2WPKH( +// // data: data, +// // network: network, +// // ) +// // .data), +// // network: network, +// // ) +// // .data +// // .address!; +// // break; +// // case DerivePathType.bip84: +// // addressString = btc_dart +// // .P2WPKH( +// // network: network, +// // data: data, +// // ) +// // .data +// // .address!; +// // break; +// default: +// throw UnimplementedError("segwit paynyms not implemented yet"); +// } +// +// final address = Address( +// walletId: walletId, +// value: addressString, +// publicKey: paymentCode.getPubKey(), +// derivationIndex: 0, +// type: type, +// subType: AddressSubType.paynymNotification, +// otherData: paymentCode.toString(), +// ); +// +// await db.putAddress(address); +// return address; +// } +// } +// } diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 7e88fe3c5..b67054b4c 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -14,16 +14,17 @@ import 'package:isar/isar.dart'; import 'package:stackwallet/db/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -34,6 +35,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -50,8 +52,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "bb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e"; -enum DerivePathType { bip44 } - bip32.BIP32 getBip32Node(int chain, int index, String mnemonic, NetworkType network, DerivePathType derivePathType) { final root = getBip32Root(mnemonic, network); @@ -90,7 +90,8 @@ bip32.BIP32 getBip32NodeFromRoot( case DerivePathType.bip44: return root.derivePath("m/44'/$coinType'/0'/$chain/$index"); default: - throw Exception("DerivePathType must not be null."); + throw Exception( + "DerivePathType null or unsupported (${DerivePathType.bip44})"); } } @@ -125,7 +126,8 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { return getBip32Root(args.item1, args.item2); } -class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { +class DogecoinWallet extends CoinServiceAPI + with WalletCache, WalletDB, ElectrumXParsing { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); final _prefs = Prefs.instance; @@ -150,8 +152,16 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { Future<List<isar_models.UTXO>> get utxos => db.getUTXOs(walletId).findAll(); @override - Future<List<isar_models.Transaction>> get transactions => - db.getTransactions(walletId).sortByTimestampDesc().findAll(); + Future<List<isar_models.Transaction>> get transactions => db + .getTransactions(walletId) + .filter() + .not() + .group((q) => q + .subTypeEqualTo(isar_models.TransactionSubType.bip47Notification) + .and() + .typeEqualTo(isar_models.TransactionType.incoming)) + .sortByTimestampDesc() + .findAll(); @override Coin get coin => _coin; @@ -168,7 +178,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip44); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); // @override Future<String> get currentChangeAddress async => @@ -182,7 +192,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip44); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -217,6 +227,14 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", @@ -371,7 +389,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { ); break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } receivingNodes.addAll({ "${_id}_$j": { @@ -447,6 +465,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -523,11 +542,30 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { await _generateAddressForChain(1, 0, DerivePathType.bip44); p2pkhChangeAddressArray.add(address); } + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ]); + } - await db.putAddresses([ - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ]); + // paynym stuff + // // generate to ensure notification address is in db before refreshing transactions + // await getMyNotificationAddress(DerivePathType.bip44); + // + // // refresh transactions to pick up any received notification transactions + // await _refreshTransactions(); + // + // // restore paynym transactions + // await restoreAllHistory( + // maxUnusedAddressGap: maxUnusedAddressGap, + // maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + // ); await _updateUTXOs(); @@ -596,6 +634,13 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } return needsRefresh; + } on NoSuchTransactionException catch (e) { + // TODO: move direct transactions elsewhere + await db.isar.writeTxn(() async { + await db.isar.transactions.deleteByTxidWalletId(e.txid, walletId); + }); + await txTracker.deleteTransaction(e.txid); + return true; } catch (e, s) { Logging.instance.log( "Exception caught in refreshIfThereIsNewData: $e\n$s", @@ -761,6 +806,9 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId)); await _checkCurrentReceivingAddressesForTransactions(); + // paynym stuff + // await checkAllCurrentReceivingPaynymAddressesForTransactions(); + final fetchFuture = _refreshTransactions(); final utxosRefreshFuture = _updateUTXOs(); GlobalEventBus.instance @@ -1011,46 +1059,31 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _fetchTransactionData(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override @@ -1099,6 +1132,27 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { _secureStore = secureStore; initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); + + // paynym stuff + // initPaynymWalletInterface( + // walletId: walletId, + // walletName: walletName, + // network: network, + // coin: coin, + // db: db, + // electrumXClient: electrumXClient, + // getMnemonic: () => mnemonic, + // getChainHeight: () => chainHeight, + // getCurrentChangeAddress: () => currentChangeAddress, + // estimateTxFee: estimateTxFee, + // prepareSend: prepareSend, + // getTxCount: getTxCount, + // fetchBuildTxData: fetchBuildTxData, + // refresh: refresh, + // checkChangeAddressForTransactions: checkChangeAddressForTransactions, + // addDerivation: addDerivation, + // addDerivations: addDerivations, + // ); } @override @@ -1161,10 +1215,8 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .not() .typeEqualTo(isar_models.AddressType.nonWallet) .and() - .group((q) => q - .subTypeEqualTo(isar_models.AddressSubType.receiving) - .or() - .subTypeEqualTo(isar_models.AddressSubType.change)) + .not() + .subTypeEqualTo(isar_models.AddressSubType.nonWallet) .findAll(); return allAddresses; } @@ -1274,9 +1326,8 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip44: address = P2PKH(data: data, network: network).data.address!; break; - // default: - // // should never hit this due to all enum cases handled - // return null; + default: + throw Exception("Unsupported DerivePathType"); } // add generated address & info to derivations @@ -1321,6 +1372,8 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .sortByDerivationIndexDesc() .findFirst(); break; + default: + throw Exception("Unsupported DerivePathType"); } return address!.value; } @@ -1333,6 +1386,8 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip44: key = "${walletId}_${chainId}DerivationsP2PKH"; break; + default: + throw Exception("Unsupported DerivePathType"); } return key; } @@ -1503,15 +1558,34 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { coin: coin, ); - // todo check here if we should mark as blocked + // fetch stored tx to see if paynym notification tx and block utxo + final storedTx = await db.getTransaction( + walletId, + fetchedUtxoList[i][j]["tx_hash"] as String, + ); + + bool shouldBlock = false; + String? blockReason; + + if (storedTx?.subType == + isar_models.TransactionSubType.bip47Notification && + storedTx?.type == isar_models.TransactionType.incoming) { + // probably safe to assume this is an incoming tx as it is a utxo + // belonging to this wallet. The extra check may be redundant but + // just in case... + + shouldBlock = true; + blockReason = "Incoming paynym notification transaction."; + } + final utxo = isar_models.UTXO( walletId: walletId, txid: txn["txid"] as String, vout: fetchedUtxoList[i][j]["tx_pos"] as int, value: fetchedUtxoList[i][j]["value"] as int, name: "", - isBlocked: false, - blockedReason: null, + isBlocked: shouldBlock, + blockedReason: blockReason, isCoinbase: txn["is_coinbase"] as bool? ?? false, blockHash: txn["blockhash"] as String?, blockHeight: fetchedUtxoList[i][j]["height"] as int?, @@ -1539,7 +1613,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); @@ -1656,7 +1730,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip44); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1675,12 +1749,12 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions($DerivePathType.bip44): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions($DerivePathType.bip44): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1700,7 +1774,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip44); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1719,7 +1793,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkChangeAddressForTransactions(${DerivePathType.bip44}): $e\n$s", + "Exception rethrown from _checkChangeAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2088,7 +2162,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip44), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2141,8 +2215,8 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { feeForTwoOutputs) { // generate new change address if current change address has been used await checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip44); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -2340,6 +2414,8 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip44: addressesP2PKH.add(address); break; + default: + throw Exception("Unsupported DerivePathType"); } } } @@ -2490,6 +2566,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; @@ -2757,7 +2834,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip44); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); @@ -2775,7 +2852,7 @@ class DogecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Dogecoin Network final dogecoin = NetworkType( messagePrefix: '\x18Dogecoin Signed Message:\n', - bech32: 'bc', + // bech32: 'bc', bip32: Bip32Type(public: 0x02facafd, private: 0x02fac398), pubKeyHash: 0x1e, scriptHash: 0x16, @@ -2783,7 +2860,7 @@ final dogecoin = NetworkType( final dogecointestnet = NetworkType( messagePrefix: '\x18Dogecoin Signed Message:\n', - bech32: 'tb', + // bech32: 'tb', bip32: Bip32Type(public: 0x043587cf, private: 0x04358394), pubKeyHash: 0x71, scriptHash: 0xc4, diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index 86ed2979b..42198104c 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -839,6 +839,10 @@ class EpicCashWallet extends CoinServiceAPI isar_models.Address? address = await db .getAddresses(walletId) .filter() + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .and() + .typeEqualTo(isar_models.AddressType.mimbleWimble) + .and() .derivationIndexEqualTo(index) .findFirst(); @@ -877,8 +881,14 @@ class EpicCashWallet extends CoinServiceAPI (await _currentReceivingAddress)?.value ?? (await _getReceivingAddressForIndex(0)).value; - Future<isar_models.Address?> get _currentReceivingAddress => - db.getAddresses(walletId).sortByDerivationIndexDesc().findFirst(); + Future<isar_models.Address?> get _currentReceivingAddress => db + .getAddresses(walletId) + .filter() + .subTypeEqualTo(isar_models.AddressSubType.receiving) + .and() + .typeEqualTo(isar_models.AddressType.mimbleWimble) + .sortByDerivationIndexDesc() + .findFirst(); @override Future<void> exit() async { @@ -1416,6 +1426,14 @@ class EpicCashWallet extends CoinServiceAPI }); await updateCachedChainHeight(latestHeight!); + if (latestHeight! > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return latestHeight!; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index ec63db186..9f767dbba 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -818,44 +818,31 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final currentPrice = await firoPrice; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _fetchTransactionData(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } /// Holds the max fee that can be sent @@ -3665,7 +3652,7 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); @@ -4897,6 +4884,14 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index c36f10eb6..03b569511 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -17,13 +17,13 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -33,6 +33,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -50,8 +51,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "4966625a4b2851d9fdee139e56211a0d88575f59ed816ff5e6a63deb4e3e29a0"; -enum DerivePathType { bip44, bip49, bip84 } - bip32.BIP32 getBip32Node( int chain, int index, @@ -103,7 +102,7 @@ bip32.BIP32 getBip32NodeFromRoot( case DerivePathType.bip84: return root.derivePath("m/84'/$coinType'/0'/$chain/$index"); default: - throw Exception("DerivePathType must not be null."); + throw Exception("DerivePathType unsupported"); } } @@ -138,7 +137,8 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { return getBip32Root(args.item1, args.item2); } -class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { +class LitecoinWallet extends CoinServiceAPI + with WalletCache, WalletDB, ElectrumXParsing { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); @@ -193,7 +193,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip84); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -206,7 +206,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip84); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -241,6 +241,14 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", @@ -421,7 +429,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2wpkh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType unsupported"); } final address = isar_models.Address( @@ -509,6 +517,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -682,14 +691,25 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { p2wpkhChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2wpkhReceiveAddressArray, - ...p2wpkhChangeAddressArray, - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } await _updateUTXOs(); @@ -1194,46 +1214,31 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _refreshTransactions(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override @@ -1532,6 +1537,8 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .address!; addrType = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType unsupported"); } // add generated address & info to derivations @@ -1578,6 +1585,8 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: type = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType unsupported"); } address = await db .getAddresses(walletId) @@ -1605,6 +1614,8 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: key = "${walletId}_${chainId}DerivationsP2WPKH"; break; + default: + throw Exception("DerivePathType unsupported"); } return key; } @@ -1776,7 +1787,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); @@ -1891,7 +1902,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1910,7 +1921,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1930,7 +1941,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip84); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1949,12 +1960,12 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2349,7 +2360,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip84), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2388,8 +2399,8 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip84); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -2595,6 +2606,8 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: addressesP2WPKH.add(address); break; + default: + throw Exception("DerivePathType unsupported"); } } } @@ -2879,6 +2892,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; @@ -3345,7 +3359,7 @@ class LitecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/coins/manager.dart b/lib/services/coins/manager.dart index a590752e0..203c2d05f 100644 --- a/lib/services/coins/manager.dart +++ b/lib/services/coins/manager.dart @@ -9,6 +9,7 @@ import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; @@ -109,8 +110,15 @@ class Manager with ChangeNotifier { try { final txid = await _currentWallet.confirmSend(txData: txData); - txData["txid"] = txid; - await _currentWallet.updateSentCachedTxData(txData); + try { + txData["txid"] = txid; + await _currentWallet.updateSentCachedTxData(txData); + } catch (e, s) { + // do not rethrow as that would get handled as a send failure further up + // also this is not critical code and transaction should show up on \ + // refresh regardless + Logging.instance.log("$e\n$s", level: LogLevel.Warning); + } notifyListeners(); return txid; @@ -214,4 +222,6 @@ class Manager with ChangeNotifier { } int get currentHeight => _currentWallet.storedChainHeight; + + bool get hasPaynymSupport => _currentWallet is PaynymWalletInterface; } diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index d7346a880..10852044b 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -17,13 +17,13 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/node_service.dart'; @@ -33,6 +33,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -50,8 +51,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"; -enum DerivePathType { bip44, bip49, bip84 } - bip32.BIP32 getBip32Node( int chain, int index, @@ -135,7 +134,8 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) { return getBip32Root(args.item1, args.item2); } -class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { +class NamecoinWallet extends CoinServiceAPI + with WalletCache, WalletDB, ElectrumXParsing { static const integrationTestFlag = bool.fromEnvironment("IS_INTEGRATION_TEST"); @@ -188,7 +188,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip84); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -201,7 +201,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip84); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -236,6 +236,14 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", @@ -411,7 +419,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2wpkh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } final address = isar_models.Address( @@ -499,6 +507,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -672,14 +681,25 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { p2wpkhChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2wpkhReceiveAddressArray, - ...p2wpkhChangeAddressArray, - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ...p2shReceiveAddressArray, + ...p2shChangeAddressArray, + ]); + } await _updateUTXOs(); @@ -1183,46 +1203,31 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _refreshTransactions(); - // _transactionData = Future(() => data); - // } - // - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override @@ -1418,17 +1423,21 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { - final features = await electrumXClient.getServerFeatures(); - Logging.instance.log("features: $features", level: LogLevel.Info); - switch (coin) { - case Coin.namecoin: - if (features['genesis_hash'] != GENESIS_HASH_MAINNET) { - throw Exception("genesis hash does not match main net!"); - } - break; - default: - throw Exception( - "Attempted to generate a NamecoinWallet using a non namecoin coin type: ${coin.name}"); + try { + final features = await electrumXClient.getServerFeatures(); + Logging.instance.log("features: $features", level: LogLevel.Info); + switch (coin) { + case Coin.namecoin: + if (features['genesis_hash'] != GENESIS_HASH_MAINNET) { + throw Exception("genesis hash does not match main net!"); + } + break; + default: + throw Exception( + "Attempted to generate a NamecoinWallet using a non namecoin coin type: ${coin.name}"); + } + } catch (e, s) { + Logging.instance.log("$e/n$s", level: LogLevel.Info); } } @@ -1509,6 +1518,8 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { .address!; addrType = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType must not be null."); } // add generated address & info to derivations @@ -1555,6 +1566,9 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: type = isar_models.AddressType.p2wpkh; break; + default: + throw Exception( + "DerivePathType null or unsupported (${DerivePathType.bip44})"); } address = await db .getAddresses(walletId) @@ -1582,6 +1596,8 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: key = "${walletId}_${chainId}DerivationsP2WPKH"; break; + default: + throw Exception("DerivePathType $derivePathType not supported"); } return key; } @@ -1755,7 +1771,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); @@ -1873,7 +1889,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1892,7 +1908,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1912,7 +1928,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip84); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1932,12 +1948,12 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2336,7 +2352,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip84), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2375,8 +2391,8 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip84); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -2869,6 +2885,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; @@ -3336,7 +3353,7 @@ class NamecoinWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index d19fdf769..1f6c7a2ea 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -32,6 +32,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; @@ -48,8 +49,6 @@ const String GENESIS_HASH_MAINNET = const String GENESIS_HASH_TESTNET = "0000594ada5310b367443ee0afd4fa3d0bbd5850ea4e33cdc7d6a904a7ec7c90"; -enum DerivePathType { bip44, bip84 } - bip32.BIP32 getBip32Node( int chain, int index, @@ -96,7 +95,7 @@ bip32.BIP32 getBip32NodeFromRoot( case DerivePathType.bip84: return root.derivePath("m/84'/$coinType'/0'/$chain/$index"); default: - throw Exception("DerivePathType must not be null."); + throw Exception("DerivePathType $derivePathType not supported"); } } @@ -184,7 +183,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.receiving) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(0, 0, DerivePathType.bip84); + await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); Future<String> get currentChangeAddress async => (await _currentChangeAddress).value; @@ -197,7 +196,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { .subTypeEqualTo(isar_models.AddressSubType.change) .sortByDerivationIndexDesc() .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathType.bip84); + await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); @override Future<void> exit() async { @@ -232,6 +231,14 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { final result = await _electrumXClient.getBlockHeadTip(); final height = result["height"] as int; await updateCachedChainHeight(height); + if (height > storedChainHeight) { + GlobalEventBus.instance.fire( + UpdatedInBackgroundEvent( + "Updated current chain height in $walletId $walletName!", + walletId, + ), + ); + } return height; } catch (e, s) { Logging.instance.log("Exception caught in chainHeight: $e\n$s", @@ -394,7 +401,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { addrType = isar_models.AddressType.p2wpkh; break; default: - throw Exception("No Path type $type exists"); + throw Exception("DerivePathType $type not supported"); } final address = isar_models.Address( @@ -482,6 +489,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { required String mnemonic, int maxUnusedAddressGap = 20, int maxNumberOfIndexesToCheck = 1000, + bool isRescan = false, }) async { longMutex = true; @@ -607,12 +615,21 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { p2wpkhChangeAddressArray.add(address); } - await db.putAddresses([ - ...p2wpkhReceiveAddressArray, - ...p2wpkhChangeAddressArray, - ...p2pkhReceiveAddressArray, - ...p2pkhChangeAddressArray, - ]); + if (isRescan) { + await db.updateOrPutAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ]); + } else { + await db.putAddresses([ + ...p2wpkhReceiveAddressArray, + ...p2wpkhChangeAddressArray, + ...p2pkhReceiveAddressArray, + ...p2pkhChangeAddressArray, + ]); + } await _updateUTXOs(); @@ -1114,46 +1131,31 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - // final priceData = - // await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - // Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - // final locale = - // Platform.isWindows ? "en_US" : await Devicelocale.currentLocale; - // final String worthNow = Format.localizedStringAsFixed( - // value: - // ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - // Decimal.fromInt(Constants.satsPerCoin(coin))) - // .toDecimal(scaleOnInfinitePrecision: 2), - // decimalPlaces: 2, - // locale: locale!); - // - // final tx = models.Transaction( - // txid: txData["txid"] as String, - // confirmedStatus: false, - // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - // txType: "Sent", - // amount: txData["recipientAmt"] as int, - // worthNow: worthNow, - // worthAtBlockTimestamp: worthNow, - // fees: txData["fee"] as int, - // inputSize: 0, - // outputSize: 0, - // inputs: [], - // outputs: [], - // address: txData["address"] as String, - // height: -1, - // confirmations: 0, - // ); - // - // if (cachedTxData == null) { - // final data = await _refreshTransactions(); - // _transactionData = Future(() => data); - // } else { - // final transactions = cachedTxData!.getAllTransactions(); - // transactions[tx.txid] = tx; - // cachedTxData = models.TransactionData.fromMap(transactions); - // _transactionData = Future(() => cachedTxData!); - // } + final transaction = isar_models.Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + type: isar_models.TransactionType.outgoing, + subType: isar_models.TransactionSubType.none, + amount: txData["recipientAmt"] as int, + fee: txData["fee"] as int, + height: null, + isCancelled: false, + isLelantus: false, + otherData: null, + slateId: null, + ); + + final address = txData["address"] is String + ? await db.getAddress(walletId, txData["address"] as String) + : null; + + await db.addNewTransactionData( + [ + Tuple4(transaction, [], [], address), + ], + walletId, + ); } @override @@ -1336,17 +1338,21 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { Logging.instance .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info); if (!integrationTestFlag) { - final features = await electrumXClient.getServerFeatures(); - Logging.instance.log("features: $features", level: LogLevel.Info); - switch (coin) { - case Coin.particl: - if (features['genesis_hash'] != GENESIS_HASH_MAINNET) { - throw Exception("genesis hash does not match main net!"); - } - break; - default: - throw Exception( - "Attempted to generate a ParticlWallet using a non particl coin type: ${coin.name}"); + try { + final features = await electrumXClient.getServerFeatures(); + Logging.instance.log("features: $features", level: LogLevel.Info); + switch (coin) { + case Coin.particl: + if (features['genesis_hash'] != GENESIS_HASH_MAINNET) { + throw Exception("genesis hash does not match main net!"); + } + break; + default: + throw Exception( + "Attempted to generate a ParticlWallet using a non particl coin type: ${coin.name}"); + } + } catch (e, s) { + Logging.instance.log("$e/n$s", level: LogLevel.Info); } } @@ -1407,6 +1413,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { address = P2WPKH(network: _network, data: data).data.address!; addrType = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType $derivePathType not supported"); } // add generated address & info to derivations @@ -1450,6 +1458,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: type = isar_models.AddressType.p2wpkh; break; + default: + throw Exception("DerivePathType $derivePathType not supported"); } address = await db .getAddresses(walletId) @@ -1475,6 +1485,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: key = "${walletId}_${chainId}DerivationsP2WPKH"; break; + default: + throw Exception("DerivePathType $derivePathType not supported"); } return key; } @@ -1646,7 +1658,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // TODO move this out of here and into IDB await db.isar.writeTxn(() async { - await db.isar.utxos.clear(); + await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); await db.isar.utxos.putAll(outputArray); }); @@ -1761,7 +1773,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1780,7 +1792,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { } } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -1800,7 +1812,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new change address final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathType.bip84); + 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); final existing = await db .getAddresses(walletId) @@ -1819,12 +1831,12 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { } } on SocketException catch (se, s) { Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $se\n$s", + "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", level: LogLevel.Error); return; } catch (e, s) { Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathType.bip84}): $e\n$s", + "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", level: LogLevel.Error); rethrow; } @@ -2189,7 +2201,6 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { Logging.instance.log(s.toString(), level: LogLevel.Warning); } // Logging.instance.log("output is transparent", level: LogLevel.Info); - } else if (output.containsKey('ct_fee') as bool) { // or type: data // TODO handle CT tx @@ -2501,7 +2512,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { utxoSigningData: utxoSigningData, recipients: [ _recipientAddress, - await _getCurrentAddressForChain(1, DerivePathType.bip84), + await _getCurrentAddressForChain(1, DerivePathTypeExt.primaryFor(coin)), ], satoshiAmounts: [ satoshiAmountToSend, @@ -2540,8 +2551,8 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { feeForTwoOutputs) { // generate new change address if current change address has been used await _checkChangeAddressForTransactions(); - final String newChangeAddress = - await _getCurrentAddressForChain(1, DerivePathType.bip84); + final String newChangeAddress = await _getCurrentAddressForChain( + 1, DerivePathTypeExt.primaryFor(coin)); int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; @@ -2743,6 +2754,9 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { case DerivePathType.bip84: addressesP2WPKH.add(address); break; + default: + throw Exception( + "DerivePathType ${addressType(address: address)} not supported"); } } } @@ -2967,6 +2981,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { mnemonic: mnemonic!, maxUnusedAddressGap: maxUnusedAddressGap, maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, + isRescan: true, ); longMutex = false; @@ -3328,7 +3343,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB { // Use new index to derive a new receiving address final newReceivingAddress = await _generateAddressForChain( - 0, newReceivingIndex, DerivePathType.bip84); + 0, newReceivingIndex, DerivePathTypeExt.primaryFor(coin)); // Add that new receiving address await db.putAddress(newReceivingAddress); diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart new file mode 100644 index 000000000..c0b572b20 --- /dev/null +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -0,0 +1,224 @@ +import 'package:bip47/src/util.dart'; +import 'package:decimal/decimal.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:tuple/tuple.dart'; + +mixin ElectrumXParsing { + Future<Tuple4<Transaction, List<Output>, List<Input>, Address>> + parseTransaction( + Map<String, dynamic> txData, + dynamic electrumxClient, + List<Address> myAddresses, + Coin coin, + int minConfirms, + String walletId, + ) async { + Set<String> receivingAddresses = myAddresses + .where((e) => + e.subType == AddressSubType.receiving || + e.subType == AddressSubType.paynymReceive || + e.subType == AddressSubType.paynymNotification) + .map((e) => e.value) + .toSet(); + Set<String> changeAddresses = myAddresses + .where((e) => e.subType == AddressSubType.change) + .map((e) => e.value) + .toSet(); + + Set<String> inputAddresses = {}; + Set<String> outputAddresses = {}; + + int totalInputValue = 0; + int totalOutputValue = 0; + + int amountSentFromWallet = 0; + int amountReceivedInWallet = 0; + int changeAmount = 0; + + // parse inputs + for (final input in txData["vin"] as List) { + final prevTxid = input["txid"] as String; + final prevOut = input["vout"] as int; + + // fetch input tx to get address + final inputTx = await electrumxClient.getTransaction( + txHash: prevTxid, + coin: coin, + ); + + for (final output in inputTx["vout"] as List) { + // check matching output + if (prevOut == output["n"]) { + // get value + final value = Format.decimalAmountToSatoshis( + Decimal.parse(output["value"].toString()), + coin, + ); + + // add value to total + totalInputValue += value; + + // get input(prevOut) address + final address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? + output["scriptPubKey"]?["address"] as String?; + + if (address != null) { + inputAddresses.add(address); + + // if input was from my wallet, add value to amount sent + if (receivingAddresses.contains(address) || + changeAddresses.contains(address)) { + amountSentFromWallet += value; + } + } + } + } + } + + // parse outputs + for (final output in txData["vout"] as List) { + // get value + final value = Format.decimalAmountToSatoshis( + Decimal.parse(output["value"].toString()), + coin, + ); + + // add value to total + totalOutputValue += value; + + // get output address + final address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? + output["scriptPubKey"]?["address"] as String?; + if (address != null) { + outputAddresses.add(address); + + // if output was to my wallet, add value to amount received + if (receivingAddresses.contains(address)) { + amountReceivedInWallet += value; + } else if (changeAddresses.contains(address)) { + changeAmount += value; + } + } + } + + final mySentFromAddresses = [ + ...receivingAddresses.intersection(inputAddresses), + ...changeAddresses.intersection(inputAddresses) + ]; + final myReceivedOnAddresses = + receivingAddresses.intersection(outputAddresses); + final myChangeReceivedOnAddresses = + changeAddresses.intersection(outputAddresses); + + final fee = totalInputValue - totalOutputValue; + + // this is the address initially used to fetch the txid + Address transactionAddress = txData["address"] as Address; + + TransactionType type; + int amount; + if (mySentFromAddresses.isNotEmpty && myReceivedOnAddresses.isNotEmpty) { + // tx is sent to self + type = TransactionType.sentToSelf; + + // should be 0 + amount = + amountSentFromWallet - amountReceivedInWallet - fee - changeAmount; + } else if (mySentFromAddresses.isNotEmpty) { + // outgoing tx + type = TransactionType.outgoing; + amount = amountSentFromWallet - changeAmount - fee; + + final possible = + outputAddresses.difference(myChangeReceivedOnAddresses).first; + + if (transactionAddress.value != possible) { + transactionAddress = Address( + walletId: walletId, + value: possible, + derivationIndex: -1, + subType: AddressSubType.nonWallet, + type: AddressType.nonWallet, + publicKey: [], + ); + } + } else { + // incoming tx + type = TransactionType.incoming; + amount = amountReceivedInWallet; + } + + List<Output> outs = []; + List<Input> ins = []; + + for (final json in txData["vin"] as List) { + bool isCoinBase = json['coinbase'] != null; + final input = Input( + walletId: walletId, + txid: json['txid'] as String, + vout: json['vout'] as int? ?? -1, + scriptSig: json['scriptSig']?['hex'] as String?, + scriptSigAsm: json['scriptSig']?['asm'] as String?, + isCoinbase: isCoinBase ? isCoinBase : json['is_coinbase'] as bool?, + sequence: json['sequence'] as int?, + innerRedeemScriptAsm: json['innerRedeemscriptAsm'] as String?, + ); + ins.add(input); + } + + for (final json in txData["vout"] as List) { + final output = Output( + walletId: walletId, + scriptPubKey: json['scriptPubKey']?['hex'] as String?, + scriptPubKeyAsm: json['scriptPubKey']?['asm'] as String?, + scriptPubKeyType: json['scriptPubKey']?['type'] as String?, + scriptPubKeyAddress: + json["scriptPubKey"]?["addresses"]?[0] as String? ?? + json['scriptPubKey']?['type'] as String? ?? + "", + value: Format.decimalAmountToSatoshis( + Decimal.parse(json["value"].toString()), + coin, + ), + ); + outs.add(output); + } + + TransactionSubType txSubType = TransactionSubType.none; + if (this is PaynymWalletInterface && outs.length > 1 && ins.isNotEmpty) { + for (int i = 0; i < outs.length; i++) { + List<String>? scriptChunks = outs[i].scriptPubKeyAsm?.split(" "); + if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { + final blindedPaymentCode = scriptChunks![1]; + final bytes = blindedPaymentCode.fromHex; + + // https://en.bitcoin.it/wiki/BIP_0047#Sending + if (bytes.length == 80 && bytes.first == 1) { + txSubType = TransactionSubType.bip47Notification; + } + } + } + } + + final tx = Transaction( + walletId: walletId, + txid: txData["txid"] as String, + timestamp: txData["blocktime"] as int? ?? + (DateTime.now().millisecondsSinceEpoch ~/ 1000), + type: type, + subType: txSubType, + amount: amount, + fee: fee, + height: txData["height"] as int?, + isCancelled: false, + isLelantus: false, + slateId: null, + otherData: null, + ); + + return Tuple4(tx, outs, ins, transactionAddress); + } +} diff --git a/lib/services/mixins/paynym_wallet_interface.dart b/lib/services/mixins/paynym_wallet_interface.dart new file mode 100644 index 000000000..87ef97df5 --- /dev/null +++ b/lib/services/mixins/paynym_wallet_interface.dart @@ -0,0 +1,1257 @@ +import 'dart:convert'; +import 'dart:math'; +import 'dart:typed_data'; + +import 'package:bip32/bip32.dart' as bip32; +import 'package:bip47/bip47.dart'; +import 'package:bip47/src/util.dart'; +import 'package:bitcoindart/bitcoindart.dart' as btc_dart; +import 'package:bitcoindart/src/utils/constants/op.dart' as op; +import 'package:bitcoindart/src/utils/script.dart' as bscript; +import 'package:isar/isar.dart'; +import 'package:pointycastle/digests/sha256.dart'; +import 'package:stackwallet/db/main_db.dart'; +import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/exceptions/wallet/insufficient_balance_exception.dart'; +import 'package:stackwallet/exceptions/wallet/paynym_send_exception.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/utilities/bip32_utils.dart'; +import 'package:stackwallet/utilities/bip47_utils.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:stackwallet/utilities/logger.dart'; +import 'package:tuple/tuple.dart'; + +const kPaynymDerivePath = "m/47'/0'/0'"; + +mixin PaynymWalletInterface { + // passed in wallet data + late final String _walletId; + late final String _walletName; + late final btc_dart.NetworkType _network; + late final Coin _coin; + late final MainDB _db; + late final ElectrumX _electrumXClient; + late final SecureStorageInterface _secureStorage; + late final int _dustLimitP2PKH; + late final int _minConfirms; + + // passed in wallet functions + late final Future<List<String>> Function() _getMnemonic; + late final Future<int> Function() _getChainHeight; + late final Future<String> Function() _getCurrentChangeAddress; + late final int Function({ + required int vSize, + required int feeRatePerKB, + }) _estimateTxFee; + late final Future<Map<String, dynamic>> Function({ + required String address, + required int satoshiAmount, + Map<String, dynamic>? args, + }) _prepareSend; + late final Future<int> Function({ + required String address, + }) _getTxCount; + late final Future<Map<String, dynamic>> Function( + List<UTXO> utxosToUse, + ) _fetchBuildTxData; + late final Future<void> Function() _refresh; + late final Future<void> Function() _checkChangeAddressForTransactions; + late final Future<void> Function({ + required int chain, + required String address, + required String pubKey, + required String wif, + required DerivePathType derivePathType, + }) _addDerivation; + late final Future<void> Function({ + required int chain, + required DerivePathType derivePathType, + required Map<String, dynamic> derivationsToAdd, + }) _addDerivations; + + // initializer + void initPaynymWalletInterface({ + required String walletId, + required String walletName, + required btc_dart.NetworkType network, + required Coin coin, + required MainDB db, + required ElectrumX electrumXClient, + required SecureStorageInterface secureStorage, + required int dustLimitP2PKH, + required int minConfirms, + required Future<List<String>> Function() getMnemonic, + required Future<int> Function() getChainHeight, + required Future<String> Function() getCurrentChangeAddress, + required int Function({ + required int vSize, + required int feeRatePerKB, + }) + estimateTxFee, + required Future<Map<String, dynamic>> Function({ + required String address, + required int satoshiAmount, + Map<String, dynamic>? args, + }) + prepareSend, + required Future<int> Function({ + required String address, + }) + getTxCount, + required Future<Map<String, dynamic>> Function( + List<UTXO> utxosToUse, + ) + fetchBuildTxData, + required Future<void> Function() refresh, + required Future<void> Function() checkChangeAddressForTransactions, + required Future<void> Function({ + required int chain, + required String address, + required String pubKey, + required String wif, + required DerivePathType derivePathType, + }) + addDerivation, + required Future<void> Function({ + required int chain, + required DerivePathType derivePathType, + required Map<String, dynamic> derivationsToAdd, + }) + addDerivations, + }) { + _walletId = walletId; + _walletName = walletName; + _network = network; + _coin = coin; + _db = db; + _electrumXClient = electrumXClient; + _secureStorage = secureStorage; + _dustLimitP2PKH = dustLimitP2PKH; + _minConfirms = minConfirms; + _getMnemonic = getMnemonic; + _getChainHeight = getChainHeight; + _getCurrentChangeAddress = getCurrentChangeAddress; + _estimateTxFee = estimateTxFee; + _prepareSend = prepareSend; + _getTxCount = getTxCount; + _fetchBuildTxData = fetchBuildTxData; + _refresh = refresh; + _checkChangeAddressForTransactions = checkChangeAddressForTransactions; + _addDerivation = addDerivation; + _addDerivations = addDerivations; + } + + // convenience getter + btc_dart.NetworkType get networkType => _network; + + Future<Address> currentReceivingPaynymAddress(PaymentCode sender) async { + final keys = await lookupKey(sender.toString()); + final address = await _db + .getAddresses(_walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymReceive) + .and() + .anyOf<String, Address>(keys, (q, String e) => q.otherDataEqualTo(e)) + .sortByDerivationIndexDesc() + .findFirst(); + + if (address == null) { + final generatedAddress = await _generatePaynymReceivingAddress(sender, 0); + + final existing = await _db + .getAddresses(_walletId) + .filter() + .valueEqualTo(generatedAddress.value) + .findFirst(); + + if (existing == null) { + // Add that new address + await _db.putAddress(generatedAddress); + } else { + // we need to update the address + await _db.updateAddress(existing, generatedAddress); + } + + return currentReceivingPaynymAddress(sender); + } else { + return address; + } + } + + Future<Address> _generatePaynymReceivingAddress( + PaymentCode sender, + int index, + ) async { + final myPrivateKey = await deriveReceivingPrivateKey( + mnemonic: await _getMnemonic(), + index: index, + ); + + final paymentAddress = PaymentAddress.initWithPrivateKey( + myPrivateKey, + sender, + 0, + ); + final pair = paymentAddress.getReceiveAddressKeyPair(); + final address = await generatePaynymReceivingAddressFromKeyPair( + pair: pair, + derivationIndex: index, + derivePathType: DerivePathType.bip44, + fromPaymentCode: sender, + ); + return address; + } + + Future<void> checkCurrentPaynymReceivingAddressForTransactions( + PaymentCode sender) async { + final address = await currentReceivingPaynymAddress(sender); + final txCount = await _getTxCount(address: address.value); + if (txCount > 0) { + // generate next address and add to db + final nextAddress = await _generatePaynymReceivingAddress( + sender, + address.derivationIndex + 1, + ); + + final existing = await _db + .getAddresses(_walletId) + .filter() + .valueEqualTo(nextAddress.value) + .findFirst(); + + if (existing == null) { + // Add that new address + await _db.putAddress(nextAddress); + } else { + // we need to update the address + await _db.updateAddress(existing, nextAddress); + } + // keep checking until address with no tx history is set as current + await checkCurrentPaynymReceivingAddressForTransactions(sender); + } + } + + Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() async { + final codes = await getAllPaymentCodesFromNotificationTransactions(); + final List<Future<void>> futures = []; + for (final code in codes) { + futures.add(checkCurrentPaynymReceivingAddressForTransactions(code)); + } + await Future.wait(futures); + } + + // generate bip32 payment code root + Future<bip32.BIP32> getRootNode({ + required List<String> mnemonic, + }) async { + final root = await Bip32Utils.getBip32Root(mnemonic.join(" "), _network); + return root; + } + + Future<Uint8List> deriveNotificationPrivateKey({ + required List<String> mnemonic, + }) async { + final root = await getRootNode(mnemonic: mnemonic); + final node = root.derivePath(kPaynymDerivePath).derive(0); + return node.privateKey!; + } + + Future<Uint8List> deriveReceivingPrivateKey({ + required List<String> mnemonic, + required int index, + }) async { + final root = await getRootNode(mnemonic: mnemonic); + final node = root.derivePath(kPaynymDerivePath).derive(index); + return node.privateKey!; + } + + /// fetch or generate this wallet's bip47 payment code + Future<PaymentCode> getPaymentCode( + DerivePathType derivePathType, + ) async { + final address = await getMyNotificationAddress(derivePathType); + final pCodeString = await paymentCodeStringByKey(address.otherData!); + final paymentCode = PaymentCode.fromPaymentCode( + pCodeString!, + _network, + ); + return paymentCode; + } + + Future<Uint8List> signWithNotificationKey(Uint8List data) async { + final privateKey = + await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); + final pair = btc_dart.ECPair.fromPrivateKey(privateKey, network: _network); + final signed = pair.sign(SHA256Digest().process(data)); + return signed; + } + + Future<String> signStringWithNotificationKey(String data) async { + final bytes = + await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); + return Format.uint8listToString(bytes); + } + + Future<Map<String, dynamic>> preparePaymentCodeSend( + {required PaymentCode paymentCode, + required int satoshiAmount, + Map<String, dynamic>? args}) async { + if (!(await hasConnected(paymentCode.notificationAddressP2PKH()))) { + throw PaynymSendException( + "No notification transaction sent to $paymentCode"); + } else { + final myPrivateKey = + await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); + final sendToAddress = await nextUnusedSendAddressFrom( + pCode: paymentCode, + privateKey: myPrivateKey, + ); + + return _prepareSend( + address: sendToAddress.value, + satoshiAmount: satoshiAmount, + args: args, + ); + } + } + + /// get the next unused address to send to given the receiver's payment code + /// and your own private key + Future<Address> nextUnusedSendAddressFrom({ + required PaymentCode pCode, + required Uint8List privateKey, + int startIndex = 0, + }) async { + // https://en.bitcoin.it/wiki/BIP_0047#Path_levels + const maxCount = 2147483647; + + for (int i = startIndex; i < maxCount; i++) { + final keys = await lookupKey(pCode.toString()); + final address = await _db + .getAddresses(_walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymSend) + .and() + .anyOf<String, Address>(keys, (q, String e) => q.otherDataEqualTo(e)) + .and() + .derivationIndexEqualTo(i) + .findFirst(); + + if (address != null) { + final count = await _getTxCount(address: address.value); + // return address if unused, otherwise continue to next index + if (count == 0) { + return address; + } + } else { + final pair = PaymentAddress.initWithPrivateKey( + privateKey, + pCode, + i, // index to use + ).getSendAddressKeyPair(); + + // add address to local db + final address = await generatePaynymSendAddressFromKeyPair( + pair: pair, + derivationIndex: i, + derivePathType: DerivePathType.bip44, + toPaymentCode: pCode, + ); + + final storedAddress = await _db.getAddress(_walletId, address.value); + if (storedAddress == null) { + await _db.putAddress(address); + } else { + await _db.updateAddress(storedAddress, address); + } + final count = await _getTxCount(address: address.value); + // return address if unused, otherwise continue to next index + if (count == 0) { + return address; + } + } + } + + throw PaynymSendException("Exhausted unused send addresses!"); + } + + Future<Map<String, dynamic>> prepareNotificationTx({ + required int selectedTxFeeRate, + required String targetPaymentCodeString, + int additionalOutputs = 0, + List<UTXO>? utxos, + }) async { + final amountToSend = _dustLimitP2PKH; + final List<UTXO> availableOutputs = + utxos ?? await _db.getUTXOs(_walletId).findAll(); + final List<UTXO> spendableOutputs = []; + int spendableSatoshiValue = 0; + + // Build list of spendable outputs and totaling their satoshi amount + for (var i = 0; i < availableOutputs.length; i++) { + if (availableOutputs[i].isBlocked == false && + availableOutputs[i] + .isConfirmed(await _getChainHeight(), _minConfirms) == + true) { + spendableOutputs.add(availableOutputs[i]); + spendableSatoshiValue += availableOutputs[i].value; + } + } + + if (spendableSatoshiValue < amountToSend) { + // insufficient balance + throw InsufficientBalanceException( + "Spendable balance is less than the minimum required for a notification transaction."); + } else if (spendableSatoshiValue == amountToSend) { + // insufficient balance due to missing amount to cover fee + throw InsufficientBalanceException( + "Remaining balance does not cover the network fee."); + } + + // sort spendable by age (oldest first) + spendableOutputs.sort((a, b) => b.blockTime!.compareTo(a.blockTime!)); + + int satoshisBeingUsed = 0; + int outputsBeingUsed = 0; + List<UTXO> utxoObjectsToUse = []; + + for (int i = 0; + satoshisBeingUsed < amountToSend && i < spendableOutputs.length; + i++) { + utxoObjectsToUse.add(spendableOutputs[i]); + satoshisBeingUsed += spendableOutputs[i].value; + outputsBeingUsed += 1; + } + + // add additional outputs if required + for (int i = 0; + i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; + i++) { + utxoObjectsToUse.add(spendableOutputs[outputsBeingUsed]); + satoshisBeingUsed += spendableOutputs[outputsBeingUsed].value; + outputsBeingUsed += 1; + } + + // gather required signing data + final utxoSigningData = await _fetchBuildTxData(utxoObjectsToUse); + + final int vSizeForNoChange = (await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: 0)) + .item2; + + final int vSizeForWithChange = (await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: satoshisBeingUsed - amountToSend)) + .item2; + + // Assume 2 outputs, for recipient and payment code script + int feeForNoChange = _estimateTxFee( + vSize: vSizeForNoChange, + feeRatePerKB: selectedTxFeeRate, + ); + + // Assume 3 outputs, for recipient, payment code script, and change + int feeForWithChange = _estimateTxFee( + vSize: vSizeForWithChange, + feeRatePerKB: selectedTxFeeRate, + ); + + if (_coin == Coin.dogecoin || _coin == Coin.dogecoinTestNet) { + if (feeForNoChange < vSizeForNoChange * 1000) { + feeForNoChange = vSizeForNoChange * 1000; + } + if (feeForWithChange < vSizeForWithChange * 1000) { + feeForWithChange = vSizeForWithChange * 1000; + } + } + + if (satoshisBeingUsed - amountToSend > feeForNoChange + _dustLimitP2PKH) { + // try to add change output due to "left over" amount being greater than + // the estimated fee + the dust limit + int changeAmount = satoshisBeingUsed - amountToSend - feeForWithChange; + + // check estimates are correct and build notification tx + if (changeAmount >= _dustLimitP2PKH && + satoshisBeingUsed - amountToSend - changeAmount == feeForWithChange) { + var txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: changeAmount, + ); + + int feeBeingPaid = satoshisBeingUsed - amountToSend - changeAmount; + + // make sure minimum fee is accurate if that is being used + if (txn.item2 - feeBeingPaid == 1) { + changeAmount -= 1; + feeBeingPaid += 1; + txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: changeAmount, + ); + } + + Map<String, dynamic> transactionObject = { + "hex": txn.item1, + "recipientPaynym": targetPaymentCodeString, + "amount": amountToSend, + "fee": feeBeingPaid, + "vSize": txn.item2, + }; + return transactionObject; + } else { + // something broke during fee estimation or the change amount is smaller + // than the dust limit. Try without change + final txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: 0, + ); + + int feeBeingPaid = satoshisBeingUsed - amountToSend; + + Map<String, dynamic> transactionObject = { + "hex": txn.item1, + "recipientPaynym": targetPaymentCodeString, + "amount": amountToSend, + "fee": feeBeingPaid, + "vSize": txn.item2, + }; + return transactionObject; + } + } else if (satoshisBeingUsed - amountToSend >= feeForNoChange) { + // since we already checked if we need to add a change output we can just + // build without change here + final txn = await _createNotificationTx( + targetPaymentCodeString: targetPaymentCodeString, + utxosToUse: utxoObjectsToUse, + utxoSigningData: utxoSigningData, + change: 0, + ); + + int feeBeingPaid = satoshisBeingUsed - amountToSend; + + Map<String, dynamic> transactionObject = { + "hex": txn.item1, + "recipientPaynym": targetPaymentCodeString, + "amount": amountToSend, + "fee": feeBeingPaid, + "vSize": txn.item2, + }; + return transactionObject; + } else { + // if we get here we do not have enough funds to cover the tx total so we + // check if we have any more available outputs and try again + if (spendableOutputs.length > outputsBeingUsed) { + return prepareNotificationTx( + selectedTxFeeRate: selectedTxFeeRate, + targetPaymentCodeString: targetPaymentCodeString, + additionalOutputs: additionalOutputs + 1, + ); + } else { + throw InsufficientBalanceException( + "Remaining balance does not cover the network fee."); + } + } + } + + // return tuple with string value equal to the raw tx hex and the int value + // equal to its vSize + Future<Tuple2<String, int>> _createNotificationTx({ + required String targetPaymentCodeString, + required List<UTXO> utxosToUse, + required Map<String, dynamic> utxoSigningData, + required int change, + }) async { + final targetPaymentCode = + PaymentCode.fromPaymentCode(targetPaymentCodeString, _network); + final myCode = await getPaymentCode(DerivePathType.bip44); + + final utxo = utxosToUse.first; + final txPoint = utxo.txid.fromHex.toList(); + final txPointIndex = utxo.vout; + + final rev = Uint8List(txPoint.length + 4); + Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); + final buffer = rev.buffer.asByteData(); + buffer.setUint32(txPoint.length, txPointIndex, Endian.little); + + final myKeyPair = utxoSigningData[utxo.txid]["keyPair"] as btc_dart.ECPair; + + final S = SecretPoint( + myKeyPair.privateKey!, + targetPaymentCode.notificationPublicKey(), + ); + + final blindingMask = PaymentCode.getMask(S.ecdhSecret(), rev); + + final blindedPaymentCode = PaymentCode.blind( + myCode.getPayload(), + blindingMask, + ); + + final opReturnScript = bscript.compile([ + (op.OPS["OP_RETURN"] as int), + blindedPaymentCode, + ]); + + // build a notification tx + final txb = btc_dart.TransactionBuilder(network: _network); + txb.setVersion(1); + + txb.addInput( + utxo.txid, + txPointIndex, + null, + utxoSigningData[utxo.txid]["output"] as Uint8List, + ); + + // todo: modify address once segwit support is in our bip47 + txb.addOutput( + targetPaymentCode.notificationAddressP2PKH(), _dustLimitP2PKH); + txb.addOutput(opReturnScript, 0); + + // TODO: add possible change output and mark output as dangerous + if (change > 0) { + // generate new change address if current change address has been used + await _checkChangeAddressForTransactions(); + final String changeAddress = await _getCurrentChangeAddress(); + txb.addOutput(changeAddress, change); + } + + txb.sign( + vin: 0, + keyPair: myKeyPair, + witnessValue: utxo.value, + witnessScript: utxoSigningData[utxo.txid]["redeemScript"] as Uint8List?, + ); + + // sign rest of possible inputs + for (var i = 1; i < utxosToUse.length; i++) { + final txid = utxosToUse[i].txid; + txb.sign( + vin: i, + keyPair: utxoSigningData[txid]["keyPair"] as btc_dart.ECPair, + witnessValue: utxosToUse[i].value, + witnessScript: utxoSigningData[utxo.txid]["redeemScript"] as Uint8List?, + ); + } + + final builtTx = txb.build(); + + return Tuple2(builtTx.toHex(), builtTx.virtualSize()); + } + + Future<String> broadcastNotificationTx( + {required Map<String, dynamic> preparedTx}) async { + try { + Logging.instance.log("confirmNotificationTx txData: $preparedTx", + level: LogLevel.Info); + final txHash = await _electrumXClient.broadcastTransaction( + rawTx: preparedTx["hex"] as String); + Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info); + + // TODO: only refresh transaction data + try { + await _refresh(); + } catch (e) { + Logging.instance.log( + "refresh() failed in confirmNotificationTx ($_walletName::$_walletId): $e", + level: LogLevel.Error, + ); + } + + return txHash; + } catch (e, s) { + Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s", + level: LogLevel.Error); + rethrow; + } + } + + // TODO optimize + Future<bool> hasConnected(String paymentCodeString) async { + final myNotificationAddress = + await getMyNotificationAddress(DerivePathTypeExt.primaryFor(_coin)); + + final txns = await _db + .getTransactions(_walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .findAll(); + + for (final tx in txns) { + // quick check that may cause problems? + if (tx.address.value?.value == myNotificationAddress.value) { + return true; + } + + final unBlindedPaymentCode = await unBlindedPaymentCodeFromTransaction( + transaction: tx, + myNotificationAddress: myNotificationAddress, + ); + + if (paymentCodeString == unBlindedPaymentCode.toString()) { + return true; + } + + if (tx.address.value?.otherData != null) { + final code = await paymentCodeStringByKey(tx.address.value!.otherData!); + if (code == paymentCodeString) { + return true; + } + } + } + + // otherwise return no + return false; + } + + Future<PaymentCode?> unBlindedPaymentCodeFromTransaction({ + required Transaction transaction, + required Address myNotificationAddress, + }) async { + if (transaction.address.value != null && + transaction.address.value!.value != myNotificationAddress.value) { + return null; + } + + try { + final blindedCodeBytes = + Bip47Utils.getBlindedPaymentCodeBytesFrom(transaction); + + // transaction does not contain a payment code + if (blindedCodeBytes == null) { + return null; + } + + final designatedInput = transaction.inputs.first; + + final txPoint = designatedInput.txid.fromHex.toList(); + final txPointIndex = designatedInput.vout; + + final rev = Uint8List(txPoint.length + 4); + Util.copyBytes(Uint8List.fromList(txPoint), 0, rev, 0, txPoint.length); + final buffer = rev.buffer.asByteData(); + buffer.setUint32(txPoint.length, txPointIndex, Endian.little); + + final pubKey = designatedInput.scriptSigAsm!.split(" ")[1].fromHex; + + final myPrivateKey = + await deriveNotificationPrivateKey(mnemonic: await _getMnemonic()); + + final S = SecretPoint(myPrivateKey, pubKey); + + final mask = PaymentCode.getMask(S.ecdhSecret(), rev); + + final unBlindedPayload = PaymentCode.blind(blindedCodeBytes, mask); + + final unBlindedPaymentCode = + PaymentCode.initFromPayload(unBlindedPayload); + + return unBlindedPaymentCode; + } catch (e) { + Logging.instance.log( + "unBlindedPaymentCodeFromTransaction() failed: $e", + level: LogLevel.Warning, + ); + return null; + } + } + + Future<List<PaymentCode>> + getAllPaymentCodesFromNotificationTransactions() async { + final myAddress = + await getMyNotificationAddress(DerivePathTypeExt.primaryFor(_coin)); + final txns = await _db + .getTransactions(_walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .findAll(); + + List<PaymentCode> codes = []; + + for (final tx in txns) { + // tx is sent so we can check the address's otherData for the code String + if (tx.type == TransactionType.outgoing && + tx.address.value?.otherData != null) { + final codeString = + await paymentCodeStringByKey(tx.address.value!.otherData!); + if (codeString != null && + codes.where((e) => e.toString() == codeString).isEmpty) { + codes.add(PaymentCode.fromPaymentCode(codeString, _network)); + } + } else { + // otherwise we need to un blind the code + final unBlinded = await unBlindedPaymentCodeFromTransaction( + transaction: tx, + myNotificationAddress: myAddress, + ); + if (unBlinded != null && + codes.where((e) => e.toString() == unBlinded.toString()).isEmpty) { + codes.add(unBlinded); + } + } + } + + return codes; + } + + Future<void> checkForNotificationTransactionsTo( + Set<String> otherCodeStrings) async { + final sentNotificationTransactions = await _db + .getTransactions(_walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .and() + .typeEqualTo(TransactionType.outgoing) + .findAll(); + + final List<PaymentCode> codes = []; + for (final codeString in otherCodeStrings) { + codes.add(PaymentCode.fromPaymentCode(codeString, _network)); + } + + for (final tx in sentNotificationTransactions) { + if (tx.address.value != null && tx.address.value!.otherData == null) { + final oldAddress = + await _db.getAddress(_walletId, tx.address.value!.value); + for (final code in codes) { + final notificationAddress = code.notificationAddressP2PKH(); + if (notificationAddress == oldAddress!.value) { + final address = Address( + walletId: _walletId, + value: notificationAddress, + publicKey: [], + derivationIndex: 0, + type: oldAddress.type, + subType: AddressSubType.paynymNotification, + otherData: await storeCode(code.toString()), + ); + await _db.updateAddress(oldAddress, address); + } + } + } + } + } + + Future<void> restoreAllHistory({ + required int maxUnusedAddressGap, + required int maxNumberOfIndexesToCheck, + required Set<String> paymentCodeStrings, + }) async { + final codes = await getAllPaymentCodesFromNotificationTransactions(); + final List<PaymentCode> extraCodes = []; + for (final codeString in paymentCodeStrings) { + if (codes.where((e) => e.toString() == codeString).isEmpty) { + final extraCode = PaymentCode.fromPaymentCode(codeString, _network); + if (extraCode.isValid()) { + extraCodes.add(extraCode); + } + } + } + + codes.addAll(extraCodes); + + final List<Future<void>> futures = []; + for (final code in codes) { + futures.add( + restoreHistoryWith( + code, + maxUnusedAddressGap, + maxNumberOfIndexesToCheck, + ), + ); + } + + await Future.wait(futures); + } + + Future<void> restoreHistoryWith( + PaymentCode other, + int maxUnusedAddressGap, + int maxNumberOfIndexesToCheck, + ) async { + // https://en.bitcoin.it/wiki/BIP_0047#Path_levels + const maxCount = 2147483647; + assert(maxNumberOfIndexesToCheck < maxCount); + + final mnemonic = await _getMnemonic(); + + final mySendPrivateKey = + await deriveNotificationPrivateKey(mnemonic: mnemonic); + final receivingNode = + (await getRootNode(mnemonic: mnemonic)).derivePath(kPaynymDerivePath); + + List<Address> addresses = []; + int receivingGapCounter = 0; + int outgoingGapCounter = 0; + + for (int i = 0; + i < maxNumberOfIndexesToCheck && + (receivingGapCounter < maxUnusedAddressGap || + outgoingGapCounter < maxUnusedAddressGap); + i++) { + if (outgoingGapCounter < maxUnusedAddressGap) { + final paymentAddressSending = PaymentAddress.initWithPrivateKey( + mySendPrivateKey, + other, + i, // index to use + ); + final pair = paymentAddressSending.getSendAddressKeyPair(); + final address = await generatePaynymSendAddressFromKeyPair( + pair: pair, + derivationIndex: i, + derivePathType: DerivePathType.bip44, + toPaymentCode: other, + ); + addresses.add(address); + + final count = await _getTxCount(address: address.value); + + if (count > 0) { + outgoingGapCounter = 0; + } else { + outgoingGapCounter++; + } + } + + if (receivingGapCounter < maxUnusedAddressGap) { + final myReceivingPrivateKey = receivingNode.derive(i).privateKey!; + final paymentAddressReceiving = PaymentAddress.initWithPrivateKey( + myReceivingPrivateKey, + other, + 0, + ); + final pair = paymentAddressReceiving.getReceiveAddressKeyPair(); + final address = await generatePaynymReceivingAddressFromKeyPair( + pair: pair, + derivationIndex: i, + derivePathType: DerivePathType.bip44, + fromPaymentCode: other, + ); + addresses.add(address); + + final count = await _getTxCount(address: address.value); + + if (count > 0) { + receivingGapCounter = 0; + } else { + receivingGapCounter++; + } + } + } + await _db.updateOrPutAddresses(addresses); + } + + Future<Address> generatePaynymSendAddressFromKeyPair({ + required btc_dart.ECPair pair, + required int derivationIndex, + required DerivePathType derivePathType, + required PaymentCode toPaymentCode, + }) async { + final data = btc_dart.PaymentData(pubkey: pair.publicKey); + + String addressString; + switch (derivePathType) { + case DerivePathType.bip44: + addressString = + btc_dart.P2PKH(data: data, network: _network).data.address!; + break; + + // The following doesn't apply currently + // case DerivePathType.bip49: + // addressString = btc_dart + // .P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart + // .P2WPKH( + // data: data, + // network: network, + // ) + // .data), + // network: network, + // ) + // .data + // .address!; + // break; + // + // case DerivePathType.bip84: + // addressString = btc_dart + // .P2WPKH( + // network: network, + // data: data, + // ) + // .data + // .address!; + // break; + default: + throw UnimplementedError("segwit paynyms not implemented yet"); + } + + final address = Address( + walletId: _walletId, + value: addressString, + publicKey: pair.publicKey, + derivationIndex: derivationIndex, + type: AddressType.nonWallet, + subType: AddressSubType.paynymSend, + otherData: await storeCode(toPaymentCode.toString()), + ); + + return address; + } + + Future<Address> generatePaynymReceivingAddressFromKeyPair({ + required btc_dart.ECPair pair, + required int derivationIndex, + required DerivePathType derivePathType, + required PaymentCode fromPaymentCode, + }) async { + final data = btc_dart.PaymentData(pubkey: pair.publicKey); + + String addressString; + AddressType addrType; + switch (derivePathType) { + case DerivePathType.bip44: + addressString = btc_dart + .P2PKH( + data: data, + network: _network, + ) + .data + .address!; + addrType = AddressType.p2pkh; + break; + + // The following doesn't apply currently + // case DerivePathType.bip49: + // addressString = btc_dart + // .P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart + // .P2WPKH( + // data: data, + // network: network, + // ) + // .data), + // network: network, + // ) + // .data + // .address!; + // addrType = AddressType.p2sh; + // break; + // + // case DerivePathType.bip84: + // addressString = btc_dart + // .P2WPKH( + // network: network, + // data: data, + // ) + // .data + // .address!; + // addrType = AddressType.p2wpkh; + // break; + default: + throw UnimplementedError("segwit paynyms not implemented yet"); + } + + final address = Address( + walletId: _walletId, + value: addressString, + publicKey: pair.publicKey, + derivationIndex: derivationIndex, + type: addrType, + subType: AddressSubType.paynymReceive, + otherData: await storeCode(fromPaymentCode.toString()), + ); + + final myCode = await getPaymentCode(DerivePathType.bip44); + + final bip32NetworkType = bip32.NetworkType( + wif: _network.wif, + bip32: bip32.Bip32Type( + public: _network.bip32.public, + private: _network.bip32.private, + ), + ); + + final bip32.BIP32 node = bip32.BIP32.fromPrivateKey( + pair.privateKey!, + myCode.getChain(), + bip32NetworkType, + ); + + await _addDerivation( + chain: 0, + address: address.value, + derivePathType: DerivePathType.bip44, + pubKey: Format.uint8listToString(node.publicKey), + wif: node.toWIF(), + ); + + return address; + } + + Future<Address> getMyNotificationAddress( + DerivePathType derivePathType, + ) async { + // TODO: fix when segwit is here + derivePathType = DerivePathType.bip44; + + AddressType type; + switch (derivePathType) { + case DerivePathType.bip44: + type = AddressType.p2pkh; + break; + case DerivePathType.bip49: + type = AddressType.p2sh; + break; + case DerivePathType.bip84: + type = AddressType.p2wpkh; + break; + default: + throw Exception("DerivePathType $derivePathType not supported"); + } + + final storedAddress = await _db + .getAddresses(_walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymNotification) + .and() + .typeEqualTo(type) + .and() + .not() + .typeEqualTo(AddressType.nonWallet) + .findFirst(); + + if (storedAddress != null) { + return storedAddress; + } else { + final root = await getRootNode(mnemonic: await _getMnemonic()); + final node = root.derivePath(kPaynymDerivePath); + final paymentCode = PaymentCode.initFromPubKey( + node.publicKey, + node.chainCode, + _network, + ); + + String addressString; + final data = + btc_dart.PaymentData(pubkey: paymentCode.notificationPublicKey()); + switch (derivePathType) { + case DerivePathType.bip44: + addressString = btc_dart + .P2PKH( + data: data, + network: _network, + ) + .data + .address!; + break; + // case DerivePathType.bip49: + // addressString = btc_dart + // .P2SH( + // data: btc_dart.PaymentData( + // redeem: btc_dart + // .P2WPKH( + // data: data, + // network: network, + // ) + // .data), + // network: network, + // ) + // .data + // .address!; + // break; + // case DerivePathType.bip84: + // addressString = btc_dart + // .P2WPKH( + // network: network, + // data: data, + // ) + // .data + // .address!; + // break; + default: + throw UnimplementedError("segwit paynyms not implemented yet"); + } + + final address = Address( + walletId: _walletId, + value: addressString, + publicKey: paymentCode.getPubKey(), + derivationIndex: 0, + type: type, + subType: AddressSubType.paynymNotification, + otherData: await storeCode(paymentCode.toString()), + ); + + await _addDerivation( + chain: 0, + address: address.value, + derivePathType: DerivePathType.bip44, + pubKey: Format.uint8listToString(node.publicKey), + wif: node.toWIF(), + ); + + await _db.putAddress(address); + return address; + } + } + + /// look up a key that corresponds to a payment code string + Future<List<String>> lookupKey(String paymentCodeString) async { + final keys = + (await _secureStorage.keys).where((e) => e.startsWith(kPCodeKeyPrefix)); + final List<String> result = []; + for (final key in keys) { + final value = await _secureStorage.read(key: key); + if (value == paymentCodeString) { + result.add(key); + } + } + return result; + } + + /// fetch a payment code string + Future<String?> paymentCodeStringByKey(String key) async { + final value = await _secureStorage.read(key: key); + return value; + } + + /// store payment code string and return the generated key used + Future<String> storeCode(String paymentCodeString) async { + final key = _generateKey(); + await _secureStorage.write(key: key, value: paymentCodeString); + return key; + } + + /// generate a new payment code string storage key + String _generateKey() { + final bytes = _randomBytes(24); + return "$kPCodeKeyPrefix${bytes.toHex}"; + } + + // https://github.com/AaronFeickert/stack_wallet_backup/blob/master/lib/secure_storage.dart#L307-L311 + /// Generate cryptographically-secure random bytes + Uint8List _randomBytes(int n) { + final Random rng = Random.secure(); + return Uint8List.fromList( + List<int>.generate(n, (_) => rng.nextInt(0xFF + 1))); + } +} + +const String kPCodeKeyPrefix = "pCode_key_"; diff --git a/lib/services/notifications_service.dart b/lib/services/notifications_service.dart index 2368adeab..2bfe0e12f 100644 --- a/lib/services/notifications_service.dart +++ b/lib/services/notifications_service.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; +import 'package:stackwallet/exceptions/electrumx/no_such_transaction.dart'; import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/notification_model.dart'; @@ -169,12 +170,14 @@ class NotificationsService extends ChangeNotifier { } // replaces the current notification with the updated one - add(updatedNotification, true); + await add(updatedNotification, true); } } else { // TODO: check non electrumx coins } } + } on NoSuchTransactionException catch (e, s) { + await _deleteWatchedTxNotification(notification); } catch (e, s) { Logging.instance.log("$e $s", level: LogLevel.Error); } diff --git a/lib/services/transaction_notification_tracker.dart b/lib/services/transaction_notification_tracker.dart index 696465e85..6a2cce2c7 100644 --- a/lib/services/transaction_notification_tracker.dart +++ b/lib/services/transaction_notification_tracker.dart @@ -54,4 +54,25 @@ class TransactionNotificationTracker { key: "notifiedConfirmedTransactions", value: notifiedConfirmedTransactions); } + + Future<void> deleteTransaction(String txid) async { + final notifiedPendingTransactions = DB.instance.get<dynamic>( + boxName: walletId, key: "notifiedPendingTransactions") as Map? ?? + {}; + final notifiedConfirmedTransactions = DB.instance.get<dynamic>( + boxName: walletId, key: "notifiedConfirmedTransactions") as Map? ?? + {}; + + notifiedPendingTransactions.remove(txid); + notifiedConfirmedTransactions.remove(txid); + + await DB.instance.put<dynamic>( + boxName: walletId, + key: "notifiedConfirmedTransactions", + value: notifiedConfirmedTransactions); + await DB.instance.put<dynamic>( + boxName: walletId, + key: "notifiedPendingTransactions", + value: notifiedPendingTransactions); + } } diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart index 5a0427782..5bb7c3edb 100644 --- a/lib/utilities/assets.dart +++ b/lib/utilities/assets.dart @@ -194,6 +194,8 @@ class _SVG { String get exitDesktop => "assets/svg/exit-desktop.svg"; String get keys => "assets/svg/keys.svg"; String get arrowDown => "assets/svg/arrow-down.svg"; + String get robotHead => "assets/svg/robot-head.svg"; + String get whirlPool => "assets/svg/whirlpool.svg"; String get ellipse1 => "assets/svg/Ellipse-43.svg"; String get ellipse2 => "assets/svg/Ellipse-42.svg"; @@ -262,6 +264,7 @@ class _PNG { const _PNG(); String get stack => "assets/images/stack.png"; + String get unclaimedPaynym => "assets/images/unclaimed.png"; String get splash => "assets/images/splash.png"; String get monero => "assets/images/monero.png"; diff --git a/lib/utilities/bip32_utils.dart b/lib/utilities/bip32_utils.dart new file mode 100644 index 000000000..50549938f --- /dev/null +++ b/lib/utilities/bip32_utils.dart @@ -0,0 +1,32 @@ +import 'package:bip32/bip32.dart' as bip32; +import 'package:bip39/bip39.dart' as bip39; +import 'package:bitcoindart/bitcoindart.dart'; +import 'package:flutter/foundation.dart'; +import 'package:tuple/tuple.dart'; + +abstract class Bip32Utils { + static bip32.BIP32 getBip32RootSync(String mnemonic, NetworkType network) { + final seed = bip39.mnemonicToSeed(mnemonic); + final networkType = bip32.NetworkType( + wif: network.wif, + bip32: bip32.Bip32Type( + public: network.bip32.public, + private: network.bip32.private, + ), + ); + + final root = bip32.BIP32.fromSeed(seed, networkType); + return root; + } + + static Future<bip32.BIP32> getBip32Root( + String mnemonic, NetworkType network) async { + final root = await compute(_getBip32RootWrapper, Tuple2(mnemonic, network)); + return root; + } + + /// wrapper for compute() + static bip32.BIP32 _getBip32RootWrapper(Tuple2<String, NetworkType> args) { + return getBip32RootSync(args.item1, args.item2); + } +} diff --git a/lib/utilities/bip47_utils.dart b/lib/utilities/bip47_utils.dart new file mode 100644 index 000000000..6433f4e1d --- /dev/null +++ b/lib/utilities/bip47_utils.dart @@ -0,0 +1,37 @@ +import 'dart:typed_data'; + +import 'package:bip47/src/util.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/output.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; + +abstract class Bip47Utils { + /// looks at tx outputs and returns a blinded payment code if found + static Uint8List? getBlindedPaymentCodeBytesFrom(Transaction transaction) { + for (int i = 0; i < transaction.outputs.length; i++) { + final bytes = getBlindedPaymentCodeBytesFromOutput( + transaction.outputs.elementAt(i)); + if (bytes != null) { + return bytes; + } + } + + return null; + } + + static Uint8List? getBlindedPaymentCodeBytesFromOutput(Output output) { + Uint8List? blindedCodeBytes; + + List<String>? scriptChunks = output.scriptPubKeyAsm?.split(" "); + if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { + final blindedPaymentCode = scriptChunks![1]; + final bytes = blindedPaymentCode.fromHex; + + // https://en.bitcoin.it/wiki/BIP_0047#Sending + if (bytes.length == 80 && bytes.first == 1) { + blindedCodeBytes = bytes; + } + } + + return blindedCodeBytes; + } +} diff --git a/lib/utilities/desktop_password_service.dart b/lib/utilities/desktop_password_service.dart index 9ef83932b..6263eb33b 100644 --- a/lib/utilities/desktop_password_service.dart +++ b/lib/utilities/desktop_password_service.dart @@ -4,9 +4,12 @@ import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/utilities/logger.dart'; const String _kKeyBlobKey = "swbKeyBlobKeyStringID"; +const String _kKeyBlobVersionKey = "swbKeyBlobVersionKeyStringID"; + +const int kLatestBlobVersion = 2; String _getMessageFromException(Object exception) { - if (exception is IncorrectPassphrase) { + if (exception is IncorrectPassphraseOrVersion) { return exception.errMsg(); } if (exception is BadDecryption) { @@ -18,6 +21,9 @@ String _getMessageFromException(Object exception) { if (exception is EncodingError) { return exception.errMsg(); } + if (exception is VersionError) { + return exception.errMsg(); + } return exception.toString(); } @@ -41,7 +47,10 @@ class DPS { } try { - _handler = await StorageCryptoHandler.fromNewPassphrase(passphrase); + _handler = await StorageCryptoHandler.fromNewPassphrase( + passphrase, + kLatestBlobVersion, + ); final box = await Hive.openBox<String>(DB.boxNameDesktopData); await DB.instance.put<String>( @@ -49,6 +58,7 @@ class DPS { key: _kKeyBlobKey, value: await _handler!.getKeyBlob(), ); + await _updateStoredKeyBlobVersion(kLatestBlobVersion); await box.close(); } catch (e, s) { Logging.instance.log( @@ -78,7 +88,24 @@ class DPS { } try { - _handler = await StorageCryptoHandler.fromExisting(passphrase, keyBlob); + final blobVersion = await _getStoredKeyBlobVersion(); + _handler = await StorageCryptoHandler.fromExisting( + passphrase, + keyBlob, + blobVersion, + ); + if (blobVersion < kLatestBlobVersion) { + // update blob + await _handler!.resetPassphrase(passphrase, kLatestBlobVersion); + final box = await Hive.openBox<String>(DB.boxNameDesktopData); + await DB.instance.put<String>( + boxName: DB.boxNameDesktopData, + key: _kKeyBlobKey, + value: await _handler!.getKeyBlob(), + ); + await _updateStoredKeyBlobVersion(kLatestBlobVersion); + await box.close(); + } } catch (e, s) { Logging.instance.log( "${_getMessageFromException(e)}\n$s", @@ -102,7 +129,8 @@ class DPS { } try { - await StorageCryptoHandler.fromExisting(passphrase, keyBlob); + final blobVersion = await _getStoredKeyBlobVersion(); + await StorageCryptoHandler.fromExisting(passphrase, keyBlob, blobVersion); // existing passphrase matches key blob return true; } catch (e, s) { @@ -135,8 +163,10 @@ class DPS { return false; } + final blobVersion = await _getStoredKeyBlobVersion(); + try { - await _handler!.resetPassphrase(passphraseNew); + await _handler!.resetPassphrase(passphraseNew, blobVersion); final box = await Hive.openBox<String>(DB.boxNameDesktopData); await DB.instance.put<String>( @@ -144,6 +174,7 @@ class DPS { key: _kKeyBlobKey, value: await _handler!.getKeyBlob(), ); + await _updateStoredKeyBlobVersion(blobVersion); await box.close(); // successfully updated passphrase @@ -164,4 +195,22 @@ class DPS { ); return keyBlob != null; } + + Future<int> _getStoredKeyBlobVersion() async { + final box = await Hive.openBox<String>(DB.boxNameDesktopData); + final keyBlobVersionString = DB.instance.get<String>( + boxName: DB.boxNameDesktopData, + key: _kKeyBlobVersionKey, + ); + await box.close(); + return int.tryParse(keyBlobVersionString ?? "1") ?? 1; + } + + Future<void> _updateStoredKeyBlobVersion(int version) async { + await DB.instance.put<String>( + boxName: DB.boxNameDesktopData, + key: _kKeyBlobVersionKey, + value: version.toString(), + ); + } } diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart index 5120cb52f..0484fe0e8 100644 --- a/lib/utilities/enums/coin_enum.dart +++ b/lib/utilities/enums/coin_enum.dart @@ -171,30 +171,6 @@ extension CoinExt on Coin { } } - bool get hasPaynymSupport { - switch (this) { - case Coin.bitcoin: - case Coin.litecoin: - case Coin.bitcoincash: - case Coin.firo: - case Coin.namecoin: - case Coin.particl: - case Coin.bitcoinTestNet: - case Coin.litecoinTestNet: - case Coin.bitcoincashTestnet: - case Coin.firoTestNet: - case Coin.epicCash: - case Coin.monero: - case Coin.wownero: - return false; - - case Coin.dogecoin: - case Coin.dogecoinTestNet: - // return true; - return false; - } - } - bool get hasBuySupport { switch (this) { case Coin.bitcoin: diff --git a/lib/utilities/enums/derive_path_type_enum.dart b/lib/utilities/enums/derive_path_type_enum.dart new file mode 100644 index 000000000..53db94e96 --- /dev/null +++ b/lib/utilities/enums/derive_path_type_enum.dart @@ -0,0 +1,36 @@ +import 'package:stackwallet/utilities/enums/coin_enum.dart'; + +enum DerivePathType { + bip44, + bch44, + bip49, + bip84, +} + +extension DerivePathTypeExt on DerivePathType { + static DerivePathType primaryFor(Coin coin) { + switch (coin) { + case Coin.bitcoincash: + case Coin.bitcoincashTestnet: + case Coin.dogecoin: + case Coin.dogecoinTestNet: + case Coin.firo: + case Coin.firoTestNet: + return DerivePathType.bip44; + + case Coin.bitcoin: + case Coin.bitcoinTestNet: + case Coin.litecoin: + case Coin.litecoinTestNet: + case Coin.namecoin: + case Coin.particl: + return DerivePathType.bip84; + + case Coin.epicCash: + case Coin.monero: + case Coin.wownero: + throw UnsupportedError( + "$coin does not use bitcoin style derivation paths"); + } + } +} diff --git a/lib/utilities/featured_paynyms.dart b/lib/utilities/featured_paynyms.dart index 5abff9f2a..a04fa9a7d 100644 --- a/lib/utilities/featured_paynyms.dart +++ b/lib/utilities/featured_paynyms.dart @@ -1,12 +1,12 @@ abstract class FeaturedPaynyms { - // TODO: replace with actual values - static const String samouraiWalletDevFund = - "PM8TJYkuSdYXJnwDBq8ChfinfXv3srxhQrx3eoEwbSw51wMjdo9JJ2DsycwT3gt3zHQ7cV1grvabMmmf1Btj6fY7tgkgSz9B8MZuR3kjYfgMLMURJCXN"; + // TODO: replace with actual value + // static const String samouraiWalletDevFund = + // "PM8TJYkuSdYXJnwDBq8ChfinfXv3srxhQrx3eoEwbSw51wMjdo9JJ2DsycwT3gt3zHQ7cV1grvabMmmf1Btj6fY7tgkgSz9B8MZuR3kjYfgMLMURJCXN"; static const String stackWallet = - "PM8TJYkuSdYXJnwDBq8ChfinfXv3srxhQrx3eoEwbSw51wMjdo9JJ2DsycwT3gt3zHQ7cV1grvabMmmf1Btj6fY7tgkgSz9B8MZuR3kjYfgMLMURJCXN"; + "PM8TJdQcNk27JpxGRtNR7Hnh8VkJk4Nf17BthLx89fM3iX3UL2YshyaiTAvKgTCVvpgsAgY1DbojkAaUd3Rcn48NEn4uUBuqkaSddgKL8TPAAEQXNuE6"; static Map<String, String> get featured => { "Stack Wallet": stackWallet, - "Samourai Wallet Dev Fund": samouraiWalletDevFund, + // "Samourai Wallet Dev Fund": samouraiWalletDevFund, }; } diff --git a/lib/utilities/flutter_secure_storage_interface.dart b/lib/utilities/flutter_secure_storage_interface.dart index 539f17847..16fa98760 100644 --- a/lib/utilities/flutter_secure_storage_interface.dart +++ b/lib/utilities/flutter_secure_storage_interface.dart @@ -46,6 +46,8 @@ abstract class SecureStorageInterface { MacOsOptions? mOptions, WindowsOptions? wOptions, }); + + Future<List<String>> get keys; } class DesktopSecureStore { @@ -110,6 +112,10 @@ class DesktopSecureStore { await isar.encryptedStringValues.deleteByKey(key); }); } + + Future<List<String>> get keys async { + return await isar.encryptedStringValues.where().keyProperty().findAll(); + } } /// all *Options params ignored on desktop @@ -229,6 +235,15 @@ class SecureStorageWrapper implements SecureStorageInterface { ); } } + + @override + Future<List<String>> get keys async { + if (_isDesktop) { + return (_store as DesktopSecureStore).keys; + } else { + return (await (_store as FlutterSecureStorage).readAll()).keys.toList(); + } + } } // Mock class for testing purposes @@ -305,4 +320,7 @@ class FakeSecureStorage implements SecureStorageInterface { @override dynamic get store => throw UnimplementedError(); + + @override + Future<List<String>> get keys => Future(() => _store.keys.toList()); } diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart index 8b756e984..98878b6b6 100644 --- a/lib/utilities/text_styles.dart +++ b/lib/utilities/text_styles.dart @@ -13,31 +13,31 @@ class STextStyles { return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); case ThemeType.oceanBreeze: return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); case ThemeType.dark: return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); case ThemeType.oledBlack: return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); case ThemeType.fruitSorbet: return GoogleFonts.inter( color: _theme(context).textDark3, fontWeight: FontWeight.w500, - fontSize: 12, + fontSize: 14, ); } } @@ -932,6 +932,76 @@ class STextStyles { } } + static TextStyle w600_14(BuildContext context) { + switch (_theme(context).themeType) { + case ThemeType.light: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + case ThemeType.oceanBreeze: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + case ThemeType.dark: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + case ThemeType.oledBlack: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + case ThemeType.fruitSorbet: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w600, + fontSize: 14, + ); + } + } + + static TextStyle w500_14(BuildContext context) { + switch (_theme(context).themeType) { + case ThemeType.light: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + case ThemeType.oceanBreeze: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + case ThemeType.dark: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + case ThemeType.oledBlack: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + case ThemeType.fruitSorbet: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 14, + ); + } + } + static TextStyle w500_12(BuildContext context) { switch (_theme(context).themeType) { case ThemeType.light: @@ -967,6 +1037,41 @@ class STextStyles { } } + static TextStyle w500_10(BuildContext context) { + switch (_theme(context).themeType) { + case ThemeType.light: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + case ThemeType.oceanBreeze: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + case ThemeType.dark: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + case ThemeType.oledBlack: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + case ThemeType.fruitSorbet: + return GoogleFonts.inter( + color: _theme(context).textDark, + fontWeight: FontWeight.w500, + fontSize: 10, + ); + } + } + static TextStyle syncPercent(BuildContext context) { switch (_theme(context).themeType) { case ThemeType.light: @@ -1030,7 +1135,7 @@ class STextStyles { ); case ThemeType.fruitSorbet: return GoogleFonts.inter( - color: _theme(context).textDark, + color: _theme(context).bottomNavIconIcon, fontWeight: FontWeight.w500, fontSize: 12, ); diff --git a/lib/utilities/theme/fruit_sorbet_colors.dart b/lib/utilities/theme/fruit_sorbet_colors.dart index 6f0a81e82..3394b3a9c 100644 --- a/lib/utilities/theme/fruit_sorbet_colors.dart +++ b/lib/utilities/theme/fruit_sorbet_colors.dart @@ -327,7 +327,7 @@ class FruitSorbetColors extends StackColorTheme { @override Color get rateTypeToggleDesktopColorOn => const Color(0xFFFFD8CE); @override - Color get rateTypeToggleDesktopColorOff => buttonBackSecondary; + Color get rateTypeToggleDesktopColorOff => popupBG; @override BoxShadow get standardBoxShadow => BoxShadow( diff --git a/lib/utilities/theme/ocean_breeze_colors.dart b/lib/utilities/theme/ocean_breeze_colors.dart index 1ba64843d..f8bcaf0c1 100644 --- a/lib/utilities/theme/ocean_breeze_colors.dart +++ b/lib/utilities/theme/ocean_breeze_colors.dart @@ -94,7 +94,7 @@ class OceanBreezeColors extends StackColorTheme { @override Color get buttonTextPrimary => const Color(0xFFFFFFFF); @override - Color get buttonTextSecondary => const Color(0xFF232323); + Color get buttonTextSecondary => accentColorDark; @override Color get buttonTextPrimaryDisabled => const Color(0xFFFFFFFF); @override diff --git a/lib/utilities/util.dart b/lib/utilities/util.dart index 2940b6d40..6a31fae04 100644 --- a/lib/utilities/util.dart +++ b/lib/utilities/util.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/material.dart'; abstract class Util { @@ -22,6 +23,14 @@ abstract class Util { return Platform.isLinux || Platform.isMacOS || Platform.isWindows; } + static Future<bool> get isIPad async { + final deviceInfo = (await DeviceInfoPlugin().deviceInfo); + if (deviceInfo is IosDeviceInfo) { + return (deviceInfo).name?.toLowerCase().contains("ipad") == true; + } + return false; + } + static MaterialColor createMaterialColor(Color color) { List<double> strengths = <double>[.05]; final swatch = <int, Color>{}; diff --git a/lib/widgets/custom_buttons/blue_text_button.dart b/lib/widgets/custom_buttons/blue_text_button.dart index 7877ddcde..8be6bb937 100644 --- a/lib/widgets/custom_buttons/blue_text_button.dart +++ b/lib/widgets/custom_buttons/blue_text_button.dart @@ -1,17 +1,17 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:stackwallet/providers/ui/color_theme_provider.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; -class BlueTextButton extends ConsumerStatefulWidget { - const BlueTextButton({ +class _CustomTextButton extends StatefulWidget { + const _CustomTextButton({ Key? key, required this.text, + required this.enabledColor, + required this.disabledColor, this.onTap, this.enabled = true, this.textSize, @@ -21,12 +21,14 @@ class BlueTextButton extends ConsumerStatefulWidget { final VoidCallback? onTap; final bool enabled; final double? textSize; + final Color enabledColor; + final Color disabledColor; @override - ConsumerState<BlueTextButton> createState() => _BlueTextButtonState(); + State<_CustomTextButton> createState() => _CustomTextButtonState(); } -class _BlueTextButtonState extends ConsumerState<BlueTextButton> +class _CustomTextButtonState extends State<_CustomTextButton> with SingleTickerProviderStateMixin { AnimationController? controller; Animation<dynamic>? animation; @@ -37,18 +39,14 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton> @override void initState() { if (widget.enabled) { - color = ref.read(colorThemeProvider.state).state.buttonTextBorderless; + color = widget.enabledColor; controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 100), ); animation = ColorTween( - begin: ref.read(colorThemeProvider.state).state.buttonTextBorderless, - end: ref - .read(colorThemeProvider.state) - .state - .buttonTextBorderless - .withOpacity(0.4), + begin: widget.enabledColor, + end: widget.enabledColor.withOpacity(0.4), ).animate(controller!); animation!.addListener(() { @@ -57,7 +55,7 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton> }); }); } else { - color = ref.read(colorThemeProvider.state).state.textSubtitle1; + color = widget.disabledColor; } super.initState(); @@ -116,3 +114,32 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton> ); } } + +class CustomTextButton extends StatelessWidget { + const CustomTextButton({ + Key? key, + required this.text, + this.onTap, + this.enabled = true, + this.textSize, + }) : super(key: key); + + final String text; + final VoidCallback? onTap; + final bool enabled; + final double? textSize; + + @override + Widget build(BuildContext context) { + return _CustomTextButton( + key: UniqueKey(), + text: text, + enabledColor: + Theme.of(context).extension<StackColors>()!.buttonTextBorderless, + disabledColor: Theme.of(context).extension<StackColors>()!.textSubtitle1, + enabled: enabled, + textSize: textSize, + onTap: onTap, + ); + } +} diff --git a/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart b/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart index ea3771d95..e4235fef4 100644 --- a/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart +++ b/lib/widgets/custom_buttons/paynym_follow_toggle_button.dart @@ -9,9 +9,9 @@ import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart'; -import 'package:stackwallet/services/coins/coin_paynym_extension.dart'; -import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; @@ -58,16 +58,18 @@ class _PaynymFollowToggleButtonState ), ); - final wallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + + // get wallet to access paynym calls + final wallet = manager.wallet as PaynymWalletInterface; final followedAccount = await ref .read(paynymAPIProvider) .nym(widget.paymentCodeStringToFollow, true); - final myPCode = await wallet.getPaymentCode(); + final myPCode = + await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(manager.coin)); PaynymResponse<String> token = await ref.read(paynymAPIProvider).token(myPCode.toString()); @@ -158,16 +160,17 @@ class _PaynymFollowToggleButtonState ), ); - final wallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as DogecoinWallet; + final manager = + ref.read(walletsChangeNotifierProvider).getManager(widget.walletId); + + final wallet = manager.wallet as PaynymWalletInterface; final followedAccount = await ref .read(paynymAPIProvider) .nym(widget.paymentCodeStringToFollow, true); - final myPCode = await wallet.getPaymentCode(); + final myPCode = + await wallet.getPaymentCode(DerivePathTypeExt.primaryFor(manager.coin)); PaynymResponse<String> token = await ref.read(paynymAPIProvider).token(myPCode.toString()); @@ -269,8 +272,8 @@ class _PaynymFollowToggleButtonState switch (widget.style) { case PaynymFollowToggleButtonStyle.primary: return PrimaryButton( - width: isDesktop ? 120 : 84, - buttonHeight: isDesktop ? ButtonHeight.s : ButtonHeight.l, + width: isDesktop ? 120 : 100, + buttonHeight: isDesktop ? ButtonHeight.s : ButtonHeight.xl, label: isFollowing ? "Unfollow" : "Follow", onPressed: _onPressed, ); @@ -278,15 +281,15 @@ class _PaynymFollowToggleButtonState case PaynymFollowToggleButtonStyle.detailsPopup: return SecondaryButton( label: isFollowing ? "Unfollow" : "Follow", - buttonHeight: ButtonHeight.l, + buttonHeight: ButtonHeight.xl, + iconSpacing: 8, icon: SvgPicture.asset( isFollowing ? Assets.svg.userMinus : Assets.svg.userPlus, - width: 10, - height: 10, + width: 16, + height: 16, color: Theme.of(context).extension<StackColors>()!.buttonTextSecondary, ), - iconSpacing: 4, onPressed: _onPressed, ); diff --git a/lib/widgets/desktop/secondary_button.dart b/lib/widgets/desktop/secondary_button.dart index 6dba6fdd8..6b4e46221 100644 --- a/lib/widgets/desktop/secondary_button.dart +++ b/lib/widgets/desktop/secondary_button.dart @@ -78,6 +78,16 @@ class SecondaryButton extends StatelessWidget { .buttonTextSecondaryDisabled, ); } + if (buttonHeight == ButtonHeight.xl) { + return STextStyles.button(context).copyWith( + fontSize: 14, + color: enabled + ? Theme.of(context).extension<StackColors>()!.buttonTextSecondary + : Theme.of(context) + .extension<StackColors>()! + .buttonTextSecondaryDisabled, + ); + } return STextStyles.button(context).copyWith( color: enabled ? Theme.of(context).extension<StackColors>()!.buttonTextSecondary diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart index e366cd713..4e51e0d0d 100644 --- a/lib/widgets/node_card.dart +++ b/lib/widgets/node_card.dart @@ -261,7 +261,7 @@ class _NodeCardState extends ConsumerState<NodeCard> { const SizedBox( width: 66, ), - BlueTextButton( + CustomTextButton( text: "Connect", enabled: _status == "Disconnected", onTap: () async { @@ -285,7 +285,7 @@ class _NodeCardState extends ConsumerState<NodeCard> { const SizedBox( width: 48, ), - BlueTextButton( + CustomTextButton( text: "Details", onTap: () { Navigator.of(context).pushNamed( diff --git a/lib/widgets/rounded_container.dart b/lib/widgets/rounded_container.dart index 9f9bfbd8d..d689d9ca8 100644 --- a/lib/widgets/rounded_container.dart +++ b/lib/widgets/rounded_container.dart @@ -11,6 +11,7 @@ class RoundedContainer extends StatelessWidget { this.width, this.height, this.borderColor, + this.boxShadow, }) : super(key: key); final Widget? child; @@ -20,6 +21,7 @@ class RoundedContainer extends StatelessWidget { final double? width; final double? height; final Color? borderColor; + final List<BoxShadow>? boxShadow; @override Widget build(BuildContext context) { @@ -32,6 +34,7 @@ class RoundedContainer extends StatelessWidget { Constants.size.circularBorderRadius * radiusMultiplier, ), border: borderColor == null ? null : Border.all(color: borderColor!), + boxShadow: boxShadow, ), child: Padding( padding: padding, diff --git a/lib/widgets/rounded_white_container.dart b/lib/widgets/rounded_white_container.dart index 1173e95b1..2ade9b729 100644 --- a/lib/widgets/rounded_white_container.dart +++ b/lib/widgets/rounded_white_container.dart @@ -11,6 +11,7 @@ class RoundedWhiteContainer extends StatelessWidget { this.width, this.height, this.borderColor, + this.boxShadow, }) : super(key: key); final Widget? child; @@ -19,6 +20,7 @@ class RoundedWhiteContainer extends StatelessWidget { final double? width; final double? height; final Color? borderColor; + final List<BoxShadow>? boxShadow; @override Widget build(BuildContext context) { @@ -29,6 +31,7 @@ class RoundedWhiteContainer extends StatelessWidget { width: width, height: height, borderColor: borderColor, + boxShadow: boxShadow, child: child, ); } diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart index 031234142..1b19a2380 100644 --- a/lib/widgets/transaction_card.dart +++ b/lib/widgets/transaction_card.dart @@ -6,7 +6,6 @@ import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; -import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -121,7 +120,8 @@ class _TransactionCardState extends ConsumerState<TransactionCard> { } } - final currentHeight = ref.watch(currentHeightProvider(coin).state).state; + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); return Material( color: Theme.of(context).extension<StackColors>()!.popupBG, diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 59063791f..7c5023a1c 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -14,7 +14,7 @@ import flutter_secure_storage_macos import isar_flutter_libs import package_info_plus_macos import path_provider_macos -import share_plus_macos +import share_plus import shared_preferences_macos import stack_wallet_backup import url_launcher_macos diff --git a/pubspec.lock b/pubspec.lock index 8364e6ec9..5949543b2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -100,8 +100,8 @@ packages: dependency: "direct main" description: path: "." - ref: testing - resolved-ref: "8ed2f6245c71a4457ed4ffdd3a74e4bcb9f9d2d0" + ref: "87bb760be323228aed6ca7bd4532a709a4f10690" + resolved-ref: "87bb760be323228aed6ca7bd4532a709a4f10690" url: "https://github.com/cypherstack/bip47.git" source: git version: "1.0.0" @@ -1237,21 +1237,7 @@ packages: name: share_plus url: "https://pub.dartlang.org" source: hosted - version: "4.5.3" - share_plus_linux: - dependency: transitive - description: - name: share_plus_linux - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - share_plus_macos: - dependency: transitive - description: - name: share_plus_macos - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" + version: "6.3.0" share_plus_platform_interface: dependency: transitive description: @@ -1259,20 +1245,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.2.0" - share_plus_web: - dependency: transitive - description: - name: share_plus_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - share_plus_windows: - dependency: transitive - description: - name: share_plus_windows - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" shared_preferences: dependency: transitive description: @@ -1408,8 +1380,8 @@ packages: dependency: "direct main" description: path: "." - ref: "6ada1204a4e0cf84d932b568e6150550478db69b" - resolved-ref: "6ada1204a4e0cf84d932b568e6150550478db69b" + ref: e4b08d2b8965a5ae49bd57f598fa9011dd0c25e9 + resolved-ref: e4b08d2b8965a5ae49bd57f598fa9011dd0c25e9 url: "https://github.com/cypherstack/stack_wallet_backup.git" source: git version: "0.0.1" diff --git a/pubspec.yaml b/pubspec.yaml index e87083899..86fd250cc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.35+112 +version: 1.5.36+121 environment: sdk: ">=2.17.0 <3.0.0" @@ -54,12 +54,12 @@ dependencies: stack_wallet_backup: git: url: https://github.com/cypherstack/stack_wallet_backup.git - ref: 6ada1204a4e0cf84d932b568e6150550478db69b + ref: e4b08d2b8965a5ae49bd57f598fa9011dd0c25e9 bip47: git: url: https://github.com/cypherstack/bip47.git - ref: testing + ref: 87bb760be323228aed6ca7bd4532a709a4f10690 # Utility plugins # provider: ^6.0.1 @@ -126,7 +126,7 @@ dependencies: tuple: ^2.0.0 flutter_riverpod: ^1.0.3 qr_flutter: ^4.0.0 - share_plus: ^4.0.10 + share_plus: ^6.3.0 emojis: ^0.9.9 pointycastle: ^3.6.0 package_info_plus: ^1.4.2 @@ -205,6 +205,7 @@ flutter: - assets/svg/circle-check.svg - assets/svg/clipboard.svg - assets/images/stack.png + - assets/images/unclaimed.png - assets/images/monero.png - assets/images/wownero.png - assets/images/firo.png @@ -309,6 +310,8 @@ flutter: - assets/svg/plus-circle.svg - assets/svg/circle-plus-filled.svg - assets/svg/configuration.svg + - assets/svg/robot-head.svg + - assets/svg/whirlpool.svg # coin icons - assets/svg/coin_icons/Bitcoin.svg - assets/svg/coin_icons/Litecoin.svg diff --git a/test/pages/send_view/send_view_test.mocks.dart b/test/pages/send_view/send_view_test.mocks.dart index bcd5f44fc..12548c513 100644 --- a/test/pages/send_view/send_view_test.mocks.dart +++ b/test/pages/send_view/send_view_test.mocks.dart @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i17; -import 'dart:ui' as _i19; +import 'dart:async' as _i18; +import 'dart:ui' as _i20; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,26 +13,28 @@ import 'package:stackwallet/db/main_db.dart' as _i13; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i11; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i10; import 'package:stackwallet/models/balance.dart' as _i12; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i22; -import 'package:stackwallet/models/node_model.dart' as _i20; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i23; +import 'package:stackwallet/models/node_model.dart' as _i21; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i9; import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart' - as _i25; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i21; -import 'package:stackwallet/services/coins/coin_service.dart' as _i14; + as _i27; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i22; +import 'package:stackwallet/services/coins/coin_service.dart' as _i15; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i23; +import 'package:stackwallet/services/locale_service.dart' as _i25; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i8; -import 'package:stackwallet/services/wallets.dart' as _i15; +import 'package:stackwallet/services/wallets.dart' as _i16; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i26; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; -import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i24; +import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i28; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i24; +import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i26; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' as _i7; -import 'package:stackwallet/utilities/prefs.dart' as _i18; +import 'package:stackwallet/utilities/prefs.dart' as _i19; +import 'package:tuple/tuple.dart' as _i14; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -171,9 +173,20 @@ class _FakeElectrumXNode_11 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_12 extends _i1.SmartFake - implements _i14.CoinServiceAPI { - _FakeCoinServiceAPI_12( +class _FakeTuple4_12<T1, T2, T3, T4> extends _i1.SmartFake + implements _i14.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_13 extends _i1.SmartFake + implements _i15.CoinServiceAPI { + _FakeCoinServiceAPI_13( Object parent, Invocation parentInvocation, ) : super( @@ -185,7 +198,7 @@ class _FakeCoinServiceAPI_12 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i15.Wallets { +class MockWallets extends _i1.Mock implements _i16.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -252,7 +265,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i16.Coin? coin}) => + List<String> getWalletIdsFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -262,18 +275,18 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Coin, + returnValue: <_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i16.Coin? coin) => + _i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -337,17 +350,17 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( + _i18.Future<void> load(_i19.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> loadAfterStackRestore( - _i18.Prefs? prefs, + _i18.Future<void> loadAfterStackRestore( + _i19.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -358,11 +371,11 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { managers, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -370,7 +383,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -396,19 +409,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i18.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i18.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i17.Future<Map<String, _i2.WalletInfo>>); + ) as _i18.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<bool> renameWallet({ + _i18.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -423,13 +436,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> addExistingStackWallet({ + _i18.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -443,13 +456,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<String?> addNewWallet({ + _i18.Future<String?> addNewWallet({ required String? name, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -462,46 +475,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i18.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i18.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> moveFavorite({ + _i18.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -514,48 +527,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i18.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i18.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<bool> isMnemonicVerified({required String? walletId}) => + _i18.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> setMnemonicVerified({required String? walletId}) => + _i18.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> deleteWallet( + _i18.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -567,20 +580,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i18.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -588,7 +601,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -630,33 +643,33 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), ) as _i7.SecureStorageInterface); @override - List<_i20.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i21.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i20.NodeModel>[], - ) as List<_i20.NodeModel>); + returnValue: <_i21.NodeModel>[], + ) as List<_i21.NodeModel>); @override - List<_i20.NodeModel> get nodes => (super.noSuchMethod( + List<_i21.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i20.NodeModel>[], - ) as List<_i20.NodeModel>); + returnValue: <_i21.NodeModel>[], + ) as List<_i21.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateDefaults() => (super.noSuchMethod( + _i18.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setPrimaryNodeFor({ - required _i16.Coin? coin, - required _i20.NodeModel? node, + _i18.Future<void> setPrimaryNodeFor({ + required _i17.Coin? coin, + required _i21.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -669,44 +682,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i20.NodeModel? getPrimaryNodeFor({required _i16.Coin? coin}) => + _i21.NodeModel? getPrimaryNodeFor({required _i17.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i20.NodeModel?); + )) as _i21.NodeModel?); @override - List<_i20.NodeModel> getNodesFor(_i16.Coin? coin) => (super.noSuchMethod( + List<_i21.NodeModel> getNodesFor(_i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i20.NodeModel>[], - ) as List<_i20.NodeModel>); + returnValue: <_i21.NodeModel>[], + ) as List<_i21.NodeModel>); @override - _i20.NodeModel? getNodeById({required String? id}) => + _i21.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i20.NodeModel?); + )) as _i21.NodeModel?); @override - List<_i20.NodeModel> failoverNodesFor({required _i16.Coin? coin}) => + List<_i21.NodeModel> failoverNodesFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i20.NodeModel>[], - ) as List<_i20.NodeModel>); + returnValue: <_i21.NodeModel>[], + ) as List<_i21.NodeModel>); @override - _i17.Future<void> add( - _i20.NodeModel? node, + _i18.Future<void> add( + _i21.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -719,11 +732,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> delete( + _i18.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -735,11 +748,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setEnabledState( + _i18.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -753,12 +766,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> edit( - _i20.NodeModel? editedNode, + _i18.Future<void> edit( + _i21.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -771,20 +784,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i18.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -792,7 +805,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -820,13 +833,13 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i22.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i17.Timer? _timer) => super.noSuchMethod( + set timer(_i18.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -903,59 +916,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override - _i17.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i23.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), - ) as _i17.Future<List<_i22.UTXO>>); + returnValue: _i18.Future<List<_i23.UTXO>>.value(<_i23.UTXO>[]), + ) as _i18.Future<List<_i23.UTXO>>); @override - _i17.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i23.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), - ) as _i17.Future<List<_i22.Transaction>>); + _i18.Future<List<_i23.Transaction>>.value(<_i23.Transaction>[]), + ) as _i18.Future<List<_i23.Transaction>>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i18.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i17.Future<_i9.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i9.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i9.FeeObject>.value(_FakeFeeObject_6( + returnValue: _i18.Future<_i9.FeeObject>.value(_FakeFeeObject_6( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i9.FeeObject>); + ) as _i18.Future<_i9.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<int> get chainHeight => (super.noSuchMethod( + _i18.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -1044,26 +1057,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { ), ) as _i13.MainDB); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i21.DerivePathType addressType({required String? address}) => + _i24.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i21.DerivePathType.bip44, - ) as _i21.DerivePathType); + returnValue: _i24.DerivePathType.bip44, + ) as _i24.DerivePathType); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1080,47 +1093,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i18.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i18.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i18.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1136,26 +1149,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -1173,33 +1186,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1209,36 +1222,36 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<_i10.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i18.Future<_i10.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), returnValue: - _i17.Future<_i10.ElectrumXNode>.value(_FakeElectrumXNode_11( + _i18.Future<_i10.ElectrumXNode>.value(_FakeElectrumXNode_11( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i17.Future<_i10.ElectrumXNode>); + ) as _i18.Future<_i10.ElectrumXNode>); @override - _i17.Future<void> addDerivation({ + _i18.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i21.DerivePathType? derivePathType, + required _i24.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1252,13 +1265,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addDerivations({ + _i18.Future<void> addDerivations({ required int? chain, - required _i21.DerivePathType? derivePathType, + required _i24.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1271,50 +1284,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<List<Map<String, dynamic>>> fastFetch( + _i18.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i17.Future<List<Map<String, dynamic>>>.value( + returnValue: _i18.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i17.Future<List<Map<String, dynamic>>>); + ) as _i18.Future<List<Map<String, dynamic>>>); @override - _i17.Future<int> getTxCount({required String? address}) => + _i18.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i18.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> checkCurrentChangeAddressesForTransactions() => + _i18.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1338,7 +1351,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i22.UTXO>? utxos, + List<_i23.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1354,19 +1367,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { }, )); @override - _i17.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i22.UTXO>? utxosToUse) => + _i18.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i23.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<Map<String, dynamic>> buildTransaction({ - required List<_i22.UTXO>? utxosToUse, + _i18.Future<Map<String, dynamic>> buildTransaction({ + required List<_i23.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1383,10 +1396,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1398,11 +1411,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1414,8 +1427,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1434,25 +1447,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i18.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void initCache( String? walletId, - _i16.Coin? coin, + _i17.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1465,14 +1478,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i18.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1482,14 +1495,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i18.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1499,15 +1512,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i18.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i12.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1523,15 +1536,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { ), ) as _i12.Balance); @override - _i17.Future<void> updateCachedBalance(_i12.Balance? balance) => + _i18.Future<void> updateCachedBalance(_i12.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i12.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1547,15 +1560,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { ), ) as _i12.Balance); @override - _i17.Future<void> updateCachedBalanceSecondary(_i12.Balance? balance) => + _i18.Future<void> updateCachedBalanceSecondary(_i12.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void initWalletDB({_i13.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1565,12 +1578,55 @@ class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i18.Future< + _i14.Tuple4<_i23.Transaction, List<_i23.Output>, List<_i23.Input>, + _i23.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i23.Address>? myAddresses, + _i17.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i18.Future< + _i14.Tuple4<_i23.Transaction, List<_i23.Output>, List<_i23.Input>, + _i23.Address>>.value(_FakeTuple4_12<_i23.Transaction, + List<_i23.Output>, List<_i23.Input>, _i23.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i18.Future< + _i14.Tuple4<_i23.Transaction, List<_i23.Output>, List<_i23.Input>, + _i23.Address>>); } /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i23.LocaleService { +class MockLocaleService extends _i1.Mock implements _i25.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -1586,17 +1642,17 @@ class MockLocaleService extends _i1.Mock implements _i23.LocaleService { returnValue: false, ) as bool); @override - _i17.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i18.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1604,7 +1660,7 @@ class MockLocaleService extends _i1.Mock implements _i23.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1632,7 +1688,7 @@ class MockLocaleService extends _i1.Mock implements _i23.LocaleService { /// A class which mocks [Prefs]. /// /// See the documentation for Mockito's code generation for more information. -class MockPrefs extends _i1.Mock implements _i18.Prefs { +class MockPrefs extends _i1.Mock implements _i19.Prefs { MockPrefs() { _i1.throwOnMissingStub(this); } @@ -1688,12 +1744,12 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValueForMissingStub: null, ); @override - _i24.SyncingType get syncType => (super.noSuchMethod( + _i26.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), - returnValue: _i24.SyncingType.currentWalletOnly, - ) as _i24.SyncingType); + returnValue: _i26.SyncingType.currentWalletOnly, + ) as _i26.SyncingType); @override - set syncType(_i24.SyncingType? syncType) => super.noSuchMethod( + set syncType(_i26.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( #syncType, syncType, @@ -1753,12 +1809,12 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValueForMissingStub: null, ); @override - _i25.ExchangeRateType get exchangeRateType => (super.noSuchMethod( + _i27.ExchangeRateType get exchangeRateType => (super.noSuchMethod( Invocation.getter(#exchangeRateType), - returnValue: _i25.ExchangeRateType.estimated, - ) as _i25.ExchangeRateType); + returnValue: _i27.ExchangeRateType.estimated, + ) as _i27.ExchangeRateType); @override - set exchangeRateType(_i25.ExchangeRateType? exchangeRateType) => + set exchangeRateType(_i27.ExchangeRateType? exchangeRateType) => super.noSuchMethod( Invocation.setter( #exchangeRateType, @@ -1840,12 +1896,12 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValueForMissingStub: null, ); @override - _i26.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( + _i28.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), - returnValue: _i26.BackupFrequencyType.everyTenMinutes, - ) as _i26.BackupFrequencyType); + returnValue: _i28.BackupFrequencyType.everyTenMinutes, + ) as _i28.BackupFrequencyType); @override - set backupFrequencyType(_i26.BackupFrequencyType? backupFrequencyType) => + set backupFrequencyType(_i28.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( Invocation.setter( #backupFrequencyType, @@ -1915,33 +1971,33 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValue: false, ) as bool); @override - _i17.Future<void> init() => (super.noSuchMethod( + _i18.Future<void> init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( + _i18.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( #incrementCurrentNotificationIndex, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> isExternalCallsSet() => (super.noSuchMethod( + _i18.Future<bool> isExternalCallsSet() => (super.noSuchMethod( Invocation.method( #isExternalCallsSet, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1949,7 +2005,7 @@ class MockPrefs extends _i1.Mock implements _i18.Prefs { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1992,23 +2048,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i14.CoinServiceAPI get wallet => (super.noSuchMethod( + _i15.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_12( + returnValue: _FakeCoinServiceAPI_13( this, Invocation.getter(#wallet), ), - ) as _i14.CoinServiceAPI); + ) as _i15.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2041,23 +2097,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<_i9.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i9.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i9.FeeObject>.value(_FakeFeeObject_6( + returnValue: _i18.Future<_i9.FeeObject>.value(_FakeFeeObject_6( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i9.FeeObject>); + ) as _i18.Future<_i9.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i12.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2067,16 +2123,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i12.Balance); @override - _i17.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i23.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), - ) as _i17.Future<List<_i22.Transaction>>); + _i18.Future<List<_i23.Transaction>>.value(<_i23.Transaction>[]), + ) as _i18.Future<List<_i23.Transaction>>); @override - _i17.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i23.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), - ) as _i17.Future<List<_i22.UTXO>>); + returnValue: _i18.Future<List<_i23.UTXO>>.value(<_i23.UTXO>[]), + ) as _i18.Future<List<_i23.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2096,10 +2152,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -2111,19 +2167,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -2133,7 +2194,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2149,27 +2210,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2179,33 +2240,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2222,20 +2283,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i18.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2247,11 +2308,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2263,18 +2324,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2282,7 +2343,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2302,7 +2363,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i15.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -2313,10 +2374,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2349,23 +2410,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i17.Future<_i9.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i9.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i9.FeeObject>.value(_FakeFeeObject_6( + returnValue: _i18.Future<_i9.FeeObject>.value(_FakeFeeObject_6( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i9.FeeObject>); + ) as _i18.Future<_i9.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i12.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2375,16 +2436,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { ), ) as _i12.Balance); @override - _i17.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i23.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), - ) as _i17.Future<List<_i22.Transaction>>); + _i18.Future<List<_i23.Transaction>>.value(<_i23.Transaction>[]), + ) as _i18.Future<List<_i23.Transaction>>); @override - _i17.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i23.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), - ) as _i17.Future<List<_i22.UTXO>>); + returnValue: _i18.Future<List<_i23.UTXO>>.value(<_i23.UTXO>[]), + ) as _i18.Future<List<_i23.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2404,10 +2465,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2424,7 +2485,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: 0, ) as int); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2440,36 +2501,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2479,15 +2540,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2504,38 +2565,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2547,11 +2608,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2563,24 +2624,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); } 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 bb5c5c408..54ade45c2 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 @@ -363,6 +363,11 @@ class MockManager extends _i1.Mock implements _i11.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 f0c334e7e..84fc1bf4e 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 @@ -324,6 +324,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 f0c11b04a..7d23a2dd7 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 @@ -322,6 +322,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/lockscreen_view_screen_test.mocks.dart b/test/screen_tests/lockscreen_view_screen_test.mocks.dart index 6328b6881..92518048b 100644 --- a/test/screen_tests/lockscreen_view_screen_test.mocks.dart +++ b/test/screen_tests/lockscreen_view_screen_test.mocks.dart @@ -631,6 +631,11 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 c0c6f6902..01f47579b 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 @@ -418,6 +418,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 aef163b0e..106485fdb 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 @@ -418,6 +418,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 7f31b64c4..419b72e3f 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 @@ -418,6 +418,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart b/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart index 56e72d944..50cd7afd8 100644 --- a/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 a7467d9be..ba5f52688 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 @@ -416,6 +416,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 9267a9fba..7a1afa588 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 @@ -631,6 +631,11 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 13aa6edb8..31fb8546c 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 @@ -472,6 +472,11 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart b/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart index b8c7f3cbd..742498415 100644 --- a/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart index 68f2eeb10..b4c96f70c 100644 --- a/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 8b60863ab..9fe30a1cb 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 @@ -408,6 +408,11 @@ class MockManager extends _i1.Mock implements _i11.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 09d59deb2..f0b37d032 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 @@ -408,6 +408,11 @@ class MockManager extends _i1.Mock implements _i11.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart index a958461b8..3711513b4 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart index 284065eba..fc733ad66 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 24da7d388..b36f289d8 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 @@ -416,6 +416,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 0bf926563..dc382ee73 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 @@ -673,6 +673,11 @@ class MockManager extends _i1.Mock implements _i15.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 487f2f2bf..e469b8be4 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 @@ -416,6 +416,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 31bda1f65..bd3520e44 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 @@ -195,6 +195,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart index 161b63e1d..cbfc6644f 100644 --- a/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart @@ -194,6 +194,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart index 7172f3e29..a4936c793 100644 --- a/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart @@ -193,6 +193,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart index ba206a8c6..3126e4580 100644 --- a/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart @@ -235,6 +235,11 @@ class MockManager extends _i1.Mock implements _i8.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, 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 ae6a2d1f9..135802891 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 @@ -195,6 +195,11 @@ class MockManager extends _i1.Mock implements _i5.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/services/coins/bitcoin/bitcoin_wallet_test.dart b/test/services/coins/bitcoin/bitcoin_wallet_test.dart index 6fdea3d03..2efce36f3 100644 --- a/test/services/coins/bitcoin/bitcoin_wallet_test.dart +++ b/test/services/coins/bitcoin/bitcoin_wallet_test.dart @@ -11,6 +11,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'bitcoin_wallet_test.mocks.dart'; @@ -39,12 +40,6 @@ void main() async { }); }); - test("bitcoin DerivePathType enum", () { - expect(DerivePathType.values.length, 3); - expect(DerivePathType.values.toString(), - "[DerivePathType.bip44, DerivePathType.bip49, DerivePathType.bip84]"); - }); - group("bip32 node/root", () { test("getBip32Root", () { final root = getBip32Root(TEST_MNEMONIC, bitcoin); diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart index c4cdede86..20ab88a53 100644 --- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart @@ -11,6 +11,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'bitcoincash_wallet_test.mocks.dart'; @@ -40,24 +41,18 @@ void main() async { }); }); - test("bitcoincash DerivePathType enum", () { - expect(DerivePathType.values.length, 2); - expect(DerivePathType.values.toString(), - "[DerivePathType.bip44, DerivePathType.bip49]"); - }); - - group("bip32 node/root", () { - test("getBip32Root", () { - final root = getBip32Root(TEST_MNEMONIC, bitcoincash); - expect(root.toWIF(), ROOT_WIF); - }); - - test("basic getBip32Node", () { - final node = - getBip32Node(0, 0, TEST_MNEMONIC, bitcoincash, DerivePathType.bip44); - expect(node.toWIF(), NODE_WIF_44); - }); - }); + // group("bip32 node/root", () { + // test("getBip32Root", () { + // final root = getBip32Root(TEST_MNEMONIC, bitcoincash); + // expect(root.toWIF(), ROOT_WIF); + // }); + // + // test("basic getBip32Node", () { + // final node = + // getBip32Node(0, 0, TEST_MNEMONIC, bitcoincash, DerivePathType.bip44); + // expect(node.toWIF(), NODE_WIF_44); + // }); + // }); group("mainnet bitcoincash addressType", () { MockElectrumX? client; diff --git a/test/services/coins/dogecoin/dogecoin_wallet_test.dart b/test/services/coins/dogecoin/dogecoin_wallet_test.dart index e9f166736..7a025e760 100644 --- a/test/services/coins/dogecoin/dogecoin_wallet_test.dart +++ b/test/services/coins/dogecoin/dogecoin_wallet_test.dart @@ -11,6 +11,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'dogecoin_wallet_test.mocks.dart'; @@ -39,11 +40,6 @@ void main() { }); }); - test("dogecoin DerivePathType enum", () { - expect(DerivePathType.values.length, 1); - expect(DerivePathType.values.toString(), "[DerivePathType.bip44]"); - }); - group("bip32 node/root", () { test("getBip32Root", () { final root = getBip32Root(TEST_MNEMONIC, dogecoin); diff --git a/test/services/coins/namecoin/namecoin_wallet_test.dart b/test/services/coins/namecoin/namecoin_wallet_test.dart index 53ce2edbd..22750a935 100644 --- a/test/services/coins/namecoin/namecoin_wallet_test.dart +++ b/test/services/coins/namecoin/namecoin_wallet_test.dart @@ -10,6 +10,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'namecoin_wallet_test.mocks.dart'; @@ -38,12 +39,6 @@ void main() { }); }); - test("namecoin DerivePathType enum", () { - expect(DerivePathType.values.length, 3); - expect(DerivePathType.values.toString(), - "[DerivePathType.bip44, DerivePathType.bip49, DerivePathType.bip84]"); - }); - group("bip32 node/root", () { test("getBip32Root", () { final root = getBip32Root(TEST_MNEMONIC, namecoin); diff --git a/test/services/coins/particl/particl_wallet_test.dart b/test/services/coins/particl/particl_wallet_test.dart index 698a5f657..4f4d0e81b 100644 --- a/test/services/coins/particl/particl_wallet_test.dart +++ b/test/services/coins/particl/particl_wallet_test.dart @@ -10,6 +10,7 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/particl/particl_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'particl_wallet_test.mocks.dart'; @@ -39,12 +40,6 @@ void main() { }); }); - test("particl DerivePathType enum", () { - expect(DerivePathType.values.length, 2); - expect(DerivePathType.values.toString(), - "[DerivePathType.bip44, DerivePathType.bip84]"); - }); - group("bip32 node/root", () { test("getBip32Root", () { final root = getBip32Root(TEST_MNEMONIC, particl); diff --git a/test/widget_tests/managed_favorite_test.mocks.dart b/test/widget_tests/managed_favorite_test.mocks.dart index a5ee69930..a51988ce0 100644 --- a/test/widget_tests/managed_favorite_test.mocks.dart +++ b/test/widget_tests/managed_favorite_test.mocks.dart @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i17; -import 'dart:ui' as _i19; +import 'dart:async' as _i18; +import 'dart:ui' as _i20; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,22 +13,24 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21; -import 'package:stackwallet/models/node_model.dart' as _i23; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i22; +import 'package:stackwallet/models/node_model.dart' as _i25; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i20; -import 'package:stackwallet/services/coins/coin_service.dart' as _i14; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i21; +import 'package:stackwallet/services/coins/coin_service.dart' as _i15; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i22; +import 'package:stackwallet/services/locale_service.dart' as _i24; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i15; +import 'package:stackwallet/services/wallets.dart' as _i16; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i23; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i13; -import 'package:stackwallet/utilities/prefs.dart' as _i18; + as _i14; +import 'package:stackwallet/utilities/prefs.dart' as _i19; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -155,9 +157,9 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } -class _FakeSecureStorageInterface_11 extends _i1.SmartFake - implements _i13.SecureStorageInterface { - _FakeSecureStorageInterface_11( +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( Object parent, Invocation parentInvocation, ) : super( @@ -166,9 +168,20 @@ class _FakeSecureStorageInterface_11 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_12 extends _i1.SmartFake - implements _i14.CoinServiceAPI { - _FakeCoinServiceAPI_12( +class _FakeSecureStorageInterface_12 extends _i1.SmartFake + implements _i14.SecureStorageInterface { + _FakeSecureStorageInterface_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_13 extends _i1.SmartFake + implements _i15.CoinServiceAPI { + _FakeCoinServiceAPI_13( Object parent, Invocation parentInvocation, ) : super( @@ -180,7 +193,7 @@ class _FakeCoinServiceAPI_12 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i15.Wallets { +class MockWallets extends _i1.Mock implements _i16.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -247,7 +260,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i16.Coin? coin}) => + List<String> getWalletIdsFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -257,18 +270,18 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Coin, + returnValue: <_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i16.Coin? coin) => + _i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -332,17 +345,17 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( + _i18.Future<void> load(_i19.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> loadAfterStackRestore( - _i18.Prefs? prefs, + _i18.Future<void> loadAfterStackRestore( + _i19.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -353,11 +366,11 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { managers, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -365,7 +378,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -391,19 +404,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i18.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i18.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i17.Future<Map<String, _i2.WalletInfo>>); + ) as _i18.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<bool> renameWallet({ + _i18.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -418,13 +431,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> addExistingStackWallet({ + _i18.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -438,13 +451,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<String?> addNewWallet({ + _i18.Future<String?> addNewWallet({ required String? name, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -457,46 +470,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i18.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i18.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> moveFavorite({ + _i18.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -509,48 +522,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i18.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i18.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<bool> isMnemonicVerified({required String? walletId}) => + _i18.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> setMnemonicVerified({required String? walletId}) => + _i18.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> deleteWallet( + _i18.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -562,20 +575,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i18.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -583,7 +596,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -611,13 +624,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i17.Timer? _timer) => super.noSuchMethod( + set timer(_i18.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -694,59 +707,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i18.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<int> get chainHeight => (super.noSuchMethod( + _i18.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -835,26 +848,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i12.MainDB); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i20.DerivePathType addressType({required String? address}) => + _i23.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i20.DerivePathType.bip44, - ) as _i20.DerivePathType); + returnValue: _i23.DerivePathType.bip44, + ) as _i23.DerivePathType); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -871,47 +884,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i18.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i18.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i18.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -927,26 +940,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -964,33 +977,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1000,35 +1013,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i18.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i17.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i18.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i17.Future<_i9.ElectrumXNode>); + ) as _i18.Future<_i9.ElectrumXNode>); @override - _i17.Future<void> addDerivation({ + _i18.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1042,13 +1055,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addDerivations({ + _i18.Future<void> addDerivations({ required int? chain, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1061,50 +1074,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<List<Map<String, dynamic>>> fastFetch( + _i18.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i17.Future<List<Map<String, dynamic>>>.value( + returnValue: _i18.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i17.Future<List<Map<String, dynamic>>>); + ) as _i18.Future<List<Map<String, dynamic>>>); @override - _i17.Future<int> getTxCount({required String? address}) => + _i18.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i18.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> checkCurrentChangeAddressesForTransactions() => + _i18.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1128,7 +1141,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i21.UTXO>? utxos, + List<_i22.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1144,19 +1157,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, )); @override - _i17.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i21.UTXO>? utxosToUse) => + _i18.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i22.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<Map<String, dynamic>> buildTransaction({ - required List<_i21.UTXO>? utxosToUse, + _i18.Future<Map<String, dynamic>> buildTransaction({ + required List<_i22.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1173,10 +1186,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1188,11 +1201,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1204,8 +1217,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1224,25 +1237,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i18.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void initCache( String? walletId, - _i16.Coin? coin, + _i17.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1255,14 +1268,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i18.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1272,14 +1285,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i18.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1289,15 +1302,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i18.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1313,15 +1326,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1337,15 +1350,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1355,12 +1368,55 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i22.Address>? myAddresses, + _i17.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>.value(_FakeTuple4_11<_i22.Transaction, + List<_i22.Output>, List<_i22.Input>, _i22.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>); } /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i22.LocaleService { +class MockLocaleService extends _i1.Mock implements _i24.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -1376,17 +1432,17 @@ class MockLocaleService extends _i1.Mock implements _i22.LocaleService { returnValue: false, ) as bool); @override - _i17.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i18.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1394,7 +1450,7 @@ class MockLocaleService extends _i1.Mock implements _i22.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1424,41 +1480,41 @@ class MockLocaleService extends _i1.Mock implements _i22.LocaleService { /// See the documentation for Mockito's code generation for more information. class MockNodeService extends _i1.Mock implements _i3.NodeService { @override - _i13.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i14.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_11( + returnValue: _FakeSecureStorageInterface_12( this, Invocation.getter(#secureStorageInterface), ), - ) as _i13.SecureStorageInterface); + ) as _i14.SecureStorageInterface); @override - List<_i23.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i25.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i23.NodeModel>[], - ) as List<_i23.NodeModel>); + returnValue: <_i25.NodeModel>[], + ) as List<_i25.NodeModel>); @override - List<_i23.NodeModel> get nodes => (super.noSuchMethod( + List<_i25.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i23.NodeModel>[], - ) as List<_i23.NodeModel>); + returnValue: <_i25.NodeModel>[], + ) as List<_i25.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateDefaults() => (super.noSuchMethod( + _i18.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setPrimaryNodeFor({ - required _i16.Coin? coin, - required _i23.NodeModel? node, + _i18.Future<void> setPrimaryNodeFor({ + required _i17.Coin? coin, + required _i25.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -1471,44 +1527,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i23.NodeModel? getPrimaryNodeFor({required _i16.Coin? coin}) => + _i25.NodeModel? getPrimaryNodeFor({required _i17.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i23.NodeModel?); + )) as _i25.NodeModel?); @override - List<_i23.NodeModel> getNodesFor(_i16.Coin? coin) => (super.noSuchMethod( + List<_i25.NodeModel> getNodesFor(_i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i23.NodeModel>[], - ) as List<_i23.NodeModel>); + returnValue: <_i25.NodeModel>[], + ) as List<_i25.NodeModel>); @override - _i23.NodeModel? getNodeById({required String? id}) => + _i25.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i23.NodeModel?); + )) as _i25.NodeModel?); @override - List<_i23.NodeModel> failoverNodesFor({required _i16.Coin? coin}) => + List<_i25.NodeModel> failoverNodesFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i23.NodeModel>[], - ) as List<_i23.NodeModel>); + returnValue: <_i25.NodeModel>[], + ) as List<_i25.NodeModel>); @override - _i17.Future<void> add( - _i23.NodeModel? node, + _i18.Future<void> add( + _i25.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -1521,11 +1577,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> delete( + _i18.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -1537,11 +1593,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setEnabledState( + _i18.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -1555,12 +1611,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> edit( - _i23.NodeModel? editedNode, + _i18.Future<void> edit( + _i25.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -1573,20 +1629,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i18.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1594,7 +1650,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1637,23 +1693,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i14.CoinServiceAPI get wallet => (super.noSuchMethod( + _i15.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_12( + returnValue: _FakeCoinServiceAPI_13( this, Invocation.getter(#wallet), ), - ) as _i14.CoinServiceAPI); + ) as _i15.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1686,23 +1742,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1712,16 +1768,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1741,10 +1797,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -1756,19 +1812,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1778,7 +1839,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1794,27 +1855,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1824,33 +1885,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1867,20 +1928,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i18.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1892,11 +1953,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1908,18 +1969,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1927,7 +1988,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1947,7 +2008,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i15.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1958,10 +2019,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1994,23 +2055,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2020,16 +2081,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2049,10 +2110,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2069,7 +2130,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: 0, ) as int); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2085,36 +2146,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2124,15 +2185,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2149,38 +2210,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2192,11 +2253,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2208,24 +2269,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); } 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 d31019d37..aeefa1a27 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 @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i16; -import 'dart:ui' as _i18; +import 'dart:async' as _i17; +import 'dart:ui' as _i19; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,18 +13,20 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i20; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i19; -import 'package:stackwallet/services/coins/coin_service.dart' as _i13; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i20; +import 'package:stackwallet/services/coins/coin_service.dart' as _i14; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i14; +import 'package:stackwallet/services/wallets.dart' as _i15; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i15; -import 'package:stackwallet/utilities/prefs.dart' as _i17; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i22; +import 'package:stackwallet/utilities/prefs.dart' as _i18; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -151,9 +153,20 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } -class _FakeCoinServiceAPI_11 extends _i1.SmartFake - implements _i13.CoinServiceAPI { - _FakeCoinServiceAPI_11( +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_12 extends _i1.SmartFake + implements _i14.CoinServiceAPI { + _FakeCoinServiceAPI_12( Object parent, Invocation parentInvocation, ) : super( @@ -165,7 +178,7 @@ class _FakeCoinServiceAPI_11 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i14.Wallets { +class MockWallets extends _i1.Mock implements _i15.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -232,7 +245,7 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i15.Coin? coin}) => + List<String> getWalletIdsFor({required _i16.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -242,18 +255,18 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i15.Coin, + returnValue: <_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i15.Coin? coin) => + _i16.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -317,17 +330,17 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { returnValueForMissingStub: null, ); @override - _i16.Future<void> load(_i17.Prefs? prefs) => (super.noSuchMethod( + _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> loadAfterStackRestore( - _i17.Prefs? prefs, + _i17.Future<void> loadAfterStackRestore( + _i18.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -338,11 +351,11 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { managers, ], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -350,7 +363,7 @@ class MockWallets extends _i1.Mock implements _i14.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -376,19 +389,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i16.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i16.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i16.Future<Map<String, _i2.WalletInfo>>); + ) as _i17.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i16.Future<bool> renameWallet({ + _i17.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -403,13 +416,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> addExistingStackWallet({ + _i17.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i15.Coin? coin, + required _i16.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -423,13 +436,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<String?> addNewWallet({ + _i17.Future<String?> addNewWallet({ required String? name, - required _i15.Coin? coin, + required _i16.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -442,46 +455,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i16.Future<String?>.value(), - ) as _i16.Future<String?>); + returnValue: _i17.Future<String?>.value(), + ) as _i17.Future<String?>); @override - _i16.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i16.Future<List<String>>.value(<String>[]), - ) as _i16.Future<List<String>>); + returnValue: _i17.Future<List<String>>.value(<String>[]), + ) as _i17.Future<List<String>>); @override - _i16.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> moveFavorite({ + _i17.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -494,48 +507,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i16.Future<String?>.value(), - ) as _i16.Future<String?>); + returnValue: _i17.Future<String?>.value(), + ) as _i17.Future<String?>); @override - _i16.Future<bool> isMnemonicVerified({required String? walletId}) => + _i17.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> setMnemonicVerified({required String? walletId}) => + _i17.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<int> deleteWallet( + _i17.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -547,20 +560,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -568,7 +581,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -596,13 +609,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i16.Timer? _timer) => super.noSuchMethod( + set timer(_i17.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -679,59 +692,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: false, ) as bool); @override - _i15.Coin get coin => (super.noSuchMethod( + _i16.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i15.Coin.bitcoin, - ) as _i15.Coin); + returnValue: _i16.Coin.bitcoin, + ) as _i16.Coin); @override - _i16.Future<List<_i20.UTXO>> get utxos => (super.noSuchMethod( + _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i16.Future<List<_i20.UTXO>>.value(<_i20.UTXO>[]), - ) as _i16.Future<List<_i20.UTXO>>); + returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), + ) as _i17.Future<List<_i21.UTXO>>); @override - _i16.Future<List<_i20.Transaction>> get transactions => (super.noSuchMethod( + _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i16.Future<List<_i20.Transaction>>.value(<_i20.Transaction>[]), - ) as _i16.Future<List<_i20.Transaction>>); + _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), + ) as _i17.Future<List<_i21.Transaction>>); @override - _i16.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override - _i16.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i16.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i16.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i16.Future<_i8.FeeObject>); + ) as _i17.Future<_i8.FeeObject>); @override - _i16.Future<int> get maxFee => (super.noSuchMethod( + _i17.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i16.Future<List<String>>.value(<String>[]), - ) as _i16.Future<List<String>>); + returnValue: _i17.Future<List<String>>.value(<String>[]), + ) as _i17.Future<List<String>>); @override - _i16.Future<int> get chainHeight => (super.noSuchMethod( + _i17.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -820,26 +833,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { ), ) as _i12.MainDB); @override - _i16.Future<void> exit() => (super.noSuchMethod( + _i17.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i19.DerivePathType addressType({required String? address}) => + _i22.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i19.DerivePathType.bip44, - ) as _i19.DerivePathType); + returnValue: _i22.DerivePathType.bip44, + ) as _i22.DerivePathType); @override - _i16.Future<void> recoverFromMnemonic({ + _i17.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -856,47 +869,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { #height: height, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> refresh() => (super.noSuchMethod( + _i17.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<Map<String, dynamic>> prepareSend({ + _i17.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -912,26 +925,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { }, ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override - _i16.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -949,33 +962,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i16.Future<void> initializeNew() => (super.noSuchMethod( + _i17.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> initializeExisting() => (super.noSuchMethod( + _i17.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -985,35 +998,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i17.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i16.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i17.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i16.Future<_i9.ElectrumXNode>); + ) as _i17.Future<_i9.ElectrumXNode>); @override - _i16.Future<void> addDerivation({ + _i17.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i19.DerivePathType? derivePathType, + required _i22.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1027,13 +1040,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> addDerivations({ + _i17.Future<void> addDerivations({ required int? chain, - required _i19.DerivePathType? derivePathType, + required _i22.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1046,50 +1059,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<List<Map<String, dynamic>>> fastFetch( + _i17.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i16.Future<List<Map<String, dynamic>>>.value( + returnValue: _i17.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i16.Future<List<Map<String, dynamic>>>); + ) as _i17.Future<List<Map<String, dynamic>>>); @override - _i16.Future<int> getTxCount({required String? address}) => + _i17.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> checkCurrentChangeAddressesForTransactions() => + _i17.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1113,7 +1126,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i20.UTXO>? utxos, + List<_i21.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1129,19 +1142,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { }, )); @override - _i16.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i20.UTXO>? utxosToUse) => + _i17.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i21.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<Map<String, dynamic>> buildTransaction({ - required List<_i20.UTXO>? utxosToUse, + _i17.Future<Map<String, dynamic>> buildTransaction({ + required List<_i21.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1158,10 +1171,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { }, ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<void> fullRescan( + _i17.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1173,11 +1186,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<int> estimateFeeFor( + _i17.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1189,8 +1202,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { feeRate, ], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1209,25 +1222,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: 0, ) as int); @override - _i16.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override void initCache( String? walletId, - _i15.Coin? coin, + _i16.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1240,14 +1253,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i16.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1257,14 +1270,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: 0, ) as int); @override - _i16.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1274,15 +1287,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1298,15 +1311,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { ), ) as _i11.Balance); @override - _i16.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i17.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1322,15 +1335,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { ), ) as _i11.Balance); @override - _i16.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i17.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1340,6 +1353,49 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i17.Future< + _i13.Tuple4<_i21.Transaction, List<_i21.Output>, List<_i21.Input>, + _i21.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i21.Address>? myAddresses, + _i16.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i17.Future< + _i13.Tuple4<_i21.Transaction, List<_i21.Output>, List<_i21.Input>, + _i21.Address>>.value(_FakeTuple4_11<_i21.Transaction, + List<_i21.Output>, List<_i21.Input>, _i21.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i17.Future< + _i13.Tuple4<_i21.Transaction, List<_i21.Output>, List<_i21.Input>, + _i21.Address>>); } /// A class which mocks [Manager]. @@ -1360,23 +1416,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i13.CoinServiceAPI get wallet => (super.noSuchMethod( + _i14.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_11( + returnValue: _FakeCoinServiceAPI_12( this, Invocation.getter(#wallet), ), - ) as _i13.CoinServiceAPI); + ) as _i14.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i15.Coin get coin => (super.noSuchMethod( + _i16.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i15.Coin.bitcoin, - ) as _i15.Coin); + returnValue: _i16.Coin.bitcoin, + ) as _i16.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1409,23 +1465,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i16.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i16.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i16.Future<_i8.FeeObject>); + ) as _i17.Future<_i8.FeeObject>); @override - _i16.Future<int> get maxFee => (super.noSuchMethod( + _i17.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1435,16 +1491,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i16.Future<List<_i20.Transaction>> get transactions => (super.noSuchMethod( + _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i16.Future<List<_i20.Transaction>>.value(<_i20.Transaction>[]), - ) as _i16.Future<List<_i20.Transaction>>); + _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), + ) as _i17.Future<List<_i21.Transaction>>); @override - _i16.Future<List<_i20.UTXO>> get utxos => (super.noSuchMethod( + _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i16.Future<List<_i20.UTXO>>.value(<_i20.UTXO>[]), - ) as _i16.Future<List<_i20.UTXO>>); + returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), + ) as _i17.Future<List<_i21.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1464,10 +1520,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i16.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i16.Future<List<String>>.value(<String>[]), - ) as _i16.Future<List<String>>); + returnValue: _i17.Future<List<String>>.value(<String>[]), + ) as _i17.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -1479,19 +1535,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i16.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1501,7 +1562,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i16.Future<Map<String, dynamic>> prepareSend({ + _i17.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1517,27 +1578,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override - _i16.Future<void> refresh() => (super.noSuchMethod( + _i17.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1547,33 +1608,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i16.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> initializeNew() => (super.noSuchMethod( + _i17.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> initializeExisting() => (super.noSuchMethod( + _i17.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> recoverFromMnemonic({ + _i17.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1590,20 +1651,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> fullRescan( + _i17.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1615,11 +1676,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<int> estimateFeeFor( + _i17.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1631,18 +1692,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1650,7 +1711,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1670,7 +1731,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1681,10 +1742,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i15.Coin get coin => (super.noSuchMethod( + _i16.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i15.Coin.bitcoin, - ) as _i15.Coin); + returnValue: _i16.Coin.bitcoin, + ) as _i16.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1717,23 +1778,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i16.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i16.Future<_i8.FeeObject>); + ) as _i17.Future<_i8.FeeObject>); @override - _i16.Future<int> get maxFee => (super.noSuchMethod( + _i17.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1743,16 +1804,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { ), ) as _i11.Balance); @override - _i16.Future<List<_i20.Transaction>> get transactions => (super.noSuchMethod( + _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i16.Future<List<_i20.Transaction>>.value(<_i20.Transaction>[]), - ) as _i16.Future<List<_i20.Transaction>>); + _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), + ) as _i17.Future<List<_i21.Transaction>>); @override - _i16.Future<List<_i20.UTXO>> get utxos => (super.noSuchMethod( + _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i16.Future<List<_i20.UTXO>>.value(<_i20.UTXO>[]), - ) as _i16.Future<List<_i20.UTXO>>); + returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), + ) as _i17.Future<List<_i21.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1772,10 +1833,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValue: '', ) as String); @override - _i16.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i16.Future<List<String>>.value(<String>[]), - ) as _i16.Future<List<String>>); + returnValue: _i17.Future<List<String>>.value(<String>[]), + ) as _i17.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -1792,7 +1853,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValue: 0, ) as int); @override - _i16.Future<Map<String, dynamic>> prepareSend({ + _i17.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1808,36 +1869,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { }, ), returnValue: - _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i16.Future<Map<String, dynamic>>); + _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i17.Future<Map<String, dynamic>>); @override - _i16.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i16.Future<String>.value(''), - ) as _i16.Future<String>); + returnValue: _i17.Future<String>.value(''), + ) as _i17.Future<String>); @override - _i16.Future<void> refresh() => (super.noSuchMethod( + _i17.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1847,15 +1908,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { returnValue: false, ) as bool); @override - _i16.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> recoverFromMnemonic({ + _i17.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1872,38 +1933,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { #height: height, }, ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> initializeNew() => (super.noSuchMethod( + _i17.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> initializeExisting() => (super.noSuchMethod( + _i17.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> exit() => (super.noSuchMethod( + _i17.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<void> fullRescan( + _i17.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1915,11 +1976,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); @override - _i16.Future<int> estimateFeeFor( + _i17.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1931,24 +1992,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI { feeRate, ], ), - returnValue: _i16.Future<int>.value(0), - ) as _i16.Future<int>); + returnValue: _i17.Future<int>.value(0), + ) as _i17.Future<int>); @override - _i16.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i16.Future<bool>.value(false), - ) as _i16.Future<bool>); + returnValue: _i17.Future<bool>.value(false), + ) as _i17.Future<bool>); @override - _i16.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i16.Future<void>.value(), - returnValueForMissingStub: _i16.Future<void>.value(), - ) as _i16.Future<void>); + returnValue: _i17.Future<void>.value(), + returnValueForMissingStub: _i17.Future<void>.value(), + ) as _i17.Future<void>); } diff --git a/test/widget_tests/transaction_card_test.dart b/test/widget_tests/transaction_card_test.dart index 0ab7e4477..84b6372d5 100644 --- a/test/widget_tests/transaction_card_test.dart +++ b/test/widget_tests/transaction_card_test.dart @@ -80,6 +80,8 @@ void main() { when(wallets.getManager("wallet-id")) .thenAnswer((realInvocation) => Manager(wallet)); + + when(wallet.storedChainHeight).thenAnswer((_) => 6000000); // await tester.pumpWidget( ProviderScope( @@ -173,6 +175,7 @@ void main() { .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00)); when(wallet.coin).thenAnswer((_) => Coin.firo); + when(wallet.storedChainHeight).thenAnswer((_) => 6000000); when(wallets.getManager("wallet-id")) .thenAnswer((realInvocation) => Manager(wallet)); @@ -271,6 +274,8 @@ void main() { when(wallets.getManager("wallet-id")) .thenAnswer((realInvocation) => Manager(wallet)); + when(wallet.storedChainHeight).thenAnswer((_) => 6000000); + await tester.pumpWidget( ProviderScope( overrides: [ @@ -358,6 +363,8 @@ void main() { when(wallets.getManager("wallet id")) .thenAnswer((realInvocation) => Manager(wallet)); + when(wallet.storedChainHeight).thenAnswer((_) => 6000000); + mockingjay .when(() => navigator.pushNamed("/transactionDetails", arguments: Tuple3(tx, Coin.firo, "wallet id"))) @@ -395,6 +402,7 @@ void main() { verify(mockPrefs.currency).called(2); verify(mockLocaleService.locale).called(4); verify(wallet.coin.ticker).called(2); + verify(wallet.storedChainHeight).called(2); verifyNoMoreInteractions(wallet); verifyNoMoreInteractions(mockLocaleService); diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart index c3b2cce4b..1ef218b2d 100644 --- a/test/widget_tests/transaction_card_test.mocks.dart +++ b/test/widget_tests/transaction_card_test.mocks.dart @@ -538,6 +538,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, diff --git a/test/widget_tests/wallet_card_test.mocks.dart b/test/widget_tests/wallet_card_test.mocks.dart index 5a5d048b3..2bffe7a06 100644 --- a/test/widget_tests/wallet_card_test.mocks.dart +++ b/test/widget_tests/wallet_card_test.mocks.dart @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i15; -import 'dart:ui' as _i17; +import 'dart:async' as _i16; +import 'dart:ui' as _i18; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,18 +13,20 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i19; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i20; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i18; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i19; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i20; +import 'package:stackwallet/services/locale_service.dart' as _i22; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i13; +import 'package:stackwallet/services/wallets.dart' as _i14; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i14; -import 'package:stackwallet/utilities/prefs.dart' as _i16; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i15; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i21; +import 'package:stackwallet/utilities/prefs.dart' as _i17; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -151,10 +153,21 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i13.Wallets { +class MockWallets extends _i1.Mock implements _i14.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -221,7 +234,7 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i14.Coin? coin}) => + List<String> getWalletIdsFor({required _i15.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -231,18 +244,18 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i14.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i14.Coin, + returnValue: <_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i14.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i15.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i14.Coin? coin) => + _i15.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -306,17 +319,17 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { returnValueForMissingStub: null, ); @override - _i15.Future<void> load(_i16.Prefs? prefs) => (super.noSuchMethod( + _i16.Future<void> load(_i17.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> loadAfterStackRestore( - _i16.Prefs? prefs, + _i16.Future<void> loadAfterStackRestore( + _i17.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -327,11 +340,11 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { managers, ], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -339,7 +352,7 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -359,13 +372,13 @@ class MockWallets extends _i1.Mock implements _i13.Wallets { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i15.Timer? _timer) => super.noSuchMethod( + set timer(_i16.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -442,59 +455,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: false, ) as bool); @override - _i14.Coin get coin => (super.noSuchMethod( + _i15.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i14.Coin.bitcoin, - ) as _i14.Coin); + returnValue: _i15.Coin.bitcoin, + ) as _i15.Coin); @override - _i15.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( + _i16.Future<List<_i20.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i15.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), - ) as _i15.Future<List<_i19.UTXO>>); + returnValue: _i16.Future<List<_i20.UTXO>>.value(<_i20.UTXO>[]), + ) as _i16.Future<List<_i20.UTXO>>); @override - _i15.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( + _i16.Future<List<_i20.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i15.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), - ) as _i15.Future<List<_i19.Transaction>>); + _i16.Future<List<_i20.Transaction>>.value(<_i20.Transaction>[]), + ) as _i16.Future<List<_i20.Transaction>>); @override - _i15.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i16.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i15.Future<String>.value(''), - ) as _i15.Future<String>); + returnValue: _i16.Future<String>.value(''), + ) as _i16.Future<String>); @override - _i15.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i16.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i15.Future<String>.value(''), - ) as _i15.Future<String>); + returnValue: _i16.Future<String>.value(''), + ) as _i16.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i15.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i16.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i15.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i16.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i15.Future<_i8.FeeObject>); + ) as _i16.Future<_i8.FeeObject>); @override - _i15.Future<int> get maxFee => (super.noSuchMethod( + _i16.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override - _i15.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i16.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i15.Future<List<String>>.value(<String>[]), - ) as _i15.Future<List<String>>); + returnValue: _i16.Future<List<String>>.value(<String>[]), + ) as _i16.Future<List<String>>); @override - _i15.Future<int> get chainHeight => (super.noSuchMethod( + _i16.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -583,26 +596,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { ), ) as _i12.MainDB); @override - _i15.Future<void> exit() => (super.noSuchMethod( + _i16.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i18.DerivePathType addressType({required String? address}) => + _i21.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i18.DerivePathType.bip44, - ) as _i18.DerivePathType); + returnValue: _i21.DerivePathType.bip44, + ) as _i21.DerivePathType); @override - _i15.Future<void> recoverFromMnemonic({ + _i16.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -619,47 +632,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { #height: height, }, ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i16.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i16.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i15.Future<bool>.value(false), - ) as _i15.Future<bool>); + returnValue: _i16.Future<bool>.value(false), + ) as _i16.Future<bool>); @override - _i15.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i16.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> refresh() => (super.noSuchMethod( + _i16.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<Map<String, dynamic>> prepareSend({ + _i16.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -675,26 +688,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { }, ), returnValue: - _i15.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i15.Future<Map<String, dynamic>>); + _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i16.Future<Map<String, dynamic>>); @override - _i15.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i16.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i15.Future<String>.value(''), - ) as _i15.Future<String>); + returnValue: _i16.Future<String>.value(''), + ) as _i16.Future<String>); @override - _i15.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i16.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i15.Future<bool>.value(false), - ) as _i15.Future<bool>); + returnValue: _i16.Future<bool>.value(false), + ) as _i16.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -712,33 +725,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i15.Future<void> initializeNew() => (super.noSuchMethod( + _i16.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> initializeExisting() => (super.noSuchMethod( + _i16.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i16.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -748,35 +761,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: false, ) as bool); @override - _i15.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i16.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i16.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i15.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i16.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i15.Future<_i9.ElectrumXNode>); + ) as _i16.Future<_i9.ElectrumXNode>); @override - _i15.Future<void> addDerivation({ + _i16.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i18.DerivePathType? derivePathType, + required _i21.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -790,13 +803,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> addDerivations({ + _i16.Future<void> addDerivations({ required int? chain, - required _i18.DerivePathType? derivePathType, + required _i21.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -809,50 +822,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<List<Map<String, dynamic>>> fastFetch( + _i16.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i15.Future<List<Map<String, dynamic>>>.value( + returnValue: _i16.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i15.Future<List<Map<String, dynamic>>>); + ) as _i16.Future<List<Map<String, dynamic>>>); @override - _i15.Future<int> getTxCount({required String? address}) => + _i16.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override - _i15.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i16.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<void> checkCurrentChangeAddressesForTransactions() => + _i16.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -876,7 +889,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i19.UTXO>? utxos, + List<_i20.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -892,19 +905,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { }, )); @override - _i15.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i19.UTXO>? utxosToUse) => + _i16.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i20.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i15.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i15.Future<Map<String, dynamic>>); + _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i16.Future<Map<String, dynamic>>); @override - _i15.Future<Map<String, dynamic>> buildTransaction({ - required List<_i19.UTXO>? utxosToUse, + _i16.Future<Map<String, dynamic>> buildTransaction({ + required List<_i20.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -921,10 +934,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { }, ), returnValue: - _i15.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i15.Future<Map<String, dynamic>>); + _i16.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i16.Future<Map<String, dynamic>>); @override - _i15.Future<void> fullRescan( + _i16.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -936,11 +949,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - _i15.Future<int> estimateFeeFor( + _i16.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -952,8 +965,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { feeRate, ], ), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -972,25 +985,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: 0, ) as int); @override - _i15.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i16.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i15.Future<int>.value(0), - ) as _i15.Future<int>); + returnValue: _i16.Future<int>.value(0), + ) as _i16.Future<int>); @override - _i15.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i16.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i15.Future<bool>.value(false), - ) as _i15.Future<bool>); + returnValue: _i16.Future<bool>.value(false), + ) as _i16.Future<bool>); @override void initCache( String? walletId, - _i14.Coin? coin, + _i15.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1003,14 +1016,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i15.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i16.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1020,14 +1033,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: 0, ) as int); @override - _i15.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i16.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1037,15 +1050,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { returnValue: false, ) as bool); @override - _i15.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i16.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1061,15 +1074,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { ), ) as _i11.Balance); @override - _i15.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i16.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1085,15 +1098,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { ), ) as _i11.Balance); @override - _i15.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i16.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1103,12 +1116,55 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i16.Future< + _i13.Tuple4<_i20.Transaction, List<_i20.Output>, List<_i20.Input>, + _i20.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i20.Address>? myAddresses, + _i15.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i16.Future< + _i13.Tuple4<_i20.Transaction, List<_i20.Output>, List<_i20.Input>, + _i20.Address>>.value(_FakeTuple4_11<_i20.Transaction, + List<_i20.Output>, List<_i20.Input>, _i20.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i16.Future< + _i13.Tuple4<_i20.Transaction, List<_i20.Output>, List<_i20.Input>, + _i20.Address>>); } /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i20.LocaleService { +class MockLocaleService extends _i1.Mock implements _i22.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -1124,17 +1180,17 @@ class MockLocaleService extends _i1.Mock implements _i20.LocaleService { returnValue: false, ) as bool); @override - _i15.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i16.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i15.Future<void>.value(), - returnValueForMissingStub: _i15.Future<void>.value(), - ) as _i15.Future<void>); + returnValue: _i16.Future<void>.value(), + returnValueForMissingStub: _i16.Future<void>.value(), + ) as _i16.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i18.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1142,7 +1198,7 @@ class MockLocaleService extends _i1.Mock implements _i20.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i18.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], 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 41f874146..5f2b9b7f5 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 @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i17; -import 'dart:ui' as _i19; +import 'dart:async' as _i18; +import 'dart:ui' as _i20; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,21 +13,23 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21; -import 'package:stackwallet/models/node_model.dart' as _i22; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i22; +import 'package:stackwallet/models/node_model.dart' as _i24; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i20; -import 'package:stackwallet/services/coins/coin_service.dart' as _i14; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i21; +import 'package:stackwallet/services/coins/coin_service.dart' as _i15; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i15; +import 'package:stackwallet/services/wallets.dart' as _i16; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i23; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i13; -import 'package:stackwallet/utilities/prefs.dart' as _i18; + as _i14; +import 'package:stackwallet/utilities/prefs.dart' as _i19; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -154,9 +156,9 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } -class _FakeSecureStorageInterface_11 extends _i1.SmartFake - implements _i13.SecureStorageInterface { - _FakeSecureStorageInterface_11( +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( Object parent, Invocation parentInvocation, ) : super( @@ -165,9 +167,20 @@ class _FakeSecureStorageInterface_11 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_12 extends _i1.SmartFake - implements _i14.CoinServiceAPI { - _FakeCoinServiceAPI_12( +class _FakeSecureStorageInterface_12 extends _i1.SmartFake + implements _i14.SecureStorageInterface { + _FakeSecureStorageInterface_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_13 extends _i1.SmartFake + implements _i15.CoinServiceAPI { + _FakeCoinServiceAPI_13( Object parent, Invocation parentInvocation, ) : super( @@ -179,7 +192,7 @@ class _FakeCoinServiceAPI_12 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i15.Wallets { +class MockWallets extends _i1.Mock implements _i16.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -246,7 +259,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i16.Coin? coin}) => + List<String> getWalletIdsFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -256,18 +269,18 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Coin, + returnValue: <_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i16.Coin? coin) => + _i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -331,17 +344,17 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( + _i18.Future<void> load(_i19.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> loadAfterStackRestore( - _i18.Prefs? prefs, + _i18.Future<void> loadAfterStackRestore( + _i19.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -352,11 +365,11 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { managers, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -364,7 +377,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -390,19 +403,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i18.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i18.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i17.Future<Map<String, _i2.WalletInfo>>); + ) as _i18.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<bool> renameWallet({ + _i18.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -417,13 +430,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> addExistingStackWallet({ + _i18.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -437,13 +450,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<String?> addNewWallet({ + _i18.Future<String?> addNewWallet({ required String? name, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -456,46 +469,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i18.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i18.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> moveFavorite({ + _i18.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -508,48 +521,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i18.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i18.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<bool> isMnemonicVerified({required String? walletId}) => + _i18.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> setMnemonicVerified({required String? walletId}) => + _i18.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> deleteWallet( + _i18.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -561,20 +574,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i18.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -582,7 +595,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -610,13 +623,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i17.Timer? _timer) => super.noSuchMethod( + set timer(_i18.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -693,59 +706,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i18.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<int> get chainHeight => (super.noSuchMethod( + _i18.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -834,26 +847,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i12.MainDB); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i20.DerivePathType addressType({required String? address}) => + _i23.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i20.DerivePathType.bip44, - ) as _i20.DerivePathType); + returnValue: _i23.DerivePathType.bip44, + ) as _i23.DerivePathType); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -870,47 +883,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i18.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i18.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i18.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -926,26 +939,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -963,33 +976,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -999,35 +1012,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i18.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i17.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i18.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i17.Future<_i9.ElectrumXNode>); + ) as _i18.Future<_i9.ElectrumXNode>); @override - _i17.Future<void> addDerivation({ + _i18.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1041,13 +1054,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addDerivations({ + _i18.Future<void> addDerivations({ required int? chain, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1060,50 +1073,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<List<Map<String, dynamic>>> fastFetch( + _i18.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i17.Future<List<Map<String, dynamic>>>.value( + returnValue: _i18.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i17.Future<List<Map<String, dynamic>>>); + ) as _i18.Future<List<Map<String, dynamic>>>); @override - _i17.Future<int> getTxCount({required String? address}) => + _i18.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i18.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> checkCurrentChangeAddressesForTransactions() => + _i18.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1127,7 +1140,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i21.UTXO>? utxos, + List<_i22.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1143,19 +1156,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, )); @override - _i17.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i21.UTXO>? utxosToUse) => + _i18.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i22.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<Map<String, dynamic>> buildTransaction({ - required List<_i21.UTXO>? utxosToUse, + _i18.Future<Map<String, dynamic>> buildTransaction({ + required List<_i22.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1172,10 +1185,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1187,11 +1200,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1203,8 +1216,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1223,25 +1236,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i18.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void initCache( String? walletId, - _i16.Coin? coin, + _i17.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1254,14 +1267,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i18.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1271,14 +1284,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i18.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1288,15 +1301,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i18.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1312,15 +1325,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1336,15 +1349,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1354,6 +1367,49 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i22.Address>? myAddresses, + _i17.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>.value(_FakeTuple4_11<_i22.Transaction, + List<_i22.Output>, List<_i22.Input>, _i22.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>); } /// A class which mocks [NodeService]. @@ -1361,41 +1417,41 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { /// See the documentation for Mockito's code generation for more information. class MockNodeService extends _i1.Mock implements _i3.NodeService { @override - _i13.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i14.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_11( + returnValue: _FakeSecureStorageInterface_12( this, Invocation.getter(#secureStorageInterface), ), - ) as _i13.SecureStorageInterface); + ) as _i14.SecureStorageInterface); @override - List<_i22.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i24.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - List<_i22.NodeModel> get nodes => (super.noSuchMethod( + List<_i24.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateDefaults() => (super.noSuchMethod( + _i18.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setPrimaryNodeFor({ - required _i16.Coin? coin, - required _i22.NodeModel? node, + _i18.Future<void> setPrimaryNodeFor({ + required _i17.Coin? coin, + required _i24.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -1408,44 +1464,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i22.NodeModel? getPrimaryNodeFor({required _i16.Coin? coin}) => + _i24.NodeModel? getPrimaryNodeFor({required _i17.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i22.NodeModel?); + )) as _i24.NodeModel?); @override - List<_i22.NodeModel> getNodesFor(_i16.Coin? coin) => (super.noSuchMethod( + List<_i24.NodeModel> getNodesFor(_i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - _i22.NodeModel? getNodeById({required String? id}) => + _i24.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i22.NodeModel?); + )) as _i24.NodeModel?); @override - List<_i22.NodeModel> failoverNodesFor({required _i16.Coin? coin}) => + List<_i24.NodeModel> failoverNodesFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - _i17.Future<void> add( - _i22.NodeModel? node, + _i18.Future<void> add( + _i24.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -1458,11 +1514,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> delete( + _i18.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -1474,11 +1530,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setEnabledState( + _i18.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -1492,12 +1548,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> edit( - _i22.NodeModel? editedNode, + _i18.Future<void> edit( + _i24.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -1510,20 +1566,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i18.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1531,7 +1587,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1574,23 +1630,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i14.CoinServiceAPI get wallet => (super.noSuchMethod( + _i15.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_12( + returnValue: _FakeCoinServiceAPI_13( this, Invocation.getter(#wallet), ), - ) as _i14.CoinServiceAPI); + ) as _i15.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1623,23 +1679,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1649,16 +1705,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1678,10 +1734,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -1693,19 +1749,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1715,7 +1776,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1731,27 +1792,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1761,33 +1822,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1804,20 +1865,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i18.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1829,11 +1890,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1845,18 +1906,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1864,7 +1925,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1884,7 +1945,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i15.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1895,10 +1956,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1931,23 +1992,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1957,16 +2018,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1986,10 +2047,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2006,7 +2067,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: 0, ) as int); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2022,36 +2083,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2061,15 +2122,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2086,38 +2147,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2129,11 +2190,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2145,24 +2206,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); } 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 3e88ef129..f510bde29 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 @@ -3,8 +3,8 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i17; -import 'dart:ui' as _i19; +import 'dart:async' as _i18; +import 'dart:ui' as _i20; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -13,21 +13,23 @@ import 'package:stackwallet/db/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21; -import 'package:stackwallet/models/node_model.dart' as _i22; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i22; +import 'package:stackwallet/models/node_model.dart' as _i24; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i20; -import 'package:stackwallet/services/coins/coin_service.dart' as _i14; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i21; +import 'package:stackwallet/services/coins/coin_service.dart' as _i15; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i15; +import 'package:stackwallet/services/wallets.dart' as _i16; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i16; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i23; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i13; -import 'package:stackwallet/utilities/prefs.dart' as _i18; + as _i14; +import 'package:stackwallet/utilities/prefs.dart' as _i19; +import 'package:tuple/tuple.dart' as _i13; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -154,9 +156,9 @@ class _FakeElectrumXNode_10 extends _i1.SmartFake implements _i9.ElectrumXNode { ); } -class _FakeSecureStorageInterface_11 extends _i1.SmartFake - implements _i13.SecureStorageInterface { - _FakeSecureStorageInterface_11( +class _FakeTuple4_11<T1, T2, T3, T4> extends _i1.SmartFake + implements _i13.Tuple4<T1, T2, T3, T4> { + _FakeTuple4_11( Object parent, Invocation parentInvocation, ) : super( @@ -165,9 +167,20 @@ class _FakeSecureStorageInterface_11 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_12 extends _i1.SmartFake - implements _i14.CoinServiceAPI { - _FakeCoinServiceAPI_12( +class _FakeSecureStorageInterface_12 extends _i1.SmartFake + implements _i14.SecureStorageInterface { + _FakeSecureStorageInterface_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_13 extends _i1.SmartFake + implements _i15.CoinServiceAPI { + _FakeCoinServiceAPI_13( Object parent, Invocation parentInvocation, ) : super( @@ -179,7 +192,7 @@ class _FakeCoinServiceAPI_12 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i15.Wallets { +class MockWallets extends _i1.Mock implements _i16.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -246,7 +259,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i16.Coin? coin}) => + List<String> getWalletIdsFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -256,18 +269,18 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValue: <String>[], ) as List<String>); @override - Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> + Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Coin, + returnValue: <_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>{}, - ) as Map<_i16.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); + ) as Map<_i17.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i16.Coin? coin) => + _i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -331,17 +344,17 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - _i17.Future<void> load(_i18.Prefs? prefs) => (super.noSuchMethod( + _i18.Future<void> load(_i19.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> loadAfterStackRestore( - _i18.Prefs? prefs, + _i18.Future<void> loadAfterStackRestore( + _i19.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -352,11 +365,11 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { managers, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -364,7 +377,7 @@ class MockWallets extends _i1.Mock implements _i15.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -390,19 +403,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i17.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i18.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i17.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i18.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i17.Future<Map<String, _i2.WalletInfo>>); + ) as _i18.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<bool> renameWallet({ + _i18.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -417,13 +430,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> addExistingStackWallet({ + _i18.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -437,13 +450,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<String?> addNewWallet({ + _i18.Future<String?> addNewWallet({ required String? name, - required _i16.Coin? coin, + required _i17.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -456,46 +469,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i18.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i18.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i18.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> moveFavorite({ + _i18.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -508,48 +521,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i18.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i18.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i17.Future<String?>.value(), - ) as _i17.Future<String?>); + returnValue: _i18.Future<String?>.value(), + ) as _i18.Future<String?>); @override - _i17.Future<bool> isMnemonicVerified({required String? walletId}) => + _i18.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> setMnemonicVerified({required String? walletId}) => + _i18.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> deleteWallet( + _i18.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -561,20 +574,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i18.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -582,7 +595,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -610,13 +623,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i21.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i17.Timer? _timer) => super.noSuchMethod( + set timer(_i18.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -693,59 +706,59 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i18.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override - _i17.Future<int> get chainHeight => (super.noSuchMethod( + _i18.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -834,26 +847,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i12.MainDB); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i20.DerivePathType addressType({required String? address}) => + _i23.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i20.DerivePathType.bip44, - ) as _i20.DerivePathType); + returnValue: _i23.DerivePathType.bip44, + ) as _i23.DerivePathType); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -870,47 +883,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i18.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i18.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i18.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -926,26 +939,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -963,33 +976,33 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -999,35 +1012,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i18.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i17.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( + returnValue: _i18.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_10( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i17.Future<_i9.ElectrumXNode>); + ) as _i18.Future<_i9.ElectrumXNode>); @override - _i17.Future<void> addDerivation({ + _i18.Future<void> addDerivation({ required int? chain, required String? address, required String? pubKey, required String? wif, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, }) => (super.noSuchMethod( Invocation.method( @@ -1041,13 +1054,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivePathType: derivePathType, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> addDerivations({ + _i18.Future<void> addDerivations({ required int? chain, - required _i20.DerivePathType? derivePathType, + required _i23.DerivePathType? derivePathType, required Map<String, dynamic>? derivationsToAdd, }) => (super.noSuchMethod( @@ -1060,50 +1073,50 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { #derivationsToAdd: derivationsToAdd, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<List<Map<String, dynamic>>> fastFetch( + _i18.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i17.Future<List<Map<String, dynamic>>>.value( + returnValue: _i18.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i17.Future<List<Map<String, dynamic>>>); + ) as _i18.Future<List<Map<String, dynamic>>>); @override - _i17.Future<int> getTxCount({required String? address}) => + _i18.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i18.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> checkCurrentChangeAddressesForTransactions() => + _i18.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1127,7 +1140,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { String? _recipientAddress, bool? isSendAll, { int? additionalOutputs = 0, - List<_i21.UTXO>? utxos, + List<_i22.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1143,19 +1156,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, )); @override - _i17.Future<Map<String, dynamic>> fetchBuildTxData( - List<_i21.UTXO>? utxosToUse) => + _i18.Future<Map<String, dynamic>> fetchBuildTxData( + List<_i22.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<Map<String, dynamic>> buildTransaction({ - required List<_i21.UTXO>? utxosToUse, + _i18.Future<Map<String, dynamic>> buildTransaction({ + required List<_i22.UTXO>? utxosToUse, required Map<String, dynamic>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, @@ -1172,10 +1185,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1187,11 +1200,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1203,8 +1216,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override int roughFeeEstimate( int? inputCount, @@ -1223,25 +1236,25 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( + _i18.Future<int> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override void initCache( String? walletId, - _i16.Coin? coin, + _i17.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1254,14 +1267,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i17.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i18.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1271,14 +1284,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: 0, ) as int); @override - _i17.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i18.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1288,15 +1301,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { returnValue: false, ) as bool); @override - _i17.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i18.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1312,15 +1325,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1336,15 +1349,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), ) as _i11.Balance); @override - _i17.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i18.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1354,6 +1367,49 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { ), returnValueForMissingStub: null, ); + @override + _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>> parseTransaction( + Map<String, dynamic>? txData, + dynamic electrumxClient, + List<_i22.Address>? myAddresses, + _i17.Coin? coin, + int? minConfirms, + String? walletId, + ) => + (super.noSuchMethod( + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + returnValue: _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>.value(_FakeTuple4_11<_i22.Transaction, + List<_i22.Output>, List<_i22.Input>, _i22.Address>( + this, + Invocation.method( + #parseTransaction, + [ + txData, + electrumxClient, + myAddresses, + coin, + minConfirms, + walletId, + ], + ), + )), + ) as _i18.Future< + _i13.Tuple4<_i22.Transaction, List<_i22.Output>, List<_i22.Input>, + _i22.Address>>); } /// A class which mocks [NodeService]. @@ -1361,41 +1417,41 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet { /// See the documentation for Mockito's code generation for more information. class MockNodeService extends _i1.Mock implements _i3.NodeService { @override - _i13.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i14.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_11( + returnValue: _FakeSecureStorageInterface_12( this, Invocation.getter(#secureStorageInterface), ), - ) as _i13.SecureStorageInterface); + ) as _i14.SecureStorageInterface); @override - List<_i22.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i24.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - List<_i22.NodeModel> get nodes => (super.noSuchMethod( + List<_i24.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateDefaults() => (super.noSuchMethod( + _i18.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setPrimaryNodeFor({ - required _i16.Coin? coin, - required _i22.NodeModel? node, + _i18.Future<void> setPrimaryNodeFor({ + required _i17.Coin? coin, + required _i24.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -1408,44 +1464,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i22.NodeModel? getPrimaryNodeFor({required _i16.Coin? coin}) => + _i24.NodeModel? getPrimaryNodeFor({required _i17.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i22.NodeModel?); + )) as _i24.NodeModel?); @override - List<_i22.NodeModel> getNodesFor(_i16.Coin? coin) => (super.noSuchMethod( + List<_i24.NodeModel> getNodesFor(_i17.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - _i22.NodeModel? getNodeById({required String? id}) => + _i24.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i22.NodeModel?); + )) as _i24.NodeModel?); @override - List<_i22.NodeModel> failoverNodesFor({required _i16.Coin? coin}) => + List<_i24.NodeModel> failoverNodesFor({required _i17.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i22.NodeModel>[], - ) as List<_i22.NodeModel>); + returnValue: <_i24.NodeModel>[], + ) as List<_i24.NodeModel>); @override - _i17.Future<void> add( - _i22.NodeModel? node, + _i18.Future<void> add( + _i24.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -1458,11 +1514,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> delete( + _i18.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -1474,11 +1530,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> setEnabledState( + _i18.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -1492,12 +1548,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> edit( - _i22.NodeModel? editedNode, + _i18.Future<void> edit( + _i24.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -1510,20 +1566,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i18.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1531,7 +1587,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1574,23 +1630,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i14.CoinServiceAPI get wallet => (super.noSuchMethod( + _i15.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_12( + returnValue: _FakeCoinServiceAPI_13( this, Invocation.getter(#wallet), ), - ) as _i14.CoinServiceAPI); + ) as _i15.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1623,23 +1679,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1649,16 +1705,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1678,10 +1734,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -1693,19 +1749,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: 0, ) as int); @override + bool get hasPaynymSupport => (super.noSuchMethod( + Invocation.getter(#hasPaynymSupport), + returnValue: false, + ) as bool); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -1715,7 +1776,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -1731,27 +1792,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1761,33 +1822,33 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1804,20 +1865,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i18.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1829,11 +1890,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -1845,18 +1906,18 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1864,7 +1925,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i19.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i20.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1884,7 +1945,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i15.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1895,10 +1956,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i16.Coin get coin => (super.noSuchMethod( + _i17.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i16.Coin.bitcoin, - ) as _i16.Coin); + returnValue: _i17.Coin.bitcoin, + ) as _i17.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -1931,23 +1992,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i17.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i18.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i17.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i18.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i17.Future<_i8.FeeObject>); + ) as _i18.Future<_i8.FeeObject>); @override - _i17.Future<int> get maxFee => (super.noSuchMethod( + _i18.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i18.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -1957,16 +2018,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { ), ) as _i11.Balance); @override - _i17.Future<List<_i21.Transaction>> get transactions => (super.noSuchMethod( + _i18.Future<List<_i22.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i17.Future<List<_i21.Transaction>>.value(<_i21.Transaction>[]), - ) as _i17.Future<List<_i21.Transaction>>); + _i18.Future<List<_i22.Transaction>>.value(<_i22.Transaction>[]), + ) as _i18.Future<List<_i22.Transaction>>); @override - _i17.Future<List<_i21.UTXO>> get utxos => (super.noSuchMethod( + _i18.Future<List<_i22.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i17.Future<List<_i21.UTXO>>.value(<_i21.UTXO>[]), - ) as _i17.Future<List<_i21.UTXO>>); + returnValue: _i18.Future<List<_i22.UTXO>>.value(<_i22.UTXO>[]), + ) as _i18.Future<List<_i22.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -1986,10 +2047,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: '', ) as String); @override - _i17.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i18.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i17.Future<List<String>>.value(<String>[]), - ) as _i17.Future<List<String>>); + returnValue: _i18.Future<List<String>>.value(<String>[]), + ) as _i18.Future<List<String>>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2006,7 +2067,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: 0, ) as int); @override - _i17.Future<Map<String, dynamic>> prepareSend({ + _i18.Future<Map<String, dynamic>> prepareSend({ required String? address, required int? satoshiAmount, Map<String, dynamic>? args, @@ -2022,36 +2083,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { }, ), returnValue: - _i17.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i17.Future<Map<String, dynamic>>); + _i18.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i18.Future<Map<String, dynamic>>); @override - _i17.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i18.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i17.Future<String>.value(''), - ) as _i17.Future<String>); + returnValue: _i18.Future<String>.value(''), + ) as _i18.Future<String>); @override - _i17.Future<void> refresh() => (super.noSuchMethod( + _i18.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i18.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2061,15 +2122,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { returnValue: false, ) as bool); @override - _i17.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i18.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> recoverFromMnemonic({ + _i18.Future<void> recoverFromMnemonic({ required String? mnemonic, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2086,38 +2147,38 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { #height: height, }, ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeNew() => (super.noSuchMethod( + _i18.Future<void> initializeNew() => (super.noSuchMethod( Invocation.method( #initializeNew, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> initializeExisting() => (super.noSuchMethod( + _i18.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> exit() => (super.noSuchMethod( + _i18.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<void> fullRescan( + _i18.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2129,11 +2190,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); @override - _i17.Future<int> estimateFeeFor( + _i18.Future<int> estimateFeeFor( int? satoshiAmount, int? feeRate, ) => @@ -2145,24 +2206,24 @@ class MockCoinServiceAPI extends _i1.Mock implements _i14.CoinServiceAPI { feeRate, ], ), - returnValue: _i17.Future<int>.value(0), - ) as _i17.Future<int>); + returnValue: _i18.Future<int>.value(0), + ) as _i18.Future<int>); @override - _i17.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i18.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i17.Future<bool>.value(false), - ) as _i17.Future<bool>); + returnValue: _i18.Future<bool>.value(false), + ) as _i18.Future<bool>); @override - _i17.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i18.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i17.Future<void>.value(), - returnValueForMissingStub: _i17.Future<void>.value(), - ) as _i17.Future<void>); + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); } diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 98655fe05..e265edffe 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -11,6 +11,7 @@ #include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h> #include <isar_flutter_libs/isar_flutter_libs_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h> +#include <share_plus/share_plus_windows_plugin_c_api.h> #include <stack_wallet_backup/stack_wallet_backup_plugin_c_api.h> #include <url_launcher_windows/url_launcher_windows.h> #include <window_size/window_size_plugin.h> @@ -26,6 +27,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin")); PermissionHandlerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); + SharePlusWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); StackWalletBackupPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("StackWalletBackupPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 4426d9497..6a4a3acbf 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -8,6 +8,7 @@ list(APPEND FLUTTER_PLUGIN_LIST flutter_secure_storage_windows isar_flutter_libs permission_handler_windows + share_plus stack_wallet_backup url_launcher_windows window_size