From 60ff3ebf6fc93c565bdbf9fab3c198595890c4e2 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 7 Oct 2022 10:04:56 -0600
Subject: [PATCH 001/426] color doesn't change on hover

---
 lib/utilities/theme/stack_colors.dart | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/utilities/theme/stack_colors.dart b/lib/utilities/theme/stack_colors.dart
index 7790a9f82..c5aaac8c0 100644
--- a/lib/utilities/theme/stack_colors.dart
+++ b/lib/utilities/theme/stack_colors.dart
@@ -1507,5 +1507,8 @@ class StackColors extends ThemeExtension<StackColors> {
             backgroundColor: MaterialStateProperty.all<Color>(
               background,
             ),
+            overlayColor: MaterialStateProperty.all<Color>(
+              Colors.transparent,
+            ),
           );
 }

From 82377f694a5996d28094f0d15e923b2d5ba1701e Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 12 Oct 2022 11:31:24 -0600
Subject: [PATCH 002/426] some layout fixes

---
 lib/pages/stack_privacy_calls.dart | 43 +++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 15 deletions(-)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index 841dacf9e..e50bcb7d2 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -1,20 +1,18 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_views/advanced_settings_view.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/prefs.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import 'package:stackwallet/providers/global/prefs_provider.dart';
-import 'package:stackwallet/utilities/prefs.dart';
-
 class StackPrivacyCalls extends ConsumerStatefulWidget {
   const StackPrivacyCalls({
     Key? key,
@@ -194,6 +192,7 @@ class _PrivacyToggleState extends ConsumerState<PrivacyToggle> {
       children: [
         Expanded(
           child: RawMaterialButton(
+            elevation: 0,
             fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
             shape: RoundedRectangleBorder(
               side: !ref.watch(
@@ -224,10 +223,13 @@ class _PrivacyToggleState extends ConsumerState<PrivacyToggle> {
                   Column(
                     crossAxisAlignment: CrossAxisAlignment.stretch,
                     children: [
-                      SvgPicture.asset(
-                        Assets.svg.personaEasy,
-                        width: 140,
-                        height: 140,
+                      Padding(
+                        padding: const EdgeInsets.all(16.0),
+                        child: SvgPicture.asset(
+                          Assets.svg.personaEasy,
+                          width: 140,
+                          height: 140,
+                        ),
                       ),
                       Center(
                           child: Text(
@@ -321,10 +323,13 @@ class _PrivacyToggleState extends ConsumerState<PrivacyToggle> {
                   Column(
                     crossAxisAlignment: CrossAxisAlignment.stretch,
                     children: [
-                      SvgPicture.asset(
-                        Assets.svg.personaIncognito,
-                        width: 140,
-                        height: 140,
+                      Padding(
+                        padding: const EdgeInsets.all(16.0),
+                        child: SvgPicture.asset(
+                          Assets.svg.personaIncognito,
+                          width: 140,
+                          height: 140,
+                        ),
                       ),
                       Center(
                         child: Text(
@@ -434,9 +439,17 @@ class ContinueButton extends StatelessWidget {
 
                 Prefs.instance.externalCalls = isEasy;
 
-                if (!isSettings) {
-                  Navigator.of(context).pushNamed(CreatePinView.routeName);
-                }
+                !isSettings
+                    ? Navigator.of(context).pushNamed(CreatePinView.routeName)
+                    : Navigator.of(context)
+                        .pushNamed(AdvancedSettingsView.routeName);
+
+                // if (!isSettings) {
+                //   Navigator.of(context).pushNamed(CreatePinView.routeName);
+                // }
+                // if (isSettings) {
+                //   Navigator.of(context).pop();
+                // }
               },
               child: Text(
                 !isSettings ? "Continue" : "Save changes",

From b7d5dfc32e97da120d8efcb65033882a763c9a6c Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 13 Oct 2022 10:00:00 -0600
Subject: [PATCH 003/426] continue button pushes CreatePasswordView for desktop

---
 lib/pages/stack_privacy_calls.dart | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index e50bcb7d2..e68045311 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_views/advanced_settings_view.dart';
+import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -418,7 +419,7 @@ class ContinueButton extends StatelessWidget {
 
               Prefs.instance.externalCalls = isEasy;
               if (!isSettings) {
-                Navigator.of(context).pushNamed(CreatePinView.routeName);
+                Navigator.of(context).pushNamed(CreatePasswordView.routeName);
               }
             },
             child: Text(

From 3f9111faacfd56390ea9644fdfc7f5d04f7e81d1 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 13 Oct 2022 11:55:04 -0600
Subject: [PATCH 004/426] added keys to const desktop views

---
 lib/pages_desktop_specific/home/desktop_home_view.dart | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index 4ca78894b..12c4b1e8e 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -19,6 +19,7 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
   int currentViewIndex = 0;
   final List<Widget> contentViews = [
     const Navigator(
+      key: Key("desktopStackHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: MyStackView.routeName,
     ),
@@ -32,6 +33,7 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
       color: Colors.orange,
     ),
     const Navigator(
+      key: Key("desktopSettingHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: SettingsMenu.routeName,
     ),

From 7e6edd4dab91da6e99a376491d85b38c60a6dfdd Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 13 Oct 2022 13:07:48 -0600
Subject: [PATCH 005/426] desktop basic wallet layout ui

---
 .../my_stack_view/coin_wallets_table.dart     |   7 +
 .../wallet_view/desktop_wallet_view.dart      | 294 ++++++++++++++++++
 lib/route_generator.dart                      |  15 +
 .../wallet_info_row/wallet_info_row.dart      |  70 +++--
 4 files changed, 355 insertions(+), 31 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart b/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart
index 64e4a23d3..b16a9bc58 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart';
@@ -37,6 +38,12 @@ class CoinWalletsTable extends ConsumerWidget {
                     ),
                   WalletInfoRow(
                     walletId: walletIds[i],
+                    onPressed: () async {
+                      await Navigator.of(context).pushNamed(
+                        DesktopWalletView.routeName,
+                        arguments: walletIds[i],
+                      );
+                    },
                   ),
                 ],
               ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
new file mode 100644
index 000000000..785b94dc4
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -0,0 +1,294 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+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/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class DesktopWalletView extends ConsumerStatefulWidget {
+  const DesktopWalletView({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  static const String routeName = "/desktopWalletView";
+
+  final String walletId;
+
+  @override
+  ConsumerState<DesktopWalletView> createState() => _DesktopWalletViewState();
+}
+
+class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
+  late final String walletId;
+
+  Future<void> onBackPressed() async {
+    // TODO log out and close wallet before popping back
+    Navigator.of(context).pop();
+  }
+
+  @override
+  void initState() {
+    walletId = widget.walletId;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final manager = ref.watch(walletsChangeNotifierProvider
+        .select((value) => value.getManager(walletId)));
+    final coin = manager.coin;
+
+    return DesktopScaffold(
+      appBar: DesktopAppBar(
+        background: Theme.of(context).extension<StackColors>()!.popupBG,
+        leading: Row(
+          children: [
+            const SizedBox(
+              width: 32,
+            ),
+            AppBarIconButton(
+              size: 32,
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .textFieldDefaultBG,
+              shadows: const [],
+              icon: SvgPicture.asset(
+                Assets.svg.arrowLeft,
+                width: 18,
+                height: 18,
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .topNavIconPrimary,
+              ),
+              onPressed: onBackPressed,
+            ),
+            const SizedBox(
+              width: 15,
+            ),
+            SvgPicture.asset(
+              Assets.svg.iconFor(coin: coin),
+              width: 32,
+              height: 32,
+            ),
+            const SizedBox(
+              width: 12,
+            ),
+            Text(
+              manager.walletName,
+              style: STextStyles.desktopH3(context),
+            ),
+          ],
+        ),
+        trailing: Row(
+          children: const [
+            NetworkInfoButton(),
+            SizedBox(
+              width: 12,
+            ),
+            WalletKeysButton(),
+            SizedBox(
+              width: 32,
+            ),
+          ],
+        ),
+        isCompactHeight: true,
+      ),
+      body: Padding(
+        padding: const EdgeInsets.all(24),
+        child: Column(
+          children: [
+            RoundedWhiteContainer(
+              padding: const EdgeInsets.all(20),
+              child: Row(
+                children: [
+                  SvgPicture.asset(
+                    Assets.svg.iconFor(coin: coin),
+                    width: 40,
+                    height: 40,
+                  ),
+                  const SizedBox(
+                    width: 10,
+                  ),
+                  Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Row(
+                        children: [
+                          Text(
+                            "TODO: balance",
+                            style: STextStyles.desktopH3(context),
+                          ),
+                          const SizedBox(
+                            width: 8,
+                          ),
+                          Container(
+                            color: Colors.red,
+                            width: 20,
+                            height: 20,
+                          ),
+                        ],
+                      ),
+                      Text(
+                        "todo: fiat balance",
+                        style:
+                            STextStyles.desktopTextExtraSmall(context).copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textSubtitle1,
+                        ),
+                      )
+                    ],
+                  ),
+                  const Spacer(),
+                  SecondaryButton(
+                    width: 180,
+                    height: 56,
+                    onPressed: () {
+                      // todo: go to wallet initiated exchange
+                    },
+                    label: "Exchange",
+                    icon: Container(
+                      color: Colors.red,
+                      width: 20,
+                      height: 20,
+                    ),
+                  )
+                ],
+              ),
+            ),
+            const SizedBox(
+              height: 24,
+            ),
+            Expanded(
+              child: Row(
+                children: const [
+                  Expanded(
+                    child: MyWallet(),
+                  ),
+                  SizedBox(
+                    width: 16,
+                  ),
+                  Expanded(
+                    child: RecentDesktopTransactions(),
+                  ),
+                ],
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class MyWallet extends StatefulWidget {
+  const MyWallet({Key? key}) : super(key: key);
+
+  @override
+  State<MyWallet> createState() => _MyWalletState();
+}
+
+class _MyWalletState extends State<MyWallet> {
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Text(
+          "My wallet",
+          style: STextStyles.desktopTextExtraSmall(context).copyWith(
+            color: Theme.of(context)
+                .extension<StackColors>()!
+                .textFieldActiveSearchIconLeft,
+          ),
+        ),
+        const SizedBox(
+          height: 16,
+        ),
+        Expanded(
+          child: RoundedWhiteContainer(
+            padding: const EdgeInsets.all(0),
+            child: Container(),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class RecentDesktopTransactions extends StatefulWidget {
+  const RecentDesktopTransactions({Key? key}) : super(key: key);
+
+  @override
+  State<RecentDesktopTransactions> createState() =>
+      _RecentDesktopTransactionsState();
+}
+
+class _RecentDesktopTransactionsState extends State<RecentDesktopTransactions> {
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: [
+            Text(
+              "Recent transactions",
+              style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldActiveSearchIconLeft,
+              ),
+            ),
+            BlueTextButton(
+              text: "See all",
+              onTap: () {
+                // todo: show all txns
+              },
+            ),
+          ],
+        ),
+        const SizedBox(
+          height: 16,
+        ),
+        Expanded(
+          child: RoundedWhiteContainer(
+            padding: const EdgeInsets.all(0),
+            child: Container(),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class NetworkInfoButton extends StatelessWidget {
+  const NetworkInfoButton({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      child: Text("todo: sync status"),
+    );
+  }
+}
+
+class WalletKeysButton extends StatelessWidget {
+  const WalletKeysButton({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      child: Text("todo: wallet keys"),
+    );
+  }
+}
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 834432a69..b4ca9ef92 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -86,6 +86,7 @@ import 'package:stackwallet/pages_desktop_specific/create_password/create_passwo
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
@@ -969,6 +970,20 @@ class RouteGenerator {
             builder: (_) => const MyStackView(),
             settings: RouteSettings(name: settings.name));
 
+      case DesktopWalletView.routeName:
+        if (args is String) {
+          return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => DesktopWalletView(
+              walletId: args,
+            ),
+            settings: RouteSettings(
+              name: settings.name,
+            ),
+          );
+        }
+        return _routeError("${settings.name} invalid args: ${args.toString()}");
+
       case SettingsMenu.routeName:
         return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
diff --git a/lib/widgets/wallet_info_row/wallet_info_row.dart b/lib/widgets/wallet_info_row/wallet_info_row.dart
index 4840e9b01..d5e42e814 100644
--- a/lib/widgets/wallet_info_row/wallet_info_row.dart
+++ b/lib/widgets/wallet_info_row/wallet_info_row.dart
@@ -25,9 +25,13 @@ class WalletInfoRow extends ConsumerWidget {
         .watch(walletsChangeNotifierProvider.notifier)
         .getManagerProvider(walletId));
 
-    return Row(
-      children: Util.isDesktop
-          ? [
+    if (Util.isDesktop) {
+      return GestureDetector(
+        onTap: onPressed,
+        child: Container(
+          color: Colors.transparent,
+          child: Row(
+            children: [
               Expanded(
                 flex: 4,
                 child: Row(
@@ -38,11 +42,9 @@ class WalletInfoRow extends ConsumerWidget {
                     ),
                     Text(
                       manager.walletName,
-                      style:
-                          STextStyles.desktopTextExtraSmall(context).copyWith(
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textDark,
+                      style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color:
+                            Theme.of(context).extension<StackColors>()!.textDark,
                       ),
                     ),
                   ],
@@ -70,29 +72,35 @@ class WalletInfoRow extends ConsumerWidget {
                   ],
                 ),
               )
-            ]
-          : [
-              WalletInfoCoinIcon(coin: manager.coin),
-              const SizedBox(
-                width: 12,
-              ),
-              Expanded(
-                child: Column(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
-                    Text(
-                      manager.walletName,
-                      style: STextStyles.titleBold12(context),
-                    ),
-                    const SizedBox(
-                      height: 2,
-                    ),
-                    WalletInfoRowBalanceFuture(walletId: walletId),
-                  ],
-                ),
-              ),
             ],
-    );
+          ),
+        ),
+      );
+    } else {
+      return Row(
+        children: [
+          WalletInfoCoinIcon(coin: manager.coin),
+          const SizedBox(
+            width: 12,
+          ),
+          Expanded(
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                Text(
+                  manager.walletName,
+                  style: STextStyles.titleBold12(context),
+                ),
+                const SizedBox(
+                  height: 2,
+                ),
+                WalletInfoRowBalanceFuture(walletId: walletId),
+              ],
+            ),
+          ),
+        ],
+      );
+    }
   }
 }

From 146135aad9bea0fbfd025b4af65d8e752ae9eb95 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 13 Oct 2022 13:10:24 -0600
Subject: [PATCH 006/426] main desktop view divider

---
 lib/pages_desktop_specific/home/desktop_home_view.dart | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index 12c4b1e8e..3941fc6de 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -63,6 +63,10 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
           DesktopMenu(
             onSelectionChanged: onMenuSelectionChanged,
           ),
+          Container(
+            width: 1,
+            color: Theme.of(context).extension<StackColors>()!.background,
+          ),
           Expanded(
             child: contentViews[currentViewIndex],
           ),

From 1157b5fd0f27b063a8727c5b4473e6380518ec14 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 13 Oct 2022 16:42:13 -0600
Subject: [PATCH 007/426] redid settings option layout and added first
 container

---
 .../home/settings_menu/settings_menu.dart     | 297 +++++++++---------
 1 file changed, 152 insertions(+), 145 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart b/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
index de800b51f..82b32be5b 100644
--- a/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
@@ -1,10 +1,12 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu_item.dart';
-import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+import '../../../utilities/assets.dart';
+import '../settings_menu_item.dart';
 
 class SettingsMenu extends ConsumerStatefulWidget {
   const SettingsMenu({
@@ -35,155 +37,160 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    return Material(
-      color: Theme.of(context).extension<StackColors>()!.background,
-      child: SizedBox(
-        width: 300,
-        child: Padding(
-          padding: const EdgeInsets.fromLTRB(24.0, 10.0, 0, 0),
-          child: Column(
-            crossAxisAlignment: CrossAxisAlignment.start,
+    return Column(
+      children: [
+        DesktopAppBar(
+          isCompactHeight: true,
+          leading: Row(
             children: [
-              SizedBox(
-                height: 20,
-                // width: 300,
+              const SizedBox(
+                width: 24,
+                height: 24,
               ),
               Text(
                 "Settings",
-                style: STextStyles.desktopH3(context).copyWith(
-                  fontSize: 24,
-                ),
-              ),
-              Row(
-                children: [
-                  Padding(
-                    padding: const EdgeInsets.fromLTRB(
-                      3.0,
-                      30.0,
-                      55.0,
-                      0,
-                    ),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        SettingsMenuItem(
-                          icon: SvgPicture.asset(
-                            Assets.svg.polygon,
-                            width: 11,
-                            height: 11,
-                          ),
-                          label: "Backup and restore",
-                          value: 0,
-                          group: selectedMenuItem,
-                          onChanged: updateSelectedMenuItem,
-                        ),
-                        const SizedBox(
-                          height: 2,
-                        ),
-                        SettingsMenuItem(
-                          icon: SvgPicture.asset(
-                            Assets.svg.polygon,
-                            width: 11,
-                            height: 11,
-                          ),
-                          label: "Security",
-                          value: 1,
-                          group: selectedMenuItem,
-                          onChanged: updateSelectedMenuItem,
-                        ),
-                        const SizedBox(
-                          height: 2,
-                        ),
-                        SettingsMenuItem(
-                          icon: SvgPicture.asset(
-                            Assets.svg.polygon,
-                            width: 11,
-                            height: 11,
-                          ),
-                          label: "Currency",
-                          value: 2,
-                          group: selectedMenuItem,
-                          onChanged: updateSelectedMenuItem,
-                        ),
-                        const SizedBox(
-                          height: 2,
-                        ),
-                        SettingsMenuItem(
-                          icon: SvgPicture.asset(
-                            Assets.svg.polygon,
-                            width: 11,
-                            height: 11,
-                          ),
-                          label: "Language",
-                          value: 3,
-                          group: selectedMenuItem,
-                          onChanged: updateSelectedMenuItem,
-                        ),
-                        const SizedBox(
-                          height: 2,
-                        ),
-                        SettingsMenuItem(
-                          icon: SvgPicture.asset(
-                            Assets.svg.polygon,
-                            width: 11,
-                            height: 11,
-                          ),
-                          label: "Nodes",
-                          value: 4,
-                          group: selectedMenuItem,
-                          onChanged: updateSelectedMenuItem,
-                        ),
-                        const SizedBox(
-                          height: 2,
-                        ),
-                        SettingsMenuItem(
-                          icon: SvgPicture.asset(
-                            Assets.svg.polygon,
-                            width: 11,
-                            height: 11,
-                          ),
-                          label: "Syncing preferences",
-                          value: 5,
-                          group: selectedMenuItem,
-                          onChanged: updateSelectedMenuItem,
-                        ),
-                        const SizedBox(
-                          height: 2,
-                        ),
-                        SettingsMenuItem(
-                          icon: SvgPicture.asset(
-                            Assets.svg.polygon,
-                            width: 11,
-                            height: 11,
-                          ),
-                          label: "Appearance",
-                          value: 6,
-                          group: selectedMenuItem,
-                          onChanged: updateSelectedMenuItem,
-                        ),
-                        const SizedBox(
-                          height: 2,
-                        ),
-                        SettingsMenuItem(
-                          icon: SvgPicture.asset(
-                            Assets.svg.polygon,
-                            width: 11,
-                            height: 11,
-                          ),
-                          label: "Advanced",
-                          value: 7,
-                          group: selectedMenuItem,
-                          onChanged: updateSelectedMenuItem,
-                        ),
-                      ],
-                    ),
-                  ),
-                ],
-              ),
+                style: STextStyles.desktopH3(context),
+              )
             ],
           ),
         ),
-      ),
+        Row(
+          children: [
+            Padding(
+              padding: const EdgeInsets.only(left: 15),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  SettingsMenuItem(
+                    icon: SvgPicture.asset(
+                      Assets.svg.polygon,
+                      width: 11,
+                      height: 11,
+                    ),
+                    label: "Backup and restore",
+                    value: 0,
+                    group: selectedMenuItem,
+                    onChanged: updateSelectedMenuItem,
+                  ),
+                  const SizedBox(
+                    height: 2,
+                  ),
+                  SettingsMenuItem(
+                    icon: SvgPicture.asset(
+                      Assets.svg.polygon,
+                      width: 11,
+                      height: 11,
+                    ),
+                    label: "Security",
+                    value: 1,
+                    group: selectedMenuItem,
+                    onChanged: updateSelectedMenuItem,
+                  ),
+                  const SizedBox(
+                    height: 2,
+                  ),
+                  SettingsMenuItem(
+                    icon: SvgPicture.asset(
+                      Assets.svg.polygon,
+                      width: 11,
+                      height: 11,
+                    ),
+                    label: "Currency",
+                    value: 2,
+                    group: selectedMenuItem,
+                    onChanged: updateSelectedMenuItem,
+                  ),
+                  const SizedBox(
+                    height: 2,
+                  ),
+                  SettingsMenuItem(
+                    icon: SvgPicture.asset(
+                      Assets.svg.polygon,
+                      width: 11,
+                      height: 11,
+                    ),
+                    label: "Language",
+                    value: 3,
+                    group: selectedMenuItem,
+                    onChanged: updateSelectedMenuItem,
+                  ),
+                  const SizedBox(
+                    height: 2,
+                  ),
+                  SettingsMenuItem(
+                    icon: SvgPicture.asset(
+                      Assets.svg.polygon,
+                      width: 11,
+                      height: 11,
+                    ),
+                    label: "Nodes",
+                    value: 4,
+                    group: selectedMenuItem,
+                    onChanged: updateSelectedMenuItem,
+                  ),
+                  const SizedBox(
+                    height: 2,
+                  ),
+                  SettingsMenuItem(
+                    icon: SvgPicture.asset(
+                      Assets.svg.polygon,
+                      width: 11,
+                      height: 11,
+                    ),
+                    label: "Syncing preferences",
+                    value: 5,
+                    group: selectedMenuItem,
+                    onChanged: updateSelectedMenuItem,
+                  ),
+                  const SizedBox(
+                    height: 2,
+                  ),
+                  SettingsMenuItem(
+                    icon: SvgPicture.asset(
+                      Assets.svg.polygon,
+                      width: 11,
+                      height: 11,
+                    ),
+                    label: "Appearance",
+                    value: 6,
+                    group: selectedMenuItem,
+                    onChanged: updateSelectedMenuItem,
+                  ),
+                  const SizedBox(
+                    height: 2,
+                  ),
+                  SettingsMenuItem(
+                    icon: SvgPicture.asset(
+                      Assets.svg.polygon,
+                      width: 11,
+                      height: 11,
+                    ),
+                    label: "Advanced",
+                    value: 7,
+                    group: selectedMenuItem,
+                    onChanged: updateSelectedMenuItem,
+                  ),
+                ],
+              ),
+            ),
+            Expanded(
+              child: Padding(
+                padding: const EdgeInsets.only(
+                  left: 10,
+                  right: 40,
+                ),
+                child: RoundedWhiteContainer(
+                  child: SvgPicture.asset(
+                    Assets.svg.backupAuto,
+                    width: 48,
+                    height: 48,
+                  ),
+                ),
+              ),
+            )
+          ],
+        ),
+      ],
     );
   }
 }

From d06219d3d978613378b3a7f47ff34ec2ea42c938 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 13 Oct 2022 16:42:47 -0600
Subject: [PATCH 008/426] added small text

---
 lib/utilities/text_styles.dart | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart
index c3a6929fe..8175cbde8 100644
--- a/lib/utilities/text_styles.dart
+++ b/lib/utilities/text_styles.dart
@@ -679,6 +679,25 @@ class STextStyles {
     }
   }
 
+  static TextStyle desktopTextSmall(BuildContext context) {
+    switch (_theme(context).themeType) {
+      case ThemeType.light:
+        return GoogleFonts.inter(
+          color: _theme(context).buttonTextPrimaryDisabled,
+          fontWeight: FontWeight.w500,
+          fontSize: 18,
+          height: 27 / 18,
+        );
+      case ThemeType.dark:
+        return GoogleFonts.inter(
+          color: _theme(context).buttonTextPrimaryDisabled,
+          fontWeight: FontWeight.w500,
+          fontSize: 18,
+          height: 27 / 18,
+        );
+    }
+  }
+
   static TextStyle desktopTextExtraSmall(BuildContext context) {
     switch (_theme(context).themeType) {
       case ThemeType.light:

From 8116b267c1c60c9aeee4f8c1f83f0ae981f8dfeb Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 14 Oct 2022 10:49:46 -0600
Subject: [PATCH 009/426] desktop wallet send/receive tabview

---
 .../wallet_view/desktop_wallet_view.dart      | 73 ++++++++++++++++++-
 1 file changed, 72 insertions(+), 1 deletion(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 785b94dc4..f8cc7e2dc 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.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/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -217,7 +218,45 @@ class _MyWalletState extends State<MyWallet> {
         Expanded(
           child: RoundedWhiteContainer(
             padding: const EdgeInsets.all(0),
-            child: Container(),
+            child: DefaultTabController(
+              length: 2,
+              child: Column(
+                children: [
+                  TabBar(
+                    indicatorColor: Theme.of(context)
+                        .extension<StackColors>()!
+                        .accentColorBlue,
+                    labelStyle: STextStyles.desktopTextExtraSmall(context),
+                    labelColor: Theme.of(context)
+                        .extension<StackColors>()!
+                        .accentColorBlue,
+                    unselectedLabelColor: Theme.of(context)
+                        .extension<StackColors>()!
+                        .textSubtitle1,
+                    labelPadding: const EdgeInsets.symmetric(
+                      vertical: 6,
+                    ),
+                    splashBorderRadius: BorderRadius.vertical(
+                      top: Radius.circular(
+                        Constants.size.circularBorderRadius,
+                      ),
+                    ),
+                    tabs: const [
+                      Tab(text: "Send"),
+                      Tab(text: "Receive"),
+                    ],
+                  ),
+                  const Expanded(
+                    child: TabBarView(
+                      children: [
+                        DesktopSend(),
+                        DesktopReceive(),
+                      ],
+                    ),
+                  ),
+                ],
+              ),
+            ),
           ),
         ),
       ],
@@ -225,6 +264,38 @@ class _MyWalletState extends State<MyWallet> {
   }
 }
 
+class DesktopReceive extends StatefulWidget {
+  const DesktopReceive({Key? key}) : super(key: key);
+
+  @override
+  State<DesktopReceive> createState() => _DesktopReceiveState();
+}
+
+class _DesktopReceiveState extends State<DesktopReceive> {
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      color: Colors.green,
+    );
+  }
+}
+
+class DesktopSend extends StatefulWidget {
+  const DesktopSend({Key? key}) : super(key: key);
+
+  @override
+  State<DesktopSend> createState() => _DesktopSendState();
+}
+
+class _DesktopSendState extends State<DesktopSend> {
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      color: Colors.red,
+    );
+  }
+}
+
 class RecentDesktopTransactions extends StatefulWidget {
   const RecentDesktopTransactions({Key? key}) : super(key: key);
 

From 733c81bf90eec2a9c66f73b774bb0607a2343bc2 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 14 Oct 2022 13:28:43 -0600
Subject: [PATCH 010/426] save changes button fix

---
 lib/pages/stack_privacy_calls.dart | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index e68045311..eaf7d18d0 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
-import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_views/advanced_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -408,7 +407,7 @@ class ContinueButton extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return !isDesktop
+    return isDesktop
         ? TextButton(
             style: Theme.of(context)
                 .extension<StackColors>()!
@@ -442,15 +441,7 @@ class ContinueButton extends StatelessWidget {
 
                 !isSettings
                     ? Navigator.of(context).pushNamed(CreatePinView.routeName)
-                    : Navigator.of(context)
-                        .pushNamed(AdvancedSettingsView.routeName);
-
-                // if (!isSettings) {
-                //   Navigator.of(context).pushNamed(CreatePinView.routeName);
-                // }
-                // if (isSettings) {
-                //   Navigator.of(context).pop();
-                // }
+                    : Navigator.of(context).pop();
               },
               child: Text(
                 !isSettings ? "Continue" : "Save changes",

From b822519d588ea13f1cb172be9a11121deb227cf0 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 14 Oct 2022 13:40:44 -0600
Subject: [PATCH 011/426] default to easy mode and button size fix

---
 lib/pages/stack_privacy_calls.dart | 32 ++++++++++++++++--------------
 lib/utilities/prefs.dart           |  4 +++-
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index eaf7d18d0..bf0a9fddb 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -393,21 +393,21 @@ class _PrivacyToggleState extends ConsumerState<PrivacyToggle> {
   }
 }
 
-class ContinueButton extends StatelessWidget {
-  const ContinueButton(
-      {Key? key,
-      required this.isDesktop,
-      required this.isSettings,
-      required this.isEasy})
-      : super(key: key);
+class ContinueButton extends ConsumerWidget {
+  const ContinueButton({
+    Key? key,
+    required this.isDesktop,
+    required this.isSettings,
+    required this.isEasy,
+  }) : super(key: key);
 
   final bool isDesktop;
   final bool isSettings;
   final bool isEasy;
 
   @override
-  Widget build(BuildContext context) {
-    return isDesktop
+  Widget build(BuildContext context, WidgetRef ref) {
+    return !isDesktop
         ? TextButton(
             style: Theme.of(context)
                 .extension<StackColors>()!
@@ -416,10 +416,11 @@ class ContinueButton extends StatelessWidget {
               print("Output of isEasy:");
               print(isEasy);
 
-              Prefs.instance.externalCalls = isEasy;
-              if (!isSettings) {
-                Navigator.of(context).pushNamed(CreatePasswordView.routeName);
-              }
+              ref.read(prefsChangeNotifierProvider).externalCalls = isEasy;
+
+              !isSettings
+                  ? Navigator.of(context).pushNamed(CreatePinView.routeName)
+                  : Navigator.of(context).pop();
             },
             child: Text(
               !isSettings ? "Continue" : "Save changes",
@@ -437,10 +438,11 @@ class ContinueButton extends StatelessWidget {
                 print("Output of isEasy:");
                 print(isEasy);
 
-                Prefs.instance.externalCalls = isEasy;
+                ref.read(prefsChangeNotifierProvider).externalCalls = isEasy;
 
                 !isSettings
-                    ? Navigator.of(context).pushNamed(CreatePinView.routeName)
+                    ? Navigator.of(context)
+                        .pushNamed(CreatePasswordView.routeName)
                     : Navigator.of(context).pop();
               },
               child: Text(
diff --git a/lib/utilities/prefs.dart b/lib/utilities/prefs.dart
index 7e1096550..dc165d4b6 100644
--- a/lib/utilities/prefs.dart
+++ b/lib/utilities/prefs.dart
@@ -546,7 +546,9 @@ class Prefs extends ChangeNotifier {
         boxName: DB.boxNamePrefs, key: "startupWalletId") as String?;
   }
 
-  bool _externalCalls = false;
+  // incognito mode disabled
+
+  bool _externalCalls = true;
 
   bool get externalCalls => _externalCalls;
 

From 289f0b89597d7f5df29ae4b082d7684945c185ec Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 13 Oct 2022 22:13:42 -0500
Subject: [PATCH 012/426] Add mainnet tests for address generation from test
 mnemonic

TODO: Clean up the wallet file as the tests conclude
---
 .../coins/monero/monero_wallet_test.dart      | 207 ++++++++++++++++++
 .../coins/monero/monero_wallet_test_data.dart |  14 ++
 2 files changed, 221 insertions(+)
 create mode 100644 test/services/coins/monero/monero_wallet_test.dart
 create mode 100644 test/services/coins/monero/monero_wallet_test_data.dart

diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
new file mode 100644
index 000000000..1ee2fc44a
--- /dev/null
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -0,0 +1,207 @@
+import 'dart:async';
+import 'dart:core';
+import 'dart:core' as core;
+import 'dart:io';
+import 'dart:math';
+
+import 'package:flutter_test/flutter_test.dart';
+import 'package:hive/hive.dart';
+import 'package:hive_test/hive_test.dart';
+import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
+
+import 'package:cw_core/monero_amount_format.dart';
+import 'package:cw_core/node.dart';
+import 'package:cw_core/pending_transaction.dart';
+import 'package:cw_core/unspent_coins_info.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:cw_core/wallet_credentials.dart';
+import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_service.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:cw_monero/api/wallet.dart';
+import 'package:cw_monero/pending_monero_transaction.dart';
+import 'package:cw_monero/monero_wallet.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_libmonero/core/key_service.dart';
+import 'package:flutter_libmonero/core/wallet_creation_service.dart';
+import 'package:flutter_libmonero/view_model/send/output.dart';
+import 'package:flutter_libmonero/monero/monero.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:hive/hive.dart';
+import 'package:path_provider/path_provider.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
+
+import 'dart:developer' as developer;
+
+// TODO trim down to the minimum imports above
+
+import 'monero_wallet_test_data.dart';
+
+//FlutterSecureStorage? storage;
+FakeSecureStorage? storage;
+WalletService? walletService;
+SharedPreferences? prefs;
+KeyService? keysStorage;
+MoneroWalletBase? walletBase;
+late WalletCreationService _walletCreationService;
+dynamic _walletInfoSource;
+
+String name = 'namee${Random().nextInt(10000000)}';
+int nettype = 0;
+WalletType type = WalletType.monero;
+
+@GenerateMocks([])
+void main() async {
+  storage = FakeSecureStorage();
+  prefs = await SharedPreferences.getInstance();
+  keysStorage = KeyService(storage!);
+  WalletInfo walletInfo = WalletInfo.external(
+      id: '',
+      name: '',
+      type: type,
+      isRecovery: false,
+      restoreHeight: 0,
+      date: DateTime.now(),
+      path: '',
+      address: '',
+      dirPath: '');
+  late WalletCredentials credentials;
+
+  WidgetsFlutterBinding.ensureInitialized();
+  Directory appDir = (await getApplicationDocumentsDirectory());
+  if (Platform.isIOS) {
+    appDir = (await getLibraryDirectory());
+  }
+  await Hive.close();
+  Hive.init(appDir.path);
+  Hive.registerAdapter(NodeAdapter());
+  Hive.registerAdapter(WalletInfoAdapter());
+  Hive.registerAdapter(WalletTypeAdapter());
+  Hive.registerAdapter(UnspentCoinsInfoAdapter());
+
+  monero.onStartup();
+  _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
+  walletService = monero.createMoneroWalletService(_walletInfoSource);
+
+  group("Mainnet tests", () {
+    setUp(() async {
+      try {
+        // if (name?.isEmpty ?? true) {
+        // name = await generateName();
+        // }
+        final dirPath = await pathForWalletDir(name: name, type: type);
+        final path = await pathForWallet(name: name, type: type);
+        credentials =
+            // //     creating a new wallet
+            // monero.createMoneroNewWalletCredentials(
+            //     name: name, language: "English");
+            // restoring a previous wallet
+            monero.createMoneroRestoreWalletFromSeedCredentials(
+                name: name, height: 2580000, mnemonic: testMnemonic);
+
+        walletInfo = WalletInfo.external(
+            id: WalletBase.idFor(name, type),
+            name: name,
+            type: type,
+            isRecovery: false,
+            restoreHeight: credentials.height ?? 0,
+            date: DateTime.now(),
+            path: path,
+            address: "",
+            dirPath: dirPath);
+        credentials.walletInfo = walletInfo;
+
+        _walletCreationService = WalletCreationService(
+          secureStorage: storage,
+          sharedPreferences: prefs,
+          walletService: walletService,
+          keyService: keysStorage,
+        );
+        _walletCreationService.changeWalletType();
+      } catch (e, s) {
+        print(e);
+        print(s);
+      }
+    });
+
+    test("Test mainnet address generation from seed", () async {
+      final wallet = await
+          // _walletCreationService.create(credentials);
+          _walletCreationService.restoreFromSeed(credentials);
+      walletInfo.address = wallet.walletAddresses.address;
+      //print(walletInfo.address);
+
+      await _walletInfoSource.add(walletInfo);
+      walletBase?.close();
+      walletBase = wallet as MoneroWalletBase;
+      //print("${walletBase?.seed}");
+
+      // print(walletBase);
+      // loggerPrint(walletBase.toString());
+      // loggerPrint("name: ${walletBase!.name}  seed: ${walletBase!.seed} id: "
+      //     "${walletBase!.id} walletinfo: ${toStringForinfo(walletBase!.walletInfo)} type: ${walletBase!.type} balance: "
+      //     "${walletBase!.balance.entries.first.value.available} currency: ${walletBase!.currency}");
+
+      expect(walletInfo.address, mainnetTestData[0][0]);
+      expect(
+          await walletBase!.getTransactionAddress(0, 0), mainnetTestData[0][0]);
+      expect(
+          await walletBase!.getTransactionAddress(0, 1), mainnetTestData[0][1]);
+      expect(
+          await walletBase!.getTransactionAddress(0, 2), mainnetTestData[0][2]);
+      expect(
+          await walletBase!.getTransactionAddress(1, 0), mainnetTestData[1][0]);
+      expect(
+          await walletBase!.getTransactionAddress(1, 1), mainnetTestData[1][1]);
+      expect(
+          await walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]);
+    });
+  });
+  /*
+  group("Mainnet node tests", () {
+    test("Test mainnet node connection", () async {
+      await walletBase?.connectToNode(
+          node: Node(
+              uri: "monero-stagenet.stackwallet.com:38081",
+              type: WalletType.moneroStageNet));
+      await walletBase!.rescan(
+          height:
+              credentials.height); // Probably shouldn't be rescanning from 0...
+      await walletBase!.getNodeHeight();
+      int height = await walletBase!.getNodeHeight();
+      print('height: $height');
+      bool connected = await walletBase!.isConnected();
+      print('connected: $connected');
+
+      //expect...
+    });
+  });
+   */
+
+  // TODO test deletion of wallets ... and delete them
+}
+
+Future<String> pathForWalletDir(
+    {required String name, required WalletType type}) async {
+  Directory root = (await getApplicationDocumentsDirectory());
+  if (Platform.isIOS) {
+    root = (await getLibraryDirectory());
+  }
+  final prefix = walletTypeToString(type).toLowerCase();
+  final walletsDir = Directory('${root.path}/wallets');
+  final walletDire = Directory('${walletsDir.path}/$prefix/$name');
+
+  if (!walletDire.existsSync()) {
+    walletDire.createSync(recursive: true);
+  }
+
+  return walletDire.path;
+}
+
+Future<String> pathForWallet(
+        {required String name, required WalletType type}) async =>
+    await pathForWalletDir(name: name, type: type)
+        .then((path) => path + '/$name');
diff --git a/test/services/coins/monero/monero_wallet_test_data.dart b/test/services/coins/monero/monero_wallet_test_data.dart
new file mode 100644
index 000000000..dc0a0f4cb
--- /dev/null
+++ b/test/services/coins/monero/monero_wallet_test_data.dart
@@ -0,0 +1,14 @@
+String testMnemonic =
+    'agreed aquarium wallets uptight karate wonders afoot guys itself nucleus reduce lamb fully fewest bimonthly dazed skulls magically mocked fugitive imbalance saga calamity dialect itself';
+var mainnetTestData = [
+  [
+    '4AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn',
+    '82WsoLmbZt3BPwJMF5PfT8GitThJzUq3FFoSQyr4fKfJdxZebgY3mHPcnAqTBA3FFwZRGxC4ZDwkfE1VVULPa55x3xXgCbj',
+    '84kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'
+  ],
+  [
+    '86SF44CsTBYU3vk1X7nGBbQnrUSknGbd6Uw8a9hUUgy3KBeXTDvk3pm8upMzZKw17m3mLPEzbcPp5WLpYVoHR5PKNVtFrHH',
+    '8Aa9LNGdBHwYUMsy6M9ZVXMEkTBZyEDT7aQmY32trCxbU6dwkZJSCSbcpyL7UiTB9QXXosomZtJYvUJ296vTNX5yQ81KaA2',
+    '85C5zZRcaD89PKmXEwjcYMVAUqoH5rrAXe3GokvSupXnDmccYvZagz5Qem7bQLteEw4iFEJ9oRk9BNfjTi4K2cyTJbTMMPT'
+  ]
+];

From a3a36d02c3a7e6f4ef6b166a5afd6cad55012a25 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 14 Oct 2022 10:09:17 -0500
Subject: [PATCH 013/426] Import wallets service and remove wallet at
 conclusion of tests

---
 .../coins/monero/monero_wallet_test.dart      | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index 1ee2fc44a..5b802a089 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -34,6 +34,8 @@ import 'package:path_provider/path_provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
+import 'package:stackwallet/services/wallets.dart';
+
 import 'dart:developer' as developer;
 
 // TODO trim down to the minimum imports above
@@ -48,6 +50,7 @@ KeyService? keysStorage;
 MoneroWalletBase? walletBase;
 late WalletCreationService _walletCreationService;
 dynamic _walletInfoSource;
+Wallets? walletsService;
 
 String name = 'namee${Random().nextInt(10000000)}';
 int nettype = 0;
@@ -160,6 +163,22 @@ void main() async {
           await walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]);
     });
   });
+
+  group("Mainnet wallet deletion test", () {
+    test("Test mainnet wallet deletion", () async {
+      // Remove wallet from wallet service
+      walletService?.remove(name);
+      walletsService?.removeWallet(walletId: name);
+
+      // TODO test deletion, get code from generation for checking if it already exists
+    });
+
+    /*
+    // wait for widget tree to dispose of any widgets watching the manager
+    await Future<void>.delayed(const Duration(seconds: 1));
+    walletsInstance.removeWallet(walletId: walletId);
+     */
+  });
   /*
   group("Mainnet node tests", () {
     test("Test mainnet node connection", () async {

From b6e51cb954ff1b90765b582487ecb3141fc5c840 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 14 Oct 2022 10:24:05 -0500
Subject: [PATCH 014/426] Add template wallet detection and removal code

Not enabled as wallet files are not currently being saved; only an empty folder is created and left.  TODO clean that up
---
 .../coins/monero/monero_wallet_test.dart      | 25 ++++++++++---------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index 5b802a089..d54959ab2 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -20,6 +20,7 @@ import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
 import 'package:cw_monero/api/wallet.dart';
+import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
 import 'package:cw_monero/pending_monero_transaction.dart';
 import 'package:cw_monero/monero_wallet.dart';
 import 'package:flutter/material.dart';
@@ -52,6 +53,8 @@ late WalletCreationService _walletCreationService;
 dynamic _walletInfoSource;
 Wallets? walletsService;
 
+String path = '';
+
 String name = 'namee${Random().nextInt(10000000)}';
 int nettype = 0;
 WalletType type = WalletType.monero;
@@ -96,7 +99,7 @@ void main() async {
         // name = await generateName();
         // }
         final dirPath = await pathForWalletDir(name: name, type: type);
-        final path = await pathForWallet(name: name, type: type);
+        path = await pathForWallet(name: name, type: type);
         credentials =
             // //     creating a new wallet
             // monero.createMoneroNewWalletCredentials(
@@ -163,23 +166,21 @@ void main() async {
           await walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]);
     });
   });
-
+  /*
+  // Not needed; only folder created, wallet files not saved yet.  TODO test saving and deleting wallet files and make sure to clean up leftover folder afterwards
   group("Mainnet wallet deletion test", () {
-    test("Test mainnet wallet deletion", () async {
+    test("Test mainnet wallet existence", () {
+      expect(monero_wallet_manager.isWalletExistSync(path: path), true);
+    });
+
+    test("Test mainnet wallet deletion", () {
       // Remove wallet from wallet service
       walletService?.remove(name);
       walletsService?.removeWallet(walletId: name);
-
-      // TODO test deletion, get code from generation for checking if it already exists
+      expect(monero_wallet_manager.isWalletExistSync(path: path), false);
     });
-
-    /*
-    // wait for widget tree to dispose of any widgets watching the manager
-    await Future<void>.delayed(const Duration(seconds: 1));
-    walletsInstance.removeWallet(walletId: walletId);
-     */
   });
-  /*
+
   group("Mainnet node tests", () {
     test("Test mainnet node connection", () async {
       await walletBase?.connectToNode(

From d00c15de2603f5f0bf2bee4a0871cd2b266e3624 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 14 Oct 2022 17:07:58 -0600
Subject: [PATCH 015/426] text color change

---
 lib/utilities/text_styles.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart
index 8175cbde8..82e2ad349 100644
--- a/lib/utilities/text_styles.dart
+++ b/lib/utilities/text_styles.dart
@@ -683,7 +683,7 @@ class STextStyles {
     switch (_theme(context).themeType) {
       case ThemeType.light:
         return GoogleFonts.inter(
-          color: _theme(context).buttonTextPrimaryDisabled,
+          color: _theme(context).textDark,
           fontWeight: FontWeight.w500,
           fontSize: 18,
           height: 27 / 18,

From 038df8280018472dfaf2196b297743558ca771ed Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 14 Oct 2022 17:08:24 -0600
Subject: [PATCH 016/426] backup_and_restore page

---
 .../settings_menu/backup_and_restore.dart     | 170 ++++++++++++++++++
 .../home/settings_menu/settings_menu.dart     |  24 +--
 2 files changed, 174 insertions(+), 20 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart
index e69de29bb..9030aa7fa 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart
@@ -0,0 +1,170 @@
+import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+class BackupRestore extends ConsumerStatefulWidget {
+  const BackupRestore({Key? key}) : super(key: key);
+
+  static const String routeName = "/backupRestore";
+
+  @override
+  ConsumerState<BackupRestore> createState() => _BackupRestore();
+}
+
+class _BackupRestore extends ConsumerState<BackupRestore> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return ListView(
+      shrinkWrap: true,
+      scrollDirection: Axis.vertical,
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.backupAuto,
+                  width: 48,
+                  height: 48,
+                  alignment: Alignment.topLeft,
+                ),
+                Center(
+                  child: Padding(
+                    padding: const EdgeInsets.all(10),
+                    child: RichText(
+                      textAlign: TextAlign.start,
+                      text: TextSpan(
+                        children: [
+                          TextSpan(
+                            text: "Auto Backup",
+                            style: STextStyles.desktopTextSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nAuto Backup is a custom Stack Wallet feature that offers a convenient backup of your data."
+                                "To ensure maximum security, we recommend using a unique password that you haven't used anywhere "
+                                "else on the internet before. Your password is not stored.",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nFor more information, please see our website ",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                          TextSpan(
+                            text: "stackwallet.com",
+                            style: STextStyles.richLink(context)
+                                .copyWith(fontSize: 14),
+                            recognizer: TapGestureRecognizer()
+                              ..onTap = () {
+                                launchUrl(
+                                  Uri.parse("https://stackwallet.com/"),
+                                  mode: LaunchMode.externalApplication,
+                                );
+                              },
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: EnableBackupButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 25,
+        ),
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.backupAdd,
+                  width: 48,
+                  height: 48,
+                  alignment: Alignment.topLeft,
+                ),
+                Center(
+                  child: Padding(
+                    padding: const EdgeInsets.all(10),
+                    child: RichText(
+                      textAlign: TextAlign.start,
+                      text: TextSpan(
+                        children: [
+                          TextSpan(
+                            text: "Manual Backup",
+                            style: STextStyles.desktopTextSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nCreate Manual backup to easily transfer your data between devices. "
+                                "You will create a backup file that can be later used in the Restore option. "
+                                "Use a strong password to encrypt your data.",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class EnableBackupButton extends ConsumerWidget {
+  const EnableBackupButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {},
+        child: Text(
+          "Enable Auto Backup",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart b/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
index 82b32be5b..fb5444d2a 100644
--- a/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
@@ -1,12 +1,10 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu_item.dart';
+import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
-import 'package:stackwallet/widgets/rounded_white_container.dart';
-
-import '../../../utilities/assets.dart';
-import '../settings_menu_item.dart';
 
 class SettingsMenu extends ConsumerStatefulWidget {
   const SettingsMenu({
@@ -54,7 +52,8 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
             ],
           ),
         ),
-        Row(
+        Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
           children: [
             Padding(
               padding: const EdgeInsets.only(left: 15),
@@ -173,21 +172,6 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
                 ],
               ),
             ),
-            Expanded(
-              child: Padding(
-                padding: const EdgeInsets.only(
-                  left: 10,
-                  right: 40,
-                ),
-                child: RoundedWhiteContainer(
-                  child: SvgPicture.asset(
-                    Assets.svg.backupAuto,
-                    width: 48,
-                    height: 48,
-                  ),
-                ),
-              ),
-            )
           ],
         ),
       ],

From c2aeb5bae831eaa6baa964b66d9a821063889c80 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Fri, 14 Oct 2022 18:38:46 -0500
Subject: [PATCH 017/426] Add Wownero mainnet wallet address generation test

---
 .../coins/wownero/wownero_wallet_test.dart    | 164 ++++++++++++++++++
 .../wownero/wownero_wallet_test_data.dart     |  14 ++
 2 files changed, 178 insertions(+)
 create mode 100644 test/services/coins/wownero/wownero_wallet_test.dart
 create mode 100644 test/services/coins/wownero/wownero_wallet_test_data.dart

diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
new file mode 100644
index 000000000..e64dd772c
--- /dev/null
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -0,0 +1,164 @@
+import 'dart:async';
+import 'dart:core';
+import 'dart:core' as core;
+import 'dart:io';
+import 'dart:math';
+
+import 'package:flutter_test/flutter_test.dart';
+import 'package:hive/hive.dart';
+import 'package:hive_test/hive_test.dart';
+import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
+
+import 'package:cw_core/monero_amount_format.dart';
+import 'package:cw_core/node.dart';
+import 'package:cw_core/pending_transaction.dart';
+import 'package:cw_core/unspent_coins_info.dart';
+import 'package:cw_core/wallet_base.dart';
+import 'package:cw_core/wallet_credentials.dart';
+import 'package:cw_core/wallet_info.dart';
+import 'package:cw_core/wallet_service.dart';
+import 'package:cw_core/wallet_type.dart';
+import 'package:cw_wownero/api/wallet.dart';
+import 'package:cw_wownero/pending_wownero_transaction.dart';
+import 'package:cw_wownero/wownero_wallet.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_libmonero/core/key_service.dart';
+import 'package:flutter_libmonero/core/wallet_creation_service.dart';
+import 'package:flutter_libmonero/view_model/send/output.dart';
+import 'package:flutter_libmonero/wownero/wownero.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
+import 'package:hive/hive.dart';
+import 'package:path_provider/path_provider.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+
+import 'wownero_wallet_test_data.dart';
+
+FakeSecureStorage? storage;
+WalletService? walletService;
+SharedPreferences? prefs;
+KeyService? keysStorage;
+WowneroWalletBase? walletBase;
+late WalletCreationService _walletCreationService;
+dynamic _walletInfoSource;
+
+String path = '';
+
+String name = 'namee${Random().nextInt(10000000)}';
+int nettype = 0;
+WalletType type = WalletType.wownero;
+
+@GenerateMocks([])
+void main() async {
+  storage = FakeSecureStorage();
+  prefs = await SharedPreferences.getInstance();
+  keysStorage = KeyService(storage!);
+  WalletInfo walletInfo = WalletInfo.external(
+      id: '',
+      name: '',
+      type: type,
+      isRecovery: false,
+      restoreHeight: 0,
+      date: DateTime.now(),
+      path: '',
+      address: '',
+      dirPath: '');
+  late WalletCredentials credentials;
+
+  WidgetsFlutterBinding.ensureInitialized();
+  Directory appDir = (await getApplicationDocumentsDirectory());
+  if (Platform.isIOS) {
+    appDir = (await getLibraryDirectory());
+  }
+  await Hive.close();
+  Hive.init(appDir.path);
+  Hive.registerAdapter(NodeAdapter());
+  Hive.registerAdapter(WalletInfoAdapter());
+  Hive.registerAdapter(WalletTypeAdapter());
+  Hive.registerAdapter(UnspentCoinsInfoAdapter());
+
+  wownero.onStartup();
+  _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
+  walletService = wownero.createWowneroWalletService(_walletInfoSource);
+
+  group("Wownero tests", () {
+    setUp(() async {
+      try {
+        final dirPath = await pathForWalletDir(name: name, type: type);
+        path = await pathForWallet(name: name, type: type);
+        credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
+            name: name, height: 465760, mnemonic: testMnemonic);
+
+        walletInfo = WalletInfo.external(
+            id: WalletBase.idFor(name, type),
+            name: name,
+            type: type,
+            isRecovery: false,
+            restoreHeight: credentials.height ?? 0,
+            date: DateTime.now(),
+            path: path,
+            address: "",
+            dirPath: dirPath);
+        credentials.walletInfo = walletInfo;
+
+        _walletCreationService = WalletCreationService(
+          secureStorage: storage,
+          sharedPreferences: prefs,
+          walletService: walletService,
+          keyService: keysStorage,
+        );
+        _walletCreationService.changeWalletType();
+      } catch (e, s) {
+        print(e);
+        print(s);
+      }
+    });
+
+    test("Test mainnet address generation from seed", () async {
+      final wallet = await _walletCreationService.restoreFromSeed(credentials);
+      walletInfo.address = wallet.walletAddresses.address;
+
+      await _walletInfoSource.add(walletInfo);
+      walletBase?.close();
+      walletBase = wallet as WowneroWalletBase;
+
+      expect(walletInfo.address, mainnetTestData[0][0]);
+      expect(
+          await walletBase!.getTransactionAddress(0, 0), mainnetTestData[0][0]);
+      expect(
+          await walletBase!.getTransactionAddress(0, 1), mainnetTestData[0][1]);
+      expect(
+          await walletBase!.getTransactionAddress(0, 2), mainnetTestData[0][2]);
+      expect(
+          await walletBase!.getTransactionAddress(1, 0), mainnetTestData[1][0]);
+      expect(
+          await walletBase!.getTransactionAddress(1, 1), mainnetTestData[1][1]);
+      expect(
+          await walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]);
+    });
+  });
+}
+
+Future<String> pathForWalletDir(
+    {required String name, required WalletType type}) async {
+  Directory root = (await getApplicationDocumentsDirectory());
+  if (Platform.isIOS) {
+    root = (await getLibraryDirectory());
+  }
+  final prefix = walletTypeToString(type).toLowerCase();
+  final walletsDir = Directory('${root.path}/wallets');
+  final walletDire = Directory('${walletsDir.path}/$prefix/$name');
+
+  if (!walletDire.existsSync()) {
+    walletDire.createSync(recursive: true);
+  }
+
+  return walletDire.path;
+}
+
+Future<String> pathForWallet(
+        {required String name, required WalletType type}) async =>
+    await pathForWalletDir(name: name, type: type)
+        .then((path) => path + '/$name');
diff --git a/test/services/coins/wownero/wownero_wallet_test_data.dart b/test/services/coins/wownero/wownero_wallet_test_data.dart
new file mode 100644
index 000000000..b0d93a448
--- /dev/null
+++ b/test/services/coins/wownero/wownero_wallet_test_data.dart
@@ -0,0 +1,14 @@
+String testMnemonic =
+    'weather cruise school such silly profit clerk wage reduce obtain ill sand episode shadow';
+var mainnetTestData = [
+  [
+    'Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi',
+    'WW3K54QzmMFB1uTZh3LVvgQYqANLmX1FkJHLJ4sU1E7BQmp8nGizyBnjNXSgsjCa4BQ3Rw3GG5jw1ByUkaUjSywm2KmHAbFvK',
+    'WW3e3F51KAojcSW2G5WimmE1WVFsbBHc6HppZFBa6dNiEn21cThXzdGGDbpv89aTKXSRSPSFaetK6HgCozYawaYz2knUi9Hmn'
+  ],
+  [
+    'WW2nx7MFruyN2CcXnGnMbDdvqsyZUGQthLWKYPkQ4iM9XCE54RyWVjNjgopryUbyi9WKzYhHDai2wENbh1Jh1UHa28CL72TYt',
+    'WW34p57QBMoD6MEZVTu5u9R7G3KeYqvN4eYbvHLYsgbWXpLe992fBvVB7ANJNvaGmPg2uwY5oKjwKbpo4fDU6cGS231PmvXrZ',
+    'WW2KQLLt6gjC9gRsC4NGehbAZX6UPU7sK89UQFwSg3NKj3MXPwnjh5BiJVqYYNQb6JNsfa7oP7eDjLagtLa2H6YP11RhUNQqw'
+  ]
+];

From b09ee79865f901c603d9b8c316ec4c2edd14afe4 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 17 Oct 2022 09:07:17 -0600
Subject: [PATCH 018/426] backup and restore page

---
 .../home/desktop_settings_view.dart           |   8 +-
 .../settings_menu/backup_and_restore.dart     | 118 +++++++++++++++++-
 lib/route_generator.dart                      |   7 ++
 3 files changed, 127 insertions(+), 6 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index bfe9272f2..ce51dfbe7 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -1,6 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
 class DesktopSettingsView extends ConsumerStatefulWidget {
@@ -16,8 +18,9 @@ class DesktopSettingsView extends ConsumerStatefulWidget {
 class _DesktopSettingsViewState extends ConsumerState<DesktopSettingsView> {
   int currentViewIndex = 0;
   final List<Widget> contentViews = [
-    Container(
-      color: Colors.lime,
+    const Navigator(
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: BackupRestore.routeName,
     ), //b+r
     Container(
       color: Colors.green,
@@ -48,7 +51,6 @@ class _DesktopSettingsViewState extends ConsumerState<DesktopSettingsView> {
     });
   }
 
-  // will have a row with two items: SettingsMenu and settings contentxd
   @override
   Widget build(BuildContext context) {
     return Material(
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart
index 9030aa7fa..37b27bb97 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart
@@ -88,7 +88,7 @@ class _BackupRestore extends ConsumerState<BackupRestore> {
                       padding: EdgeInsets.all(
                         10,
                       ),
-                      child: EnableBackupButton(),
+                      child: AutoBackupButton(),
                     ),
                   ],
                 ),
@@ -137,6 +137,72 @@ class _BackupRestore extends ConsumerState<BackupRestore> {
                     ),
                   ),
                 ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: ManualBackupButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 25,
+        ),
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.backupRestore,
+                  width: 48,
+                  height: 48,
+                  alignment: Alignment.topLeft,
+                ),
+                Center(
+                  child: Padding(
+                    padding: const EdgeInsets.all(10),
+                    child: RichText(
+                      textAlign: TextAlign.start,
+                      text: TextSpan(
+                        children: [
+                          TextSpan(
+                            text: "Restore Backup",
+                            style: STextStyles.desktopTextSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nUse your Stack Wallet backup file to restore your wallets, address book "
+                                "and wallet preferences.",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: ManualBackupButton(),
+                    ),
+                  ],
+                ),
               ],
             ),
           ),
@@ -146,8 +212,8 @@ class _BackupRestore extends ConsumerState<BackupRestore> {
   }
 }
 
-class EnableBackupButton extends ConsumerWidget {
-  const EnableBackupButton({
+class AutoBackupButton extends ConsumerWidget {
+  const AutoBackupButton({
     Key? key,
   }) : super(key: key);
   @override
@@ -168,3 +234,49 @@ class EnableBackupButton extends ConsumerWidget {
     );
   }
 }
+
+class ManualBackupButton extends ConsumerWidget {
+  const ManualBackupButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {},
+        child: Text(
+          "Create Manual Backup",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
+
+class RestoreBackupButton extends ConsumerWidget {
+  const RestoreBackupButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {},
+        child: Text(
+          "Restore Backup",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index b4ca9ef92..ef3b143bd 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -87,6 +87,7 @@ import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
@@ -992,6 +993,12 @@ class RouteGenerator {
                 ),
             settings: RouteSettings(name: settings.name));
 
+      case BackupRestore.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const BackupRestore(),
+            settings: RouteSettings(name: settings.name));
+
       // == End of desktop specific routes =====================================
 
       default:

From ab28a9369950747c4801a637651bc01529644406 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 17 Oct 2022 10:10:16 -0600
Subject: [PATCH 019/426] WIP: icon color change

---
 .../home/desktop_settings_view.dart           |  1 +
 .../home/settings_menu/settings_menu.dart     | 41 +++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index ce51dfbe7..10f5c683b 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -19,6 +19,7 @@ class _DesktopSettingsViewState extends ConsumerState<DesktopSettingsView> {
   int currentViewIndex = 0;
   final List<Widget> contentViews = [
     const Navigator(
+      key: Key("settingsBackupRestoreDesktopKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: BackupRestore.routeName,
     ), //b+r
diff --git a/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart b/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
index fb5444d2a..178afb2db 100644
--- a/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
@@ -4,6 +4,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu_item.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 
 class SettingsMenu extends ConsumerStatefulWidget {
@@ -65,6 +66,11 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
                       Assets.svg.polygon,
                       width: 11,
                       height: 11,
+                      color: selectedMenuItem == 0
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Colors.transparent,
                     ),
                     label: "Backup and restore",
                     value: 0,
@@ -79,6 +85,11 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
                       Assets.svg.polygon,
                       width: 11,
                       height: 11,
+                      color: selectedMenuItem == 1
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Colors.transparent,
                     ),
                     label: "Security",
                     value: 1,
@@ -93,6 +104,11 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
                       Assets.svg.polygon,
                       width: 11,
                       height: 11,
+                      color: selectedMenuItem == 2
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Colors.transparent,
                     ),
                     label: "Currency",
                     value: 2,
@@ -107,6 +123,11 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
                       Assets.svg.polygon,
                       width: 11,
                       height: 11,
+                      color: selectedMenuItem == 3
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Colors.transparent,
                     ),
                     label: "Language",
                     value: 3,
@@ -121,6 +142,11 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
                       Assets.svg.polygon,
                       width: 11,
                       height: 11,
+                      color: selectedMenuItem == 4
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Colors.transparent,
                     ),
                     label: "Nodes",
                     value: 4,
@@ -135,6 +161,11 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
                       Assets.svg.polygon,
                       width: 11,
                       height: 11,
+                      color: selectedMenuItem == 5
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Colors.transparent,
                     ),
                     label: "Syncing preferences",
                     value: 5,
@@ -149,6 +180,11 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
                       Assets.svg.polygon,
                       width: 11,
                       height: 11,
+                      color: selectedMenuItem == 6
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Colors.transparent,
                     ),
                     label: "Appearance",
                     value: 6,
@@ -163,6 +199,11 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
                       Assets.svg.polygon,
                       width: 11,
                       height: 11,
+                      color: selectedMenuItem == 7
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Colors.transparent,
                     ),
                     label: "Advanced",
                     value: 7,

From 22473c16685ffc84788f49e6abebd390c6d744a4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 17 Oct 2022 10:50:37 -0600
Subject: [PATCH 020/426] desktop settings navigation fix

---
 .../home/desktop_home_view.dart               |   4 +-
 .../home/desktop_settings_view.dart           |  24 +-
 .../home/settings_menu/settings_menu.dart     | 327 ++++++++----------
 3 files changed, 176 insertions(+), 179 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index 3941fc6de..41f4b5041 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -1,8 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_menu.dart';
+import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
@@ -35,7 +35,7 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
     const Navigator(
       key: Key("desktopSettingHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
-      initialRoute: SettingsMenu.routeName,
+      initialRoute: DesktopSettingsView.routeName,
     ),
     Container(
       color: Colors.blue,
diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index 10f5c683b..cd11eff3d 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -3,7 +3,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
 import 'package:stackwallet/route_generator.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 
 class DesktopSettingsView extends ConsumerStatefulWidget {
   const DesktopSettingsView({Key? key}) : super(key: key);
@@ -54,9 +57,24 @@ class _DesktopSettingsViewState extends ConsumerState<DesktopSettingsView> {
 
   @override
   Widget build(BuildContext context) {
-    return Material(
-      color: Theme.of(context).extension<StackColors>()!.background,
-      child: Row(
+    return DesktopScaffold(
+      background: Theme.of(context).extension<StackColors>()!.background,
+      appBar: DesktopAppBar(
+        isCompactHeight: true,
+        leading: Row(
+          children: [
+            const SizedBox(
+              width: 24,
+              height: 24,
+            ),
+            Text(
+              "Settings",
+              style: STextStyles.desktopH3(context),
+            )
+          ],
+        ),
+      ),
+      body: Row(
         children: [
           SettingsMenu(
             onSelectionChanged: onMenuSelectionChanged,
diff --git a/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart b/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
index 178afb2db..b743fdb39 100644
--- a/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/settings_menu.dart
@@ -3,9 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu_item.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
-import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 
 class SettingsMenu extends ConsumerStatefulWidget {
   const SettingsMenu({
@@ -37,184 +35,165 @@ class _SettingsMenuState extends ConsumerState<SettingsMenu> {
     debugPrint("BUILD: $runtimeType");
 
     return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
       children: [
-        DesktopAppBar(
-          isCompactHeight: true,
-          leading: Row(
+        Padding(
+          padding: const EdgeInsets.only(left: 15),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
             children: [
-              const SizedBox(
-                width: 24,
-                height: 24,
+              SettingsMenuItem(
+                icon: SvgPicture.asset(
+                  Assets.svg.polygon,
+                  width: 11,
+                  height: 11,
+                  color: selectedMenuItem == 0
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorBlue
+                      : Colors.transparent,
+                ),
+                label: "Backup and restore",
+                value: 0,
+                group: selectedMenuItem,
+                onChanged: updateSelectedMenuItem,
+              ),
+              const SizedBox(
+                height: 2,
+              ),
+              SettingsMenuItem(
+                icon: SvgPicture.asset(
+                  Assets.svg.polygon,
+                  width: 11,
+                  height: 11,
+                  color: selectedMenuItem == 1
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorBlue
+                      : Colors.transparent,
+                ),
+                label: "Security",
+                value: 1,
+                group: selectedMenuItem,
+                onChanged: updateSelectedMenuItem,
+              ),
+              const SizedBox(
+                height: 2,
+              ),
+              SettingsMenuItem(
+                icon: SvgPicture.asset(
+                  Assets.svg.polygon,
+                  width: 11,
+                  height: 11,
+                  color: selectedMenuItem == 2
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorBlue
+                      : Colors.transparent,
+                ),
+                label: "Currency",
+                value: 2,
+                group: selectedMenuItem,
+                onChanged: updateSelectedMenuItem,
+              ),
+              const SizedBox(
+                height: 2,
+              ),
+              SettingsMenuItem(
+                icon: SvgPicture.asset(
+                  Assets.svg.polygon,
+                  width: 11,
+                  height: 11,
+                  color: selectedMenuItem == 3
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorBlue
+                      : Colors.transparent,
+                ),
+                label: "Language",
+                value: 3,
+                group: selectedMenuItem,
+                onChanged: updateSelectedMenuItem,
+              ),
+              const SizedBox(
+                height: 2,
+              ),
+              SettingsMenuItem(
+                icon: SvgPicture.asset(
+                  Assets.svg.polygon,
+                  width: 11,
+                  height: 11,
+                  color: selectedMenuItem == 4
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorBlue
+                      : Colors.transparent,
+                ),
+                label: "Nodes",
+                value: 4,
+                group: selectedMenuItem,
+                onChanged: updateSelectedMenuItem,
+              ),
+              const SizedBox(
+                height: 2,
+              ),
+              SettingsMenuItem(
+                icon: SvgPicture.asset(
+                  Assets.svg.polygon,
+                  width: 11,
+                  height: 11,
+                  color: selectedMenuItem == 5
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorBlue
+                      : Colors.transparent,
+                ),
+                label: "Syncing preferences",
+                value: 5,
+                group: selectedMenuItem,
+                onChanged: updateSelectedMenuItem,
+              ),
+              const SizedBox(
+                height: 2,
+              ),
+              SettingsMenuItem(
+                icon: SvgPicture.asset(
+                  Assets.svg.polygon,
+                  width: 11,
+                  height: 11,
+                  color: selectedMenuItem == 6
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorBlue
+                      : Colors.transparent,
+                ),
+                label: "Appearance",
+                value: 6,
+                group: selectedMenuItem,
+                onChanged: updateSelectedMenuItem,
+              ),
+              const SizedBox(
+                height: 2,
+              ),
+              SettingsMenuItem(
+                icon: SvgPicture.asset(
+                  Assets.svg.polygon,
+                  width: 11,
+                  height: 11,
+                  color: selectedMenuItem == 7
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorBlue
+                      : Colors.transparent,
+                ),
+                label: "Advanced",
+                value: 7,
+                group: selectedMenuItem,
+                onChanged: updateSelectedMenuItem,
               ),
-              Text(
-                "Settings",
-                style: STextStyles.desktopH3(context),
-              )
             ],
           ),
         ),
-        Column(
-          crossAxisAlignment: CrossAxisAlignment.start,
-          children: [
-            Padding(
-              padding: const EdgeInsets.only(left: 15),
-              child: Column(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  SettingsMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.polygon,
-                      width: 11,
-                      height: 11,
-                      color: selectedMenuItem == 0
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Colors.transparent,
-                    ),
-                    label: "Backup and restore",
-                    value: 0,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  SettingsMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.polygon,
-                      width: 11,
-                      height: 11,
-                      color: selectedMenuItem == 1
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Colors.transparent,
-                    ),
-                    label: "Security",
-                    value: 1,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  SettingsMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.polygon,
-                      width: 11,
-                      height: 11,
-                      color: selectedMenuItem == 2
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Colors.transparent,
-                    ),
-                    label: "Currency",
-                    value: 2,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  SettingsMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.polygon,
-                      width: 11,
-                      height: 11,
-                      color: selectedMenuItem == 3
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Colors.transparent,
-                    ),
-                    label: "Language",
-                    value: 3,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  SettingsMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.polygon,
-                      width: 11,
-                      height: 11,
-                      color: selectedMenuItem == 4
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Colors.transparent,
-                    ),
-                    label: "Nodes",
-                    value: 4,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  SettingsMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.polygon,
-                      width: 11,
-                      height: 11,
-                      color: selectedMenuItem == 5
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Colors.transparent,
-                    ),
-                    label: "Syncing preferences",
-                    value: 5,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  SettingsMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.polygon,
-                      width: 11,
-                      height: 11,
-                      color: selectedMenuItem == 6
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Colors.transparent,
-                    ),
-                    label: "Appearance",
-                    value: 6,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  SettingsMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.polygon,
-                      width: 11,
-                      height: 11,
-                      color: selectedMenuItem == 7
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Colors.transparent,
-                    ),
-                    label: "Advanced",
-                    value: 7,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                  ),
-                ],
-              ),
-            ),
-          ],
-        ),
       ],
     );
   }

From 5da68eb8571cc6703064aa7de9167c477f3d87c0 Mon Sep 17 00:00:00 2001
From: Marco <marco@cypherstack.com>
Date: Wed, 19 Oct 2022 09:34:04 -0600
Subject: [PATCH 021/426] stack privacy

---
 lib/pages/stack_privacy_calls.dart | 99 +++++++++++-------------------
 1 file changed, 37 insertions(+), 62 deletions(-)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index 7160a60b2..2aa2a5c8a 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -6,7 +6,6 @@ import 'package:stackwallet/pages_desktop_specific/create_password/create_passwo
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
@@ -218,7 +217,6 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
       children: [
         Expanded(
           child: RawMaterialButton(
-            elevation: 0,
             fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
             shape: RoundedRectangleBorder(
               side: !externalCallsEnabled
@@ -250,13 +248,10 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
                   Column(
                     crossAxisAlignment: CrossAxisAlignment.stretch,
                     children: [
-                      Padding(
-                        padding: const EdgeInsets.all(16.0),
-                        child: SvgPicture.asset(
-                          Assets.svg.personaEasy,
-                          width: 140,
-                          height: 140,
-                        ),
+                      SvgPicture.asset(
+                        Assets.svg.personaEasy,
+                        width: 140,
+                        height: 140,
                       ),
                       Center(
                           child: Text(
@@ -343,13 +338,10 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
                   Column(
                     crossAxisAlignment: CrossAxisAlignment.stretch,
                     children: [
-                      Padding(
-                        padding: const EdgeInsets.all(16.0),
-                        child: SvgPicture.asset(
-                          Assets.svg.personaIncognito,
-                          width: 140,
-                          height: 140,
-                        ),
+                      SvgPicture.asset(
+                        Assets.svg.personaIncognito,
+                        width: 140,
+                        height: 140,
                       ),
                       Center(
                         child: Text(
@@ -409,8 +401,8 @@ class ContinueButton extends ConsumerWidget {
   const ContinueButton({
     Key? key,
     required this.isDesktop,
-    required this.isSettings,
-    required this.isEasy,
+    required this.onPressed,
+    required this.label,
   }) : super(key: key);
 
   final String label;
@@ -419,50 +411,33 @@ class ContinueButton extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    return !isDesktop
-        ? TextButton(
-            style: Theme.of(context)
-                .extension<StackColors>()!
-                .getPrimaryEnabledButtonColor(context),
-            onPressed: () {
-              print("Output of isEasy:");
-              print(isEasy);
-
-              ref.read(prefsChangeNotifierProvider).externalCalls = isEasy;
-
-              !isSettings
-                  ? Navigator.of(context).pushNamed(CreatePinView.routeName)
-                  : Navigator.of(context).pop();
-            },
-            child: Text(
-              !isSettings ? "Continue" : "Save changes",
-              style: STextStyles.button(context),
-            ),
-          )
-        : SizedBox(
-            width: 328,
-            height: 70,
-            child: TextButton(
-              style: Theme.of(context)
-                  .extension<StackColors>()!
-                  .getPrimaryEnabledButtonColor(context),
-              onPressed: () {
-                print("Output of isEasy:");
-                print(isEasy);
-
-                ref.read(prefsChangeNotifierProvider).externalCalls = isEasy;
-
-                !isSettings
-                    ? Navigator.of(context)
-                        .pushNamed(CreatePasswordView.routeName)
-                    : Navigator.of(context).pop();
-              },
-              child: Text(
-                !isSettings ? "Continue" : "Save changes",
-                style: STextStyles.button(context).copyWith(fontSize: 20),
-              ),
-            ),
-          );
+    if (isDesktop) {
+      return SizedBox(
+        width: 328,
+        height: 70,
+        child: TextButton(
+          style: Theme.of(context)
+              .extension<StackColors>()!
+              .getPrimaryEnabledButtonColor(context),
+          onPressed: onPressed,
+          child: Text(
+            label,
+            style: STextStyles.button(context).copyWith(fontSize: 20),
+          ),
+        ),
+      );
+    } else {
+      return TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: onPressed,
+        child: Text(
+          label,
+          style: STextStyles.button(context),
+        ),
+      );
+    }
   }
 }
 

From 78d741374c4c6801980691eb994df9b3d7b3c708 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 19 Oct 2022 16:10:34 -0600
Subject: [PATCH 022/426] settings menu options ui

---
 assets/svg/Button.svg                         |   6 +
 assets/svg/dollar-sign-circle.svg             |   4 +
 assets/svg/language-circle.svg                |  11 ++
 assets/svg/lock-circle.svg                    |  11 ++
 assets/svg/rotate-circle.svg                  |   4 +
 assets/svg/sun-circle.svg                     |  11 ++
 .../home/settings_menu/advanced_settings.dart | 104 +++++++++++++++++
 .../settings_menu/appearance_settings.dart    |  71 ++++++++++++
 ....dart => backup_and_restore_settings.dart} |  22 ++--
 .../home/settings_menu/currency_settings.dart | 102 +++++++++++++++++
 .../home/settings_menu/language_settings.dart | 105 +++++++++++++++++
 .../home/settings_menu/security_settings.dart | 102 +++++++++++++++++
 .../syncing_preferences_settings.dart         | 106 ++++++++++++++++++
 lib/route_generator.dart                      |  58 ++++++++--
 lib/utilities/assets.dart                     |   6 +
 15 files changed, 704 insertions(+), 19 deletions(-)
 create mode 100644 assets/svg/Button.svg
 create mode 100644 assets/svg/dollar-sign-circle.svg
 create mode 100644 assets/svg/language-circle.svg
 create mode 100644 assets/svg/lock-circle.svg
 create mode 100644 assets/svg/rotate-circle.svg
 create mode 100644 assets/svg/sun-circle.svg
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
 rename lib/pages_desktop_specific/home/settings_menu/{backup_and_restore.dart => backup_and_restore_settings.dart} (93%)
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/currency_settings.dart
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/language_settings.dart
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/security_settings.dart
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart

diff --git a/assets/svg/Button.svg b/assets/svg/Button.svg
new file mode 100644
index 000000000..37e0d359b
--- /dev/null
+++ b/assets/svg/Button.svg
@@ -0,0 +1,6 @@
+<svg width="91" height="38" viewBox="0 0 91 38" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g opacity="0.5">
+<rect y="0.5" width="91" height="37" rx="8" fill="#E0E3E3"/>
+<path d="M20.7663 24.5H17.4702V14.3182H20.8707C21.8684 14.3182 22.7251 14.522 23.4411 14.9297C24.157 15.334 24.7055 15.9157 25.0866 16.6747C25.4711 17.4304 25.6634 18.3369 25.6634 19.3942C25.6634 20.4548 25.4695 21.3662 25.0817 22.1286C24.6972 22.8909 24.1404 23.4775 23.4112 23.8885C22.6821 24.2962 21.8004 24.5 20.7663 24.5ZM19.0064 23.1577H20.6818C21.4574 23.1577 22.102 23.0118 22.6158 22.7202C23.1295 22.4252 23.514 21.9993 23.7692 21.4425C24.0244 20.8823 24.152 20.1996 24.152 19.3942C24.152 18.5954 24.0244 17.9176 23.7692 17.3608C23.5173 16.804 23.1411 16.3814 22.6406 16.093C22.1402 15.8047 21.5187 15.6605 20.7763 15.6605H19.0064V23.1577ZM27.4544 24.5V16.8636H28.9409V24.5H27.4544ZM28.2051 15.6854C27.9466 15.6854 27.7245 15.5992 27.5389 15.4268C27.3566 15.2512 27.2654 15.0424 27.2654 14.8004C27.2654 14.5552 27.3566 14.3464 27.5389 14.174C27.7245 13.9983 27.9466 13.9105 28.2051 13.9105C28.4636 13.9105 28.684 13.9983 28.8663 14.174C29.0519 14.3464 29.1447 14.5552 29.1447 14.8004C29.1447 15.0424 29.0519 15.2512 28.8663 15.4268C28.684 15.5992 28.4636 15.6854 28.2051 15.6854ZM36.663 18.728L35.3157 18.9666C35.2594 18.7943 35.1699 18.6302 35.0472 18.4744C34.9279 18.3187 34.7655 18.1911 34.56 18.0916C34.3545 17.9922 34.0977 17.9425 33.7894 17.9425C33.3685 17.9425 33.0172 18.0369 32.7354 18.2259C32.4537 18.4115 32.3129 18.6518 32.3129 18.9467C32.3129 19.2019 32.4073 19.4074 32.5962 19.5632C32.7852 19.719 33.0901 19.8466 33.511 19.946L34.7241 20.2244C35.4267 20.3868 35.9504 20.6371 36.2951 20.9751C36.6398 21.3132 36.8121 21.7524 36.8121 22.2926C36.8121 22.75 36.6796 23.1577 36.4144 23.5156C36.1526 23.8703 35.7863 24.1487 35.3157 24.3509C34.8484 24.553 34.3065 24.6541 33.69 24.6541C32.8349 24.6541 32.1372 24.4718 31.5969 24.1072C31.0567 23.7393 30.7253 23.2173 30.6026 22.5412L32.0394 22.3224C32.1289 22.697 32.3129 22.9804 32.5913 23.1726C32.8697 23.3615 33.2326 23.456 33.68 23.456C34.1673 23.456 34.5567 23.3549 34.8484 23.1527C35.14 22.9472 35.2859 22.697 35.2859 22.402C35.2859 22.1634 35.1964 21.9628 35.0174 21.8004C34.8417 21.638 34.5716 21.5154 34.207 21.4325L32.9144 21.1491C32.2018 20.9867 31.6748 20.7282 31.3335 20.3736C30.9954 20.0189 30.8263 19.5698 30.8263 19.0263C30.8263 18.5755 30.9523 18.1811 31.2042 17.843C31.4561 17.505 31.8041 17.2415 32.2482 17.0526C32.6924 16.8603 33.2011 16.7642 33.7745 16.7642C34.5998 16.7642 35.2494 16.9432 35.7234 17.3011C36.1973 17.6558 36.5105 18.1314 36.663 18.728ZM40.6689 24.669C40.185 24.669 39.7475 24.5795 39.3564 24.4006C38.9653 24.2183 38.6554 23.9548 38.4267 23.6101C38.2013 23.2654 38.0886 22.8428 38.0886 22.3423C38.0886 21.9115 38.1715 21.5568 38.3372 21.2784C38.5029 21 38.7266 20.7796 39.0083 20.6172C39.2901 20.4548 39.6049 20.3321 39.9529 20.2493C40.301 20.1664 40.6556 20.1035 41.0169 20.0604C41.4743 20.0073 41.8455 19.9643 42.1305 19.9311C42.4155 19.8946 42.6227 19.8366 42.752 19.7571C42.8812 19.6776 42.9458 19.5483 42.9458 19.3693V19.3345C42.9458 18.9003 42.8232 18.5639 42.5779 18.3253C42.336 18.0866 41.9747 17.9673 41.4941 17.9673C40.9937 17.9673 40.5993 18.0784 40.3109 18.3004C40.0259 18.5192 39.8287 18.7628 39.7193 19.0312L38.3223 18.7131C38.488 18.2491 38.7299 17.8745 39.0481 17.5895C39.3696 17.3011 39.7392 17.0923 40.1568 16.9631C40.5744 16.8305 41.0136 16.7642 41.4743 16.7642C41.7792 16.7642 42.1023 16.8007 42.4437 16.8736C42.7884 16.9432 43.1099 17.0724 43.4082 17.2614C43.7098 17.4503 43.9567 17.7204 44.149 18.0717C44.3412 18.4197 44.4373 18.8722 44.4373 19.429V24.5H42.9856V23.456H42.926C42.8298 23.6482 42.6857 23.8371 42.4934 24.0227C42.3012 24.2083 42.0543 24.3625 41.7527 24.4851C41.4511 24.6077 41.0898 24.669 40.6689 24.669ZM40.992 23.4759C41.403 23.4759 41.7543 23.3946 42.046 23.2322C42.341 23.0698 42.5647 22.8577 42.7172 22.5959C42.8729 22.3307 42.9508 22.0473 42.9508 21.7457V20.7614C42.8978 20.8144 42.795 20.8641 42.6426 20.9105C42.4934 20.9536 42.3227 20.9917 42.1305 21.0249C41.9383 21.0547 41.751 21.0829 41.5687 21.1094C41.3864 21.1326 41.234 21.1525 41.1113 21.169C40.823 21.2055 40.5595 21.2668 40.3208 21.353C40.0855 21.4392 39.8966 21.5634 39.7541 21.7259C39.6149 21.8849 39.5453 22.0971 39.5453 22.3622C39.5453 22.7301 39.6812 23.0085 39.9529 23.1974C40.2247 23.383 40.5711 23.4759 40.992 23.4759ZM46.5366 24.5V14.3182H48.0231V18.1016H48.1126C48.1987 17.9425 48.323 17.7585 48.4854 17.5497C48.6478 17.3409 48.8732 17.1586 49.1616 17.0028C49.4499 16.8438 49.8311 16.7642 50.305 16.7642C50.9215 16.7642 51.4717 16.92 51.9556 17.2315C52.4395 17.5431 52.819 17.9922 53.0941 18.5788C53.3725 19.1655 53.5117 19.8714 53.5117 20.6967C53.5117 21.522 53.3742 22.2296 53.0991 22.8196C52.824 23.4062 52.4461 23.8587 51.9656 24.1768C51.485 24.4917 50.9364 24.6491 50.32 24.6491C49.8559 24.6491 49.4764 24.5713 49.1815 24.4155C48.8898 24.2597 48.6611 24.0774 48.4954 23.8686C48.3297 23.6598 48.2021 23.4742 48.1126 23.3118H47.9883V24.5H46.5366ZM47.9933 20.6818C47.9933 21.2187 48.0711 21.6894 48.2269 22.0938C48.3827 22.4981 48.6081 22.8146 48.9031 23.0433C49.198 23.2687 49.5593 23.3814 49.9869 23.3814C50.431 23.3814 50.8022 23.2637 51.1005 23.0284C51.3988 22.7898 51.6242 22.4666 51.7766 22.0589C51.9324 21.6513 52.0103 21.1922 52.0103 20.6818C52.0103 20.178 51.9341 19.7256 51.7816 19.3246C51.6325 18.9235 51.4071 18.607 51.1055 18.375C50.8072 18.143 50.4343 18.027 49.9869 18.027C49.556 18.027 49.1914 18.138 48.8931 18.3601C48.5981 18.5821 48.3744 18.892 48.2219 19.2898C48.0695 19.6875 47.9933 20.1515 47.9933 20.6818ZM56.6674 14.3182V24.5H55.1809V14.3182H56.6674ZM61.9585 24.6541C61.2061 24.6541 60.5581 24.4934 60.0146 24.1719C59.4743 23.8471 59.0567 23.3913 58.7617 22.8047C58.4701 22.2147 58.3242 21.5237 58.3242 20.7315C58.3242 19.9493 58.4701 19.2599 58.7617 18.6634C59.0567 18.0668 59.4677 17.6011 59.9947 17.2663C60.525 16.9316 61.1448 16.7642 61.854 16.7642C62.2849 16.7642 62.7025 16.8355 63.1069 16.978C63.5112 17.1205 63.8742 17.3442 64.1957 17.6491C64.5172 17.9541 64.7707 18.3501 64.9563 18.8374C65.1419 19.3213 65.2347 19.9096 65.2347 20.6023V21.1293H59.1644V20.0156H63.7781C63.7781 19.6245 63.6985 19.2782 63.5394 18.9766C63.3803 18.6716 63.1566 18.4313 62.8683 18.2557C62.5832 18.08 62.2485 17.9922 61.864 17.9922C61.4464 17.9922 61.0818 18.0949 60.7702 18.3004C60.462 18.5026 60.2234 18.7678 60.0543 19.0959C59.8886 19.4207 59.8058 19.7737 59.8058 20.1548V21.0249C59.8058 21.5353 59.8952 21.9695 60.0742 22.3274C60.2565 22.6854 60.5101 22.9588 60.8349 23.1477C61.1597 23.3333 61.5392 23.4261 61.9734 23.4261C62.2551 23.4261 62.512 23.3864 62.744 23.3068C62.976 23.224 63.1765 23.1013 63.3455 22.9389C63.5146 22.7765 63.6438 22.576 63.7333 22.3374L65.1403 22.5909C65.0276 23.0052 64.8254 23.3681 64.5337 23.6797C64.2454 23.9879 63.8825 24.2282 63.445 24.4006C63.0108 24.5696 62.5153 24.6541 61.9585 24.6541ZM69.7427 24.6491C69.1262 24.6491 68.5761 24.4917 68.0922 24.1768C67.6116 23.8587 67.2337 23.4062 66.9586 22.8196C66.6868 22.2296 66.551 21.522 66.551 20.6967C66.551 19.8714 66.6885 19.1655 66.9636 18.5788C67.242 17.9922 67.6232 17.5431 68.1071 17.2315C68.591 16.92 69.1395 16.7642 69.7527 16.7642C70.2266 16.7642 70.6078 16.8438 70.8961 17.0028C71.1878 17.1586 71.4132 17.3409 71.5723 17.5497C71.7347 17.7585 71.8606 17.9425 71.9501 18.1016H72.0396V14.3182H73.5261V24.5H72.0744V23.3118H71.9501C71.8606 23.4742 71.7314 23.6598 71.5623 23.8686C71.3966 24.0774 71.1679 24.2597 70.8762 24.4155C70.5846 24.5713 70.2067 24.6491 69.7427 24.6491ZM70.0708 23.3814C70.4984 23.3814 70.8597 23.2687 71.1547 23.0433C71.4529 22.8146 71.6783 22.4981 71.8308 22.0938C71.9866 21.6894 72.0645 21.2187 72.0645 20.6818C72.0645 20.1515 71.9882 19.6875 71.8358 19.2898C71.6833 18.892 71.4596 18.5821 71.1646 18.3601C70.8696 18.138 70.505 18.027 70.0708 18.027C69.6234 18.027 69.2505 18.143 68.9522 18.375C68.6539 18.607 68.4286 18.9235 68.2761 19.3246C68.127 19.7256 68.0524 20.178 68.0524 20.6818C68.0524 21.1922 68.1286 21.6513 68.2811 22.0589C68.4335 22.4666 68.6589 22.7898 68.9572 23.0284C69.2588 23.2637 69.63 23.3814 70.0708 23.3814Z" fill="#8E9192"/>
+</g>
+</svg>
diff --git a/assets/svg/dollar-sign-circle.svg b/assets/svg/dollar-sign-circle.svg
new file mode 100644
index 000000000..03aacffea
--- /dev/null
+++ b/assets/svg/dollar-sign-circle.svg
@@ -0,0 +1,4 @@
+<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="48" height="48" rx="24" fill="#E0E3E3"/>
+<path d="M23.659 10.0005C24.8164 10.0005 25.7475 10.9367 25.7475 12.1005V13.483C26.8701 13.623 27.9926 13.973 29.089 14.2792C30.2029 14.5855 30.8555 15.7405 30.5423 16.8605C30.2377 17.9805 29.089 18.6367 27.9752 18.3217C27.1485 18.0942 26.3218 17.8492 25.4777 17.683C24.2073 17.438 22.7279 17.5517 21.5358 18.0767C20.4654 18.5405 19.5865 19.6605 20.7961 20.4392C21.9448 21.183 23.3893 21.4805 24.6772 21.8567C26.1913 22.2855 28.1144 22.8367 29.5589 23.8255C31.4386 25.1205 32.3175 27.2205 31.8998 29.478C31.5082 31.6567 29.994 33.0917 28.184 33.8267C27.4357 34.133 26.609 34.2467 25.7475 34.4217V35.9005C25.7475 37.0642 24.8164 38.0005 23.659 38.0005C22.5017 38.0005 21.5706 37.0642 21.5706 35.9005L21.4923 34.2117C20.1696 33.8967 18.7947 33.4417 17.4372 32.9955C16.3407 32.628 15.749 31.438 16.1058 30.3442C16.4713 29.2417 17.5764 28.6467 18.7425 29.0055C20.0738 29.443 21.4313 29.968 22.8063 30.178C24.4509 30.423 25.7649 30.2742 26.6264 29.9242C27.7838 29.4605 28.332 28.078 27.2007 27.2905C26.0347 26.4942 24.5379 26.1792 23.2065 25.803C21.7446 25.383 19.9259 24.8667 18.551 23.983C16.6627 22.7667 15.7055 20.7367 16.1145 18.5055C16.4974 16.3792 18.142 14.9705 19.8737 14.218C20.4045 13.9905 20.9788 13.8067 21.4923 13.6667V12.1005C21.4923 10.9367 22.5017 10.0005 23.5807 10.0005H23.659Z" fill="#232323"/>
+</svg>
diff --git a/assets/svg/language-circle.svg b/assets/svg/language-circle.svg
new file mode 100644
index 000000000..700ffede4
--- /dev/null
+++ b/assets/svg/language-circle.svg
@@ -0,0 +1,11 @@
+<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="48" height="48" rx="24" fill="#E0E3E3"/>
+<g clip-path="url(#clip0_5784_28907)">
+<path d="M29.602 20.0474C30.0832 20.0474 30.477 20.3954 30.477 20.9067V21.0786H33.102C33.5832 21.0786 33.977 21.4267 33.977 21.938C33.977 22.4106 33.5832 22.7974 33.102 22.7974H33.0145L32.9445 22.9907C32.5551 24.0048 31.9601 24.9931 31.2076 25.8009C31.247 25.8224 31.2863 25.8095 31.3257 25.8696L32.1526 26.3552C32.5682 26.6001 32.6995 27.1286 32.4501 27.5368C32.2051 27.945 31.667 28.0739 31.2513 27.829L30.4245 27.3435C30.232 27.2274 30.0001 27.1071 29.8513 26.9782C29.392 27.3005 28.8932 27.5798 28.3682 27.8118L28.2063 27.8806C27.7645 28.0739 27.2482 27.8763 27.0513 27.4423C26.8545 27.0083 27.0557 26.5013 27.4976 26.3079L27.6551 26.2392C27.9351 26.1146 28.2063 25.9384 28.4645 25.8181L27.9351 25.2938C27.5895 24.9587 27.5895 24.4173 27.9351 24.0821C28.2763 23.7427 28.8276 23.7427 29.1688 24.0821L29.8076 24.7052L29.8338 24.6923C30.3763 24.1681 30.8182 23.5149 31.1376 22.7587H26.452C25.9313 22.7587 25.577 22.4106 25.577 21.8993C25.577 21.4267 25.9313 21.0399 26.452 21.0399H28.727V20.8681C28.727 20.3954 29.0813 20.0087 29.602 20.0087V20.0474ZM17.002 23.0208L17.8332 24.8599H16.1313L17.002 23.0208ZM10.002 18.5005C10.002 16.9815 11.2554 15.7505 12.802 15.7505H35.202C36.7463 15.7505 38.002 16.9815 38.002 18.5005V29.5005C38.002 31.0173 36.7463 32.2505 35.202 32.2505H12.802C11.2554 32.2505 10.002 31.0173 10.002 29.5005V18.5005ZM24.002 29.5005H35.202V18.5005H24.002V29.5005ZM17.8026 20.5587C17.6626 20.2493 17.3476 20.0474 17.002 20.0474C16.6563 20.0474 16.3413 20.2493 16.2013 20.5587L13.4022 26.7462C13.2062 27.1415 13.4048 27.6872 13.8467 27.8806C14.2881 28.0739 14.8057 27.8763 15.0026 27.4423L15.392 26.5399H18.612L19.0013 27.4423C19.1982 27.8763 19.7145 28.0739 20.1563 27.8806C20.5982 27.6872 20.7995 27.1415 20.6026 26.7462L17.8026 20.5587Z" fill="#232323"/>
+</g>
+<defs>
+<clipPath id="clip0_5784_28907">
+<rect width="28" height="22" fill="white" transform="translate(10.002 13.0005)"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/assets/svg/lock-circle.svg b/assets/svg/lock-circle.svg
new file mode 100644
index 000000000..f8fd71831
--- /dev/null
+++ b/assets/svg/lock-circle.svg
@@ -0,0 +1,11 @@
+<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="48" height="48" rx="24" fill="#E0E3E3"/>
+<g clip-path="url(#clip0_5764_28774)">
+<path d="M24 10.9995C28.2589 10.9995 31.7143 14.254 31.7143 18.2687V20.6918H32.5714C34.4625 20.6918 36 22.1406 36 23.9226V33.6149C36 35.3969 34.4625 36.8457 32.5714 36.8457H15.4286C13.5348 36.8457 12 35.3969 12 33.6149V23.9226C12 22.1406 13.5348 20.6918 15.4286 20.6918H16.2857V18.2687C16.2857 14.254 19.7411 10.9995 24 10.9995ZM24 14.2303C21.6321 14.2303 19.7143 16.0385 19.7143 18.2687V20.6918H28.2857V18.2687C28.2857 16.0385 26.3679 14.2303 24 14.2303ZM25.7143 27.1534C25.7143 26.2598 24.9482 25.538 24 25.538C23.0518 25.538 22.2857 26.2598 22.2857 27.1534V30.3841C22.2857 31.2776 23.0518 31.9995 24 31.9995C24.9482 31.9995 25.7143 31.2776 25.7143 30.3841V27.1534Z" fill="#232323"/>
+</g>
+<defs>
+<clipPath id="clip0_5764_28774">
+<rect width="24" height="25.8462" fill="white" transform="translate(12 10.9995)"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/assets/svg/rotate-circle.svg b/assets/svg/rotate-circle.svg
new file mode 100644
index 000000000..1940da5f5
--- /dev/null
+++ b/assets/svg/rotate-circle.svg
@@ -0,0 +1,4 @@
+<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="48" height="48" rx="24" fill="#E0E3E3"/>
+<path d="M32.25 17.5031V15.75C32.25 14.9217 32.9203 14.25 33.75 14.25C34.5797 14.25 35.25 14.9217 35.25 15.75V21C35.25 21.8297 34.5797 22.5 33.75 22.5H32.5219C32.4984 22.5 32.475 22.5 32.4516 22.5H28.5C27.6703 22.5 27 21.8297 27 21C27 20.1703 27.6703 19.5 28.5 19.5H30C28.6313 17.6766 26.4516 16.5 23.9578 16.5C20.7375 16.5 17.9578 18.5859 16.9266 21.5016C16.6505 22.2797 15.7931 22.6922 15.0122 22.4156C14.2313 22.1391 13.8216 21.2391 14.0977 20.4984C15.5386 16.4241 19.425 13.5 23.9578 13.5C27.3469 13.5 30.2859 15.0666 32.25 17.5031ZM14.25 33.75C13.4217 33.75 12.75 33.0797 12.75 32.25V27C12.75 26.1703 13.4217 25.5 14.25 25.5H19.5C20.3297 25.5 21 26.1703 21 27C21 27.8297 20.3297 28.5 19.5 28.5H17.9578C19.3687 30.3234 21.5484 31.5 24 31.5C27.2625 31.5 30.0422 29.4141 31.0734 26.4984C31.35 25.7203 32.2078 25.3078 32.9859 25.5844C33.7688 25.8609 34.1766 26.7188 33.9 27.5016C32.4609 31.575 28.575 34.5 24 34.5C20.6531 34.5 17.6719 32.9344 15.75 30.4969V32.25C15.75 33.0797 15.0783 33.75 14.25 33.75Z" fill="#232323"/>
+</svg>
diff --git a/assets/svg/sun-circle.svg b/assets/svg/sun-circle.svg
new file mode 100644
index 000000000..eba7d031d
--- /dev/null
+++ b/assets/svg/sun-circle.svg
@@ -0,0 +1,11 @@
+<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="48" height="48" rx="24" fill="#E0E3E3"/>
+<g clip-path="url(#clip0_5813_29015)">
+<path d="M16.5734 18.4328C16.8289 18.6892 17.1657 18.8173 17.5015 18.8173C17.8373 18.8173 18.1758 18.6898 18.4328 18.4328C18.9455 17.9201 18.9455 17.0897 18.4328 16.5773L15.9555 14.0999C15.4445 13.5872 14.6123 13.5872 14.0994 14.0999C13.5864 14.6126 13.5867 15.443 14.0994 15.956L16.5734 18.4328ZM24 16.125C24.7246 16.125 25.3125 15.5371 25.3125 14.8125V11.3125C25.3125 10.5879 24.7273 10 24 10C23.2727 10 22.6875 10.5879 22.6875 11.3125V14.8125C22.6875 15.5398 23.2781 16.125 24 16.125ZM16.125 24C16.125 23.2754 15.5371 22.6875 14.8125 22.6875H11.3125C10.5879 22.6875 10 23.2781 10 24C10 24.7219 10.5879 25.3125 11.3125 25.3125H14.8125C15.5398 25.3125 16.125 24.7273 16.125 24ZM30.4969 18.8156C30.8327 18.8156 31.1695 18.6874 31.4249 18.4311L33.8995 15.9549C34.4122 15.4422 34.4122 14.6117 33.8995 14.0988C33.3868 13.5858 32.5548 13.5861 32.0434 14.0988L29.5688 16.575C29.0561 17.0877 29.0561 17.9181 29.5688 18.4306C29.8242 18.6898 30.1633 18.8156 30.4969 18.8156ZM24 31.875C23.2754 31.875 22.6875 32.4629 22.6875 33.1875V36.6875C22.6875 37.4148 23.2781 38 24 38C24.7219 38 25.3125 37.4121 25.3125 36.6875V33.1875C25.3125 32.4656 24.7273 31.875 24 31.875ZM16.5734 29.5672L14.0988 32.0434C13.5861 32.5561 13.5861 33.3866 14.0988 33.8995C14.3552 34.1559 14.6911 34.284 15.0269 34.284C15.3627 34.284 15.6995 34.1559 15.9549 33.8995L18.4295 31.4233C18.9422 30.9106 18.9422 30.0802 18.4295 29.5677C17.9168 29.0553 17.0875 29.0531 16.5734 29.5672ZM36.6875 22.6875H33.1875C32.4629 22.6875 31.875 23.2754 31.875 24C31.875 24.7246 32.4629 25.3125 33.1875 25.3125H36.6875C37.4148 25.3125 38 24.7273 38 24C38 23.2727 37.4148 22.6875 36.6875 22.6875ZM31.4266 29.5672C30.9156 29.0545 30.0834 29.0547 29.5705 29.5674C29.0575 30.0801 29.0578 30.9105 29.5705 31.4229L32.0451 33.8992C32.3006 34.1555 32.6373 34.2837 32.9731 34.2837C33.3089 34.2837 33.6447 34.1555 33.9012 33.8992C34.4139 33.3865 34.4139 32.556 33.9012 32.0431L31.4266 29.5672ZM24 17.875C20.6148 17.875 17.875 20.6148 17.875 24C17.875 27.383 20.617 30.125 24 30.125C27.383 30.125 30.125 27.383 30.125 24C30.125 20.6148 27.3852 17.875 24 17.875Z" fill="#232323"/>
+</g>
+<defs>
+<clipPath id="clip0_5813_29015">
+<rect width="28" height="28" fill="white" transform="translate(10 10)"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart
new file mode 100644
index 000000000..e470a73aa
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart
@@ -0,0 +1,104 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class AdvancedSettings extends ConsumerStatefulWidget {
+  const AdvancedSettings({Key? key}) : super(key: key);
+
+  static const String routeName = "/settingsMenuAdvanced";
+
+  @override
+  ConsumerState<AdvancedSettings> createState() => _AdvancedSettings();
+}
+
+class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return Column(
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.circleLanguage,
+                  width: 48,
+                  height: 48,
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.stretch,
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.all(10),
+                      child: RichText(
+                        textAlign: TextAlign.start,
+                        text: TextSpan(
+                          children: [
+                            TextSpan(
+                              text: "Advanced",
+                              style: STextStyles.desktopTextSmall(context),
+                            ),
+                            TextSpan(
+                              text:
+                                  "\n\nConfigurate these settings only if you know what you are doing!",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: ShowLogsButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class ShowLogsButton extends ConsumerWidget {
+  const ShowLogsButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {},
+        child: Text(
+          "Show logs",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
new file mode 100644
index 000000000..c0b2c0ca5
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
@@ -0,0 +1,71 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class AppearanceOptionSettings extends ConsumerStatefulWidget {
+  const AppearanceOptionSettings({Key? key}) : super(key: key);
+
+  static const String routeName = "/settingsMenuAppearance";
+
+  @override
+  ConsumerState<AppearanceOptionSettings> createState() =>
+      _AppearanceOptionSettings();
+}
+
+class _AppearanceOptionSettings
+    extends ConsumerState<AppearanceOptionSettings> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return Column(
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.circleSun,
+                  width: 48,
+                  height: 48,
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.stretch,
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.all(10),
+                      child: RichText(
+                        textAlign: TextAlign.left,
+                        text: TextSpan(
+                          children: [
+                            TextSpan(
+                              text: "Appearances",
+                              style: STextStyles.desktopTextSmall(context),
+                            ),
+                            TextSpan(
+                              text:
+                                  "\n\nCustomize how your Stack Wallet looks according to your preferences.",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart
similarity index 93%
rename from lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart
rename to lib/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart
index 37b27bb97..04c23ee83 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart
@@ -8,16 +8,17 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:url_launcher/url_launcher.dart';
 
-class BackupRestore extends ConsumerStatefulWidget {
-  const BackupRestore({Key? key}) : super(key: key);
+class BackupRestoreSettings extends ConsumerStatefulWidget {
+  const BackupRestoreSettings({Key? key}) : super(key: key);
 
-  static const String routeName = "/backupRestore";
+  static const String routeName = "/settingsMenuBackupRestore";
 
   @override
-  ConsumerState<BackupRestore> createState() => _BackupRestore();
+  ConsumerState<BackupRestoreSettings> createState() =>
+      _BackupRestoreSettings();
 }
 
-class _BackupRestore extends ConsumerState<BackupRestore> {
+class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
@@ -37,7 +38,6 @@ class _BackupRestore extends ConsumerState<BackupRestore> {
                   Assets.svg.backupAuto,
                   width: 48,
                   height: 48,
-                  alignment: Alignment.topLeft,
                 ),
                 Center(
                   child: Padding(
@@ -52,7 +52,7 @@ class _BackupRestore extends ConsumerState<BackupRestore> {
                           ),
                           TextSpan(
                             text:
-                                "\n\nAuto Backup is a custom Stack Wallet feature that offers a convenient backup of your data."
+                                "\n\nAuto backup is a custom Stack Wallet feature that offers a convenient backup of your data."
                                 "To ensure maximum security, we recommend using a unique password that you haven't used anywhere "
                                 "else on the internet before. Your password is not stored.",
                             style:
@@ -126,7 +126,7 @@ class _BackupRestore extends ConsumerState<BackupRestore> {
                           ),
                           TextSpan(
                             text:
-                                "\n\nCreate Manual backup to easily transfer your data between devices. "
+                                "\n\nCreate manual backup to easily transfer your data between devices. "
                                 "You will create a backup file that can be later used in the Restore option. "
                                 "Use a strong password to encrypt your data.",
                             style:
@@ -227,7 +227,7 @@ class AutoBackupButton extends ConsumerWidget {
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {},
         child: Text(
-          "Enable Auto Backup",
+          "Enable auto backup",
           style: STextStyles.button(context),
         ),
       ),
@@ -250,7 +250,7 @@ class ManualBackupButton extends ConsumerWidget {
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {},
         child: Text(
-          "Create Manual Backup",
+          "Create manual backup",
           style: STextStyles.button(context),
         ),
       ),
@@ -273,7 +273,7 @@ class RestoreBackupButton extends ConsumerWidget {
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {},
         child: Text(
-          "Restore Backup",
+          "Restore backup",
           style: STextStyles.button(context),
         ),
       ),
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings.dart
new file mode 100644
index 000000000..4327b320b
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings.dart
@@ -0,0 +1,102 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class CurrencySettings extends ConsumerStatefulWidget {
+  const CurrencySettings({Key? key}) : super(key: key);
+
+  static const String routeName = "/settingsMenuCurrency";
+
+  @override
+  ConsumerState<CurrencySettings> createState() => _CurrencySettings();
+}
+
+class _CurrencySettings extends ConsumerState<CurrencySettings> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return Column(
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.circleDollarSign,
+                  width: 48,
+                  height: 48,
+                ),
+                Center(
+                  child: Padding(
+                    padding: const EdgeInsets.all(10),
+                    child: RichText(
+                      textAlign: TextAlign.start,
+                      text: TextSpan(
+                        children: [
+                          TextSpan(
+                            text: "Currency",
+                            style: STextStyles.desktopTextSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nProtect your Stack Wallet with a strong password. Stack Wallet does not store "
+                                "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: NewPasswordButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class NewPasswordButton extends ConsumerWidget {
+  const NewPasswordButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {},
+        child: Text(
+          "Set up new password",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings.dart
new file mode 100644
index 000000000..7655188e1
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings.dart
@@ -0,0 +1,105 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class LanguageOptionSettings extends ConsumerStatefulWidget {
+  const LanguageOptionSettings({Key? key}) : super(key: key);
+
+  static const String routeName = "/settingsMenuLanguage";
+
+  @override
+  ConsumerState<LanguageOptionSettings> createState() =>
+      _LanguageOptionSettings();
+}
+
+class _LanguageOptionSettings extends ConsumerState<LanguageOptionSettings> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return Column(
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.circleLanguage,
+                  width: 48,
+                  height: 48,
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.stretch,
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.all(10),
+                      child: RichText(
+                        textAlign: TextAlign.start,
+                        text: TextSpan(
+                          children: [
+                            TextSpan(
+                              text: "Language",
+                              style: STextStyles.desktopTextSmall(context),
+                            ),
+                            TextSpan(
+                              text:
+                                  "\n\nSelect the language of your wallet. We use your system language by default.",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: ChangeLanguageButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class ChangeLanguageButton extends ConsumerWidget {
+  const ChangeLanguageButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {},
+        child: Text(
+          "Change language",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
new file mode 100644
index 000000000..febb1dc1b
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -0,0 +1,102 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class SecuritySettings extends ConsumerStatefulWidget {
+  const SecuritySettings({Key? key}) : super(key: key);
+
+  static const String routeName = "/settingsMenuSecurity";
+
+  @override
+  ConsumerState<SecuritySettings> createState() => _SecuritySettings();
+}
+
+class _SecuritySettings extends ConsumerState<SecuritySettings> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return Column(
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.circleLock,
+                  width: 48,
+                  height: 48,
+                ),
+                Center(
+                  child: Padding(
+                    padding: const EdgeInsets.all(10),
+                    child: RichText(
+                      textAlign: TextAlign.start,
+                      text: TextSpan(
+                        children: [
+                          TextSpan(
+                            text: "Change Password",
+                            style: STextStyles.desktopTextSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nProtect your Stack Wallet with a strong password. Stack Wallet does not store "
+                                "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: NewPasswordButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class NewPasswordButton extends ConsumerWidget {
+  const NewPasswordButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {},
+        child: Text(
+          "Set up new password",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
new file mode 100644
index 000000000..9b6c6c85c
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
@@ -0,0 +1,106 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class SyncingPreferencesSettings extends ConsumerStatefulWidget {
+  const SyncingPreferencesSettings({Key? key}) : super(key: key);
+
+  static const String routeName = "/settingsMenuSyncingPref";
+
+  @override
+  ConsumerState<SyncingPreferencesSettings> createState() =>
+      _SyncingPreferencesSettings();
+}
+
+class _SyncingPreferencesSettings
+    extends ConsumerState<SyncingPreferencesSettings> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return Column(
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.circleArrowRotate,
+                  width: 48,
+                  height: 48,
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.stretch,
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.all(10),
+                      child: RichText(
+                        textAlign: TextAlign.start,
+                        text: TextSpan(
+                          children: [
+                            TextSpan(
+                              text: "Syncing Preferences",
+                              style: STextStyles.desktopTextSmall(context),
+                            ),
+                            TextSpan(
+                              text:
+                                  "\nSet up your syncing preferences for all wallets in your Stack.",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: ChangePrefButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class ChangePrefButton extends ConsumerWidget {
+  const ChangePrefButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {},
+        child: Text(
+          "Change preferences",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 4a7f54e8e..e2d91a08e 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -87,8 +87,14 @@ import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
 import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
@@ -959,11 +965,11 @@ class RouteGenerator {
             builder: (_) => const DesktopHomeView(),
             settings: RouteSettings(name: settings.name));
 
-      // case DesktopSettingsView.routeName:
-      //   return getRoute(
-      //       shouldUseMaterialRoute: useMaterialPageRoute,
-      //       builder: (_) => const DesktopSettingsView(),
-      //       settings: RouteSettings(name: settings.name));
+      case DesktopSettingsView.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const DesktopSettingsView(),
+            settings: RouteSettings(name: settings.name));
 
       case MyStackView.routeName:
         return getRoute(
@@ -993,10 +999,46 @@ class RouteGenerator {
                 ),
             settings: RouteSettings(name: settings.name));
 
-      case BackupRestore.routeName:
+      case BackupRestoreSettings.routeName:
         return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const BackupRestore(),
+            builder: (_) => const BackupRestoreSettings(),
+            settings: RouteSettings(name: settings.name));
+
+      case SecuritySettings.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const SecuritySettings(),
+            settings: RouteSettings(name: settings.name));
+
+      case CurrencySettings.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const CurrencySettings(),
+            settings: RouteSettings(name: settings.name));
+
+      case LanguageOptionSettings.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const LanguageOptionSettings(),
+            settings: RouteSettings(name: settings.name));
+
+      case SyncingPreferencesSettings.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const SyncingPreferencesSettings(),
+            settings: RouteSettings(name: settings.name));
+
+      case AppearanceOptionSettings.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const AppearanceOptionSettings(),
+            settings: RouteSettings(name: settings.name));
+
+      case AdvancedSettings.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const AdvancedSettings(),
             settings: RouteSettings(name: settings.name));
 
       // == End of desktop specific routes =====================================
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 1410d6442..5ceaabcb4 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -59,6 +59,12 @@ class _SVG {
   String txExchangeFailed(BuildContext context) =>
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
 
+  String get circleSun => "assets/svg/sun-circle.svg";
+  String get circleArrowRotate => "assets/svg/rotate-circle.svg";
+  String get circleLanguage => "assets/svg/language-circle.svg";
+  String get circleDollarSign => "assets/svg/dollar-sign-circle.svg";
+  String get circleLock => "assets/svg/lock-circle.svg";
+  String get disableButton => "assets/svg/Button.svg";
   String get polygon => "assets/svg/Polygon.svg";
   String get personaIncognito => "assets/svg/persona-incognito-1.svg";
   String get personaEasy => "assets/svg/persona-easy-1.svg";

From 82cc2209552150803d67bc309b59aa1ca4cd777a Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 19 Oct 2022 16:12:25 -0600
Subject: [PATCH 023/426] settings option routes were added

---
 .../home/desktop_settings_view.dart           | 46 +++++++++++++------
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index cd11eff3d..f7927a01a 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -1,7 +1,13 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -24,28 +30,40 @@ class _DesktopSettingsViewState extends ConsumerState<DesktopSettingsView> {
     const Navigator(
       key: Key("settingsBackupRestoreDesktopKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
-      initialRoute: BackupRestore.routeName,
+      initialRoute: BackupRestoreSettings.routeName,
     ), //b+r
-    Container(
-      color: Colors.green,
+    const Navigator(
+      key: Key("settingsSecurityDesktopKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: SecuritySettings.routeName,
     ), //security
-    Container(
-      color: Colors.red,
+    const Navigator(
+      key: Key("settingsCurrencyDesktopKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: CurrencySettings.routeName,
     ), //currency
-    Container(
-      color: Colors.orange,
+    const Navigator(
+      key: Key("settingsCurrencyDesktopKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: LanguageOptionSettings.routeName,
     ), //language
     Container(
       color: Colors.yellow,
     ), //nodes
-    Container(
-      color: Colors.blue,
+    const Navigator(
+      key: Key("settingsSyncingPreferencesDesktopKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: SyncingPreferencesSettings.routeName,
     ), //syncing prefs
-    Container(
-      color: Colors.pink,
+    const Navigator(
+      key: Key("settingsAppearanceDesktopKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: AppearanceOptionSettings.routeName,
     ), //appearance
-    Container(
-      color: Colors.purple,
+    const Navigator(
+      key: Key("settingsAdvancedDesktopKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: AdvancedSettings.routeName,
     ), //advanced
   ];
 

From 6ae941e2616b1ef17f5f7d00f1f293cafcd12bce Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 19 Oct 2022 16:13:27 -0600
Subject: [PATCH 024/426] settings svgs were added

---
 pubspec.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/pubspec.yaml b/pubspec.yaml
index d4d354625..a8b11c101 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -292,6 +292,12 @@ flutter:
     - assets/svg/Polygon.svg
     - assets/svg/persona-easy-1.svg
     - assets/svg/persona-incognito-1.svg
+    - assets/svg/Button.svg
+    - assets/svg/lock-circle.svg
+    - assets/svg/dollar-sign-circle.svg
+    - assets/svg/language-circle.svg
+    - assets/svg/rotate-circle.svg
+    - assets/svg/sun-circle.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Bitcoincash.svg

From b2cb194c61598a7b708bfbd74bc6234a24d4a848 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 19 Oct 2022 16:22:09 -0600
Subject: [PATCH 025/426] Marco's version updates

---
 pubspec.lock | 62 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 38 insertions(+), 24 deletions(-)

diff --git a/pubspec.lock b/pubspec.lock
index 2405aef27..1a564066d 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -42,7 +42,7 @@ packages:
       name: archive
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "3.3.0"
+    version: "3.1.11"
   args:
     dependency: transitive
     description:
@@ -63,7 +63,7 @@ packages:
       name: async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.9.0"
+    version: "2.8.2"
   barcode_scan2:
     dependency: "direct main"
     description:
@@ -190,7 +190,14 @@ packages:
       name: characters
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.2.1"
+    version: "1.2.0"
+  charcode:
+    dependency: transitive
+    description:
+      name: charcode
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.3.1"
   checked_yaml:
     dependency: transitive
     description:
@@ -204,7 +211,7 @@ packages:
       name: clock
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.1"
+    version: "1.1.0"
   code_builder:
     dependency: transitive
     description:
@@ -274,7 +281,7 @@ packages:
       name: coverage
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.5.0"
+    version: "1.2.0"
   cross_file:
     dependency: transitive
     description:
@@ -414,7 +421,7 @@ packages:
       name: fake_async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.1"
+    version: "1.3.0"
   ffi:
     dependency: "direct main"
     description:
@@ -529,7 +536,7 @@ packages:
       name: flutter_native_splash
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.2.11"
+    version: "2.2.9"
   flutter_plugin_android_lifecycle:
     dependency: transitive
     description:
@@ -802,6 +809,13 @@ packages:
       relative: true
     source: path
     version: "0.0.1"
+  lint:
+    dependency: transitive
+    description:
+      name: lint
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.10.0"
   lints:
     dependency: transitive
     description:
@@ -829,28 +843,28 @@ packages:
       name: lottie
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.4.3"
+    version: "1.4.2"
   matcher:
     dependency: transitive
     description:
       name: matcher
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.12.12"
+    version: "0.12.11"
   material_color_utilities:
     dependency: transitive
     description:
       name: material_color_utilities
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.1.5"
+    version: "0.1.4"
   meta:
     dependency: transitive
     description:
       name: meta
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.8.0"
+    version: "1.7.0"
   mime:
     dependency: transitive
     description:
@@ -962,7 +976,7 @@ packages:
       name: path
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.8.2"
+    version: "1.8.1"
   path_drawing:
     dependency: transitive
     description:
@@ -1338,7 +1352,7 @@ packages:
       name: source_span
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.9.0"
+    version: "1.8.2"
   stack_trace:
     dependency: transitive
     description:
@@ -1382,49 +1396,49 @@ packages:
       name: string_scanner
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.1"
+    version: "1.1.0"
   sync_http:
     dependency: transitive
     description:
       name: sync_http
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.3.1"
+    version: "0.3.0"
   term_glyph:
     dependency: transitive
     description:
       name: term_glyph
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.2.1"
+    version: "1.2.0"
   test:
     dependency: transitive
     description:
       name: test
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.21.4"
+    version: "1.21.1"
   test_api:
     dependency: transitive
     description:
       name: test_api
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.12"
+    version: "0.4.9"
   test_core:
     dependency: transitive
     description:
       name: test_core
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.16"
+    version: "0.4.13"
   time:
     dependency: transitive
     description:
       name: time
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.1.3"
+    version: "2.1.2"
   timezone:
     dependency: transitive
     description:
@@ -1466,7 +1480,7 @@ packages:
       name: typed_data
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.1"
+    version: "1.3.0"
   universal_io:
     dependency: transitive
     description:
@@ -1550,7 +1564,7 @@ packages:
       name: vm_service
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "9.0.0"
+    version: "8.2.2"
   wakelock:
     dependency: "direct main"
     description:
@@ -1666,5 +1680,5 @@ packages:
     source: hosted
     version: "1.0.0"
 sdks:
-  dart: ">=2.18.0 <3.0.0"
-  flutter: ">=3.3.0"
+  dart: ">=2.17.5 <3.0.0"
+  flutter: ">=3.0.1"

From 3e34f18f9c16627fddcd706079d3695186cc24d5 Mon Sep 17 00:00:00 2001
From: rehrar <diego@cypherstack.com>
Date: Thu, 20 Oct 2022 11:36:49 -0600
Subject: [PATCH 026/426] make m1 mac (ipad mode) work in desktop mode

---
 lib/main.dart           | 3 +++
 lib/utilities/util.dart | 5 +++++
 2 files changed, 8 insertions(+)

diff --git a/lib/main.dart b/lib/main.dart
index ad1ef9b7f..e1297cc5a 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -68,6 +68,9 @@ final openedFromSWBFileStringStateProvider =
 void main() async {
   WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
   GoogleFonts.config.allowRuntimeFetching = false;
+  if(Platform.isIOS){
+    Util.libraryPath = await getLibraryDirectory();
+  }
 
   if (Util.isDesktop) {
     setWindowTitle('Stack Wallet');
diff --git a/lib/utilities/util.dart b/lib/utilities/util.dart
index 8a98787f2..5963bfee9 100644
--- a/lib/utilities/util.dart
+++ b/lib/utilities/util.dart
@@ -1,9 +1,14 @@
 import 'dart:io';
 
 import 'package:flutter/material.dart';
+import 'package:path_provider/path_provider.dart';
 
 abstract class Util {
+  static Directory? libraryPath;
   static bool get isDesktop {
+    if(Platform.isIOS && libraryPath != null && !libraryPath!.path.contains("/var/mobile/")){
+      return true;
+    }
     return Platform.isLinux || Platform.isMacOS || Platform.isWindows;
   }
 

From fba7fbf1cc842976973f1cc5ad7dd372b7db9908 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 20 Oct 2022 11:54:24 -0600
Subject: [PATCH 027/426] added desktop node settings

---
 assets/svg/node-circle.svg                    |   4 +
 .../home/desktop_settings_view.dart           |   9 +-
 .../home/settings_menu/nodes_settings.dart    | 165 ++++++++++++++++++
 lib/route_generator.dart                      |   7 +
 lib/utilities/assets.dart                     |   1 +
 pubspec.yaml                                  |   1 +
 6 files changed, 184 insertions(+), 3 deletions(-)
 create mode 100644 assets/svg/node-circle.svg
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart

diff --git a/assets/svg/node-circle.svg b/assets/svg/node-circle.svg
new file mode 100644
index 000000000..bd9353a2b
--- /dev/null
+++ b/assets/svg/node-circle.svg
@@ -0,0 +1,4 @@
+<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="48" height="48" rx="24" fill="#E0E3E3"/>
+<path d="M34.5 25.5H13.5C12.6741 25.5 12 26.1741 12 27V33C12 33.8259 12.6741 34.5 13.5 34.5H34.5C35.3259 34.5 36 33.8259 36 33V27C36 26.175 35.325 25.5 34.5 25.5ZM28.5 31.125C27.8789 31.125 27.375 30.6211 27.375 30C27.375 29.3789 27.8789 28.875 28.5 28.875C29.1211 28.875 29.625 29.3789 29.625 30C29.625 30.6211 29.1234 31.125 28.5 31.125ZM31.5 31.125C30.8789 31.125 30.375 30.6211 30.375 30C30.375 29.3789 30.8789 28.875 31.5 28.875C32.1211 28.875 32.625 29.3789 32.625 30C32.625 30.6211 32.1234 31.125 31.5 31.125ZM34.5 13.5H13.5C12.6741 13.5 12 14.1741 12 15V21C12 21.8259 12.6741 22.5 13.5 22.5H34.5C35.3259 22.5 36 21.8259 36 21V15C36 14.1741 35.325 13.5 34.5 13.5ZM28.5 19.125C27.8789 19.125 27.375 18.6211 27.375 18C27.375 17.3789 27.8813 16.875 28.5 16.875C29.1187 16.875 29.625 17.3812 29.625 18C29.625 18.6188 29.1234 19.125 28.5 19.125ZM31.5 19.125C30.8789 19.125 30.375 18.6211 30.375 18C30.375 17.3789 30.8813 16.875 31.5 16.875C32.1187 16.875 32.625 17.3812 32.625 18C32.625 18.6188 32.1234 19.125 31.5 19.125Z" fill="#232323"/>
+</svg>
diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index f7927a01a..7aff94b66 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -5,6 +5,7 @@ import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart';
@@ -43,12 +44,14 @@ class _DesktopSettingsViewState extends ConsumerState<DesktopSettingsView> {
       initialRoute: CurrencySettings.routeName,
     ), //currency
     const Navigator(
-      key: Key("settingsCurrencyDesktopKey"),
+      key: Key("settingsLanguageDesktopKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: LanguageOptionSettings.routeName,
     ), //language
-    Container(
-      color: Colors.yellow,
+    const Navigator(
+      key: Key("settingsNodesDesktopKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: NodesSettings.routeName,
     ), //nodes
     const Navigator(
       key: Key("settingsSyncingPreferencesDesktopKey"),
diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
new file mode 100644
index 000000000..4227b537f
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -0,0 +1,165 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+import '../../../providers/global/node_service_provider.dart';
+import '../../../providers/global/prefs_provider.dart';
+import '../../../utilities/constants.dart';
+import '../../../utilities/enums/coin_enum.dart';
+
+class NodesSettings extends ConsumerStatefulWidget {
+  const NodesSettings({Key? key}) : super(key: key);
+
+  static const String routeName = "/settingsMenuNodes";
+
+  @override
+  ConsumerState<NodesSettings> createState() => _NodesSettings();
+}
+
+class _NodesSettings extends ConsumerState<NodesSettings> {
+  List<Coin> _coins = [...Coin.values];
+
+  @override
+  void initState() {
+    _coins = _coins.toList();
+    _coins.remove(Coin.firoTestNet);
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    bool showTestNet = ref.watch(
+      prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
+    );
+
+    List<Coin> coins = showTestNet
+        ? _coins
+        : _coins.sublist(0, _coins.length - kTestNetCoinCount);
+
+    debugPrint("BUILD: $runtimeType");
+    return Column(
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.circleNode,
+                  width: 48,
+                  height: 48,
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.stretch,
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.all(10),
+                      child: RichText(
+                        textAlign: TextAlign.start,
+                        text: TextSpan(
+                          children: [
+                            TextSpan(
+                              text: "Nodes",
+                              style: STextStyles.desktopTextSmall(context),
+                            ),
+                            TextSpan(
+                              text: "\n\nSelect a coin to see nodes",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+                SingleChildScrollView(
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.stretch,
+                    children: [
+                      ...coins.map(
+                        (coin) {
+                          final count = ref
+                              .watch(nodeServiceChangeNotifierProvider
+                                  .select((value) => value.getNodesFor(coin)))
+                              .length;
+
+                          return Padding(
+                            padding: const EdgeInsets.all(4),
+                            child: RoundedWhiteContainer(
+                              padding: const EdgeInsets.all(0),
+                              child: RawMaterialButton(
+                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                                shape: RoundedRectangleBorder(
+                                  borderRadius: BorderRadius.circular(
+                                    Constants.size.circularBorderRadius,
+                                  ),
+                                ),
+                                materialTapTargetSize:
+                                    MaterialTapTargetSize.shrinkWrap,
+                                onPressed: () {
+                                  // Navigator.of(context).pushNamed(
+                                  //   CoinNodesView.routeName,
+                                  //   arguments: coin,
+                                  // );
+                                },
+                                child: Padding(
+                                  padding: const EdgeInsets.all(12),
+                                  child: Row(
+                                    children: [
+                                      SvgPicture.asset(
+                                        Assets.svg.iconFor(coin: coin),
+                                        width: 24,
+                                        height: 24,
+                                      ),
+                                      const SizedBox(
+                                        width: 12,
+                                      ),
+                                      Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          Text(
+                                            "${coin.prettyName} nodes",
+                                            style: STextStyles.titleBold12(
+                                                context),
+                                          ),
+                                          Text(
+                                            count > 1
+                                                ? "$count nodes"
+                                                : "Default",
+                                            style: STextStyles.label(context),
+                                          ),
+                                        ],
+                                      )
+                                    ],
+                                  ),
+                                ),
+                              ),
+                            ),
+                          );
+                        },
+                      ),
+                    ],
+                  ),
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index e2d91a08e..f915e7837 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -92,6 +92,7 @@ import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart';
@@ -1023,6 +1024,12 @@ class RouteGenerator {
             builder: (_) => const LanguageOptionSettings(),
             settings: RouteSettings(name: settings.name));
 
+      case NodesSettings.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const NodesSettings(),
+            settings: RouteSettings(name: settings.name));
+
       case SyncingPreferencesSettings.routeName:
         return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 5ceaabcb4..5136f1a37 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -59,6 +59,7 @@ class _SVG {
   String txExchangeFailed(BuildContext context) =>
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
 
+  String get circleNode => "assets/svg/node-circle.svg";
   String get circleSun => "assets/svg/sun-circle.svg";
   String get circleArrowRotate => "assets/svg/rotate-circle.svg";
   String get circleLanguage => "assets/svg/language-circle.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index a8b11c101..64fe730f6 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -298,6 +298,7 @@ flutter:
     - assets/svg/language-circle.svg
     - assets/svg/rotate-circle.svg
     - assets/svg/sun-circle.svg
+    - assets/svg/node-circle.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Bitcoincash.svg

From c231758902025582ac47ec036544b05409e1fca0 Mon Sep 17 00:00:00 2001
From: rehrar <diego@cypherstack.com>
Date: Thu, 20 Oct 2022 14:19:50 -0600
Subject: [PATCH 028/426] remove suggestions and autocomplete for desktop

---
 .../add_wallet_view/add_wallet_view.dart          |  2 ++
 .../name_your_wallet_view.dart                    |  2 ++
 .../mobile_mnemonic_length_selector.dart          |  6 +++++-
 .../sub_widgets/restore_from_date_picker.dart     |  4 ++++
 .../address_book_views/address_book_view.dart     |  4 ++++
 .../subviews/add_address_book_entry_view.dart     |  4 ++++
 .../subviews/edit_contact_name_emoji_view.dart    |  4 ++++
 .../subviews/new_contact_address_entry_form.dart  |  8 +++++++-
 lib/pages/exchange_view/edit_trade_note_view.dart |  4 ++++
 .../fixed_rate_pair_coin_selection_view.dart      |  4 ++++
 .../floating_rate_currency_selection_view.dart    |  4 ++++
 .../generate_receiving_uri_qr_code_view.dart      |  5 +++++
 lib/pages/send_view/send_view.dart                | 15 ++++++++++++++-
 .../advanced_views/debug_view.dart                |  4 ++++
 .../global_settings_view/currency_view.dart       |  4 ++++
 .../global_settings_view/language_view.dart       |  4 ++++
 .../manage_nodes_views/add_edit_node_view.dart    | 12 ++++++++++++
 .../stack_backup_views/auto_backup_view.dart      |  4 ++++
 .../create_auto_backup_view.dart                  |  8 +++++++-
 .../stack_backup_views/create_backup_view.dart    |  3 +++
 .../stack_backup_views/edit_auto_backup_view.dart |  8 +++++++-
 .../restore_from_file_view.dart                   |  4 ++++
 .../wallet_settings_view.dart                     |  6 ++++++
 .../rename_wallet_view.dart                       |  4 ++++
 .../transaction_views/all_transactions_view.dart  |  4 ++++
 .../transaction_views/edit_note_view.dart         |  4 ++++
 .../transaction_search_filter_view.dart           |  4 ++++
 27 files changed, 134 insertions(+), 5 deletions(-)

diff --git a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
index ae72e1846..df5c44d18 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
@@ -90,6 +90,8 @@ class _AddWalletViewState extends State<AddWalletView> {
                             Constants.size.circularBorderRadius,
                           ),
                           child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             controller: _searchFieldController,
                             focusNode: _searchFocusNode,
                             onChanged: (value) {
diff --git a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
index f7dbe3d33..8bc01b124 100644
--- a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
+++ b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
@@ -194,6 +194,8 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
               Constants.size.circularBorderRadius,
             ),
             child: TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
               onChanged: (string) {
                 if (string.isEmpty) {
                   if (_nextEnabled) {
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/mobile_mnemonic_length_selector.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/mobile_mnemonic_length_selector.dart
index 49896e107..4f5b76fab 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/mobile_mnemonic_length_selector.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/mobile_mnemonic_length_selector.dart
@@ -7,6 +7,8 @@ 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';
+
 class MobileMnemonicLengthSelector extends ConsumerWidget {
   const MobileMnemonicLengthSelector({
     Key? key,
@@ -19,7 +21,9 @@ class MobileMnemonicLengthSelector extends ConsumerWidget {
   Widget build(BuildContext context, WidgetRef ref) {
     return Stack(
       children: [
-        const TextField(
+        TextField(
+          autocorrect: Util.isDesktop ? false : true,
+          enableSuggestions: Util.isDesktop ? false : true,
           // controller: _lengthController,
           readOnly: true,
           textInputAction: TextInputAction.none,
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_from_date_picker.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_from_date_picker.dart
index 8a24e95bb..112d50428 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_from_date_picker.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_from_date_picker.dart
@@ -4,6 +4,8 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class RestoreFromDatePicker extends StatefulWidget {
   const RestoreFromDatePicker({Key? key, required this.onTap})
       : super(key: key);
@@ -37,6 +39,8 @@ class _RestoreFromDatePickerState extends State<RestoreFromDatePicker> {
     return Container(
       color: Colors.transparent,
       child: TextField(
+        autocorrect: Util.isDesktop ? false : true,
+        enableSuggestions: Util.isDesktop ? false : true,
         onTap: onTap,
         controller: _dateController,
         style: STextStyles.field(context),
diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index b70ef19ed..c9dd72d72 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -21,6 +21,8 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class AddressBookView extends ConsumerStatefulWidget {
   const AddressBookView({Key? key, this.coin}) : super(key: key);
 
@@ -198,6 +200,8 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
                             Constants.size.circularBorderRadius,
                           ),
                           child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             controller: _searchController,
                             focusNode: _searchFocusNode,
                             onChanged: (value) {
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 4fa89908c..74f3dfde8 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
@@ -22,6 +22,8 @@ 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';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class AddAddressBookEntryView extends ConsumerStatefulWidget {
   const AddAddressBookEntryView({
     Key? key,
@@ -279,6 +281,8 @@ class _AddAddressBookEntryViewState
                           Constants.size.circularBorderRadius,
                         ),
                         child: TextField(
+                          autocorrect: Util.isDesktop ? false : true,
+                          enableSuggestions: Util.isDesktop ? false : true,
                           controller: nameController,
                           focusNode: nameFocusNode,
                           style: STextStyles.field(context),
diff --git a/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart b/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart
index 45c23b13c..fff01eee3 100644
--- a/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart
+++ b/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart
@@ -13,6 +13,8 @@ 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';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class EditContactNameEmojiView extends ConsumerStatefulWidget {
   const EditContactNameEmojiView({
     Key? key,
@@ -200,6 +202,8 @@ class _EditContactNameEmojiViewState
                             Constants.size.circularBorderRadius,
                           ),
                           child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             controller: nameController,
                             focusNode: nameFocusNode,
                             style: STextStyles.field(context),
diff --git a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
index 73de8b0aa..ce98cee10 100644
--- a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
+++ b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
@@ -20,6 +20,8 @@ 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';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class NewContactAddressEntryForm extends ConsumerStatefulWidget {
   const NewContactAddressEntryForm({
     Key? key,
@@ -71,6 +73,8 @@ class _NewContactAddressEntryFormState
     return Column(
       children: [
         TextField(
+          autocorrect: Util.isDesktop ? false : true,
+          enableSuggestions: Util.isDesktop ? false : true,
           readOnly: true,
           style: STextStyles.field(context),
           decoration: InputDecoration(
@@ -154,6 +158,8 @@ class _NewContactAddressEntryFormState
             Constants.size.circularBorderRadius,
           ),
           child: TextField(
+            autocorrect: Util.isDesktop ? false : true,
+            enableSuggestions: Util.isDesktop ? false : true,
             focusNode: addressLabelFocusNode,
             controller: addressLabelController,
             style: STextStyles.field(context),
@@ -197,6 +203,7 @@ class _NewContactAddressEntryFormState
             Constants.size.circularBorderRadius,
           ),
           child: TextField(
+            enableSuggestions: Util.isDesktop ? false : true,
             focusNode: addressFocusNode,
             controller: addressController,
             style: STextStyles.field(context),
@@ -324,7 +331,6 @@ class _NewContactAddressEntryFormState
             key: const Key("addAddressBookEntryViewAddressField"),
             readOnly: false,
             autocorrect: false,
-            enableSuggestions: false,
             // inputFormatters: <TextInputFormatter>[
             //   FilteringTextInputFormatter.allow(RegExp("[a-zA-Z0-9]{34}")),
             // ],
diff --git a/lib/pages/exchange_view/edit_trade_note_view.dart b/lib/pages/exchange_view/edit_trade_note_view.dart
index 5e1571b73..e2a72d1b4 100644
--- a/lib/pages/exchange_view/edit_trade_note_view.dart
+++ b/lib/pages/exchange_view/edit_trade_note_view.dart
@@ -9,6 +9,8 @@ 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';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class EditTradeNoteView extends ConsumerStatefulWidget {
   const EditTradeNoteView({
     Key? key,
@@ -85,6 +87,8 @@ class _EditNoteViewState extends ConsumerState<EditTradeNoteView> {
                             Constants.size.circularBorderRadius,
                           ),
                           child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             controller: _noteController,
                             style: STextStyles.field(context),
                             focusNode: noteFieldFocusNode,
diff --git a/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart b/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart
index d7577e960..80bdcda62 100644
--- a/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart
+++ b/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart
@@ -16,6 +16,8 @@ import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 import 'package:tuple/tuple.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class FixedRateMarketPairCoinSelectionView extends ConsumerStatefulWidget {
   const FixedRateMarketPairCoinSelectionView({
     Key? key,
@@ -152,6 +154,8 @@ class _FixedRateMarketPairCoinSelectionViewState
                 Constants.size.circularBorderRadius,
               ),
               child: TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
                 controller: _searchController,
                 focusNode: _searchFocusNode,
                 onChanged: filter,
diff --git a/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart b/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart
index 7c3b935b7..e1c1addd2 100644
--- a/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart
+++ b/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart
@@ -13,6 +13,8 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class FloatingRateCurrencySelectionView extends StatefulWidget {
   const FloatingRateCurrencySelectionView({
     Key? key,
@@ -108,6 +110,8 @@ class _FloatingRateCurrencySelectionViewState
                 Constants.size.circularBorderRadius,
               ),
               child: TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
                 controller: _searchController,
                 focusNode: _searchFocusNode,
                 onChanged: filter,
diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
index 744d8b53c..3e29612d1 100644
--- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
+++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
@@ -19,6 +19,7 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -160,6 +161,8 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                             Constants.size.circularBorderRadius,
                           ),
                           child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             controller: amountController,
                             focusNode: _amountFocusNode,
                             style: STextStyles.field(context),
@@ -209,6 +212,8 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                             Constants.size.circularBorderRadius,
                           ),
                           child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             controller: noteController,
                             focusNode: _noteFocusNode,
                             style: STextStyles.field(context),
diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart
index 5e689a580..d91b7a3ea 100644
--- a/lib/pages/send_view/send_view.dart
+++ b/lib/pages/send_view/send_view.dart
@@ -41,6 +41,8 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class SendView extends ConsumerStatefulWidget {
   const SendView({
     Key? key,
@@ -885,7 +887,10 @@ class _SendViewState extends ConsumerState<SendView> {
                         if (coin == Coin.firo)
                           Stack(
                             children: [
-                              const TextField(
+                              TextField(
+                                autocorrect: Util.isDesktop ? false : true,
+                                enableSuggestions:
+                                    Util.isDesktop ? false : true,
                                 readOnly: true,
                                 textInputAction: TextInputAction.none,
                               ),
@@ -1061,6 +1066,8 @@ class _SendViewState extends ConsumerState<SendView> {
                           height: 8,
                         ),
                         TextField(
+                          autocorrect: Util.isDesktop ? false : true,
+                          enableSuggestions: Util.isDesktop ? false : true,
                           style: STextStyles.smallMed14(context).copyWith(
                             color: Theme.of(context)
                                 .extension<StackColors>()!
@@ -1114,6 +1121,8 @@ class _SendViewState extends ConsumerState<SendView> {
                           ),
                         if (Prefs.instance.externalCalls)
                           TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             style: STextStyles.smallMed14(context).copyWith(
                               color: Theme.of(context)
                                   .extension<StackColors>()!
@@ -1238,6 +1247,8 @@ class _SendViewState extends ConsumerState<SendView> {
                             Constants.size.circularBorderRadius,
                           ),
                           child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             controller: noteController,
                             focusNode: _noteFocusNode,
                             style: STextStyles.field(context),
@@ -1283,6 +1294,8 @@ class _SendViewState extends ConsumerState<SendView> {
                         Stack(
                           children: [
                             TextField(
+                              autocorrect: Util.isDesktop ? false : true,
+                              enableSuggestions: Util.isDesktop ? false : true,
                               controller: feeController,
                               readOnly: true,
                               textInputAction: TextInputAction.none,
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 29baad1c6..e5c442173 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
@@ -25,6 +25,8 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class DebugView extends ConsumerStatefulWidget {
   const DebugView({Key? key}) : super(key: key);
 
@@ -217,6 +219,8 @@ class _DebugViewState extends ConsumerState<DebugView> {
                             Constants.size.circularBorderRadius,
                           ),
                           child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             controller: _searchController,
                             focusNode: _searchFocusNode,
                             onChanged: (newString) {
diff --git a/lib/pages/settings_views/global_settings_view/currency_view.dart b/lib/pages/settings_views/global_settings_view/currency_view.dart
index cae947caa..e884393bd 100644
--- a/lib/pages/settings_views/global_settings_view/currency_view.dart
+++ b/lib/pages/settings_views/global_settings_view/currency_view.dart
@@ -13,6 +13,8 @@ import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class BaseCurrencySettingsView extends ConsumerStatefulWidget {
   const BaseCurrencySettingsView({Key? key}) : super(key: key);
 
@@ -140,6 +142,8 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
                         Constants.size.circularBorderRadius,
                       ),
                       child: TextField(
+                        autocorrect: Util.isDesktop ? false : true,
+                        enableSuggestions: Util.isDesktop ? false : true,
                         controller: _searchController,
                         focusNode: _searchFocusNode,
                         onChanged: (newString) {
diff --git a/lib/pages/settings_views/global_settings_view/language_view.dart b/lib/pages/settings_views/global_settings_view/language_view.dart
index 75a2751a2..b617546e4 100644
--- a/lib/pages/settings_views/global_settings_view/language_view.dart
+++ b/lib/pages/settings_views/global_settings_view/language_view.dart
@@ -13,6 +13,8 @@ import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class LanguageSettingsView extends ConsumerStatefulWidget {
   const LanguageSettingsView({Key? key}) : super(key: key);
 
@@ -138,6 +140,8 @@ class _LanguageViewState extends ConsumerState<LanguageSettingsView> {
                         Constants.size.circularBorderRadius,
                       ),
                       child: TextField(
+                        autocorrect: Util.isDesktop ? false : true,
+                        enableSuggestions: Util.isDesktop ? false : true,
                         controller: _searchController,
                         focusNode: _searchFocusNode,
                         onChanged: (newString) {
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 143b1e84d..100c03e1b 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -27,6 +27,8 @@ import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 import 'package:uuid/uuid.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 enum AddEditNodeViewType { add, edit }
 
 class AddEditNodeView extends ConsumerStatefulWidget {
@@ -648,6 +650,8 @@ class _NodeFormState extends ConsumerState<NodeForm> {
             Constants.size.circularBorderRadius,
           ),
           child: TextField(
+            autocorrect: Util.isDesktop ? false : true,
+            enableSuggestions: Util.isDesktop ? false : true,
             key: const Key("addCustomNodeNodeNameFieldKey"),
             readOnly: widget.readOnly,
             enabled: enableField(_nameController),
@@ -695,6 +699,8 @@ class _NodeFormState extends ConsumerState<NodeForm> {
                   Constants.size.circularBorderRadius,
                 ),
                 child: TextField(
+                  autocorrect: Util.isDesktop ? false : true,
+                  enableSuggestions: Util.isDesktop ? false : true,
                   key: const Key("addCustomNodeNodeAddressFieldKey"),
                   readOnly: widget.readOnly,
                   enabled: enableField(_hostController),
@@ -746,6 +752,8 @@ class _NodeFormState extends ConsumerState<NodeForm> {
                   Constants.size.circularBorderRadius,
                 ),
                 child: TextField(
+                  autocorrect: Util.isDesktop ? false : true,
+                  enableSuggestions: Util.isDesktop ? false : true,
                   key: const Key("addCustomNodeNodePortFieldKey"),
                   readOnly: widget.readOnly,
                   enabled: enableField(_portController),
@@ -797,6 +805,8 @@ class _NodeFormState extends ConsumerState<NodeForm> {
               Constants.size.circularBorderRadius,
             ),
             child: TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
               controller: _usernameController,
               readOnly: widget.readOnly,
               enabled: enableField(_usernameController),
@@ -844,6 +854,8 @@ class _NodeFormState extends ConsumerState<NodeForm> {
               Constants.size.circularBorderRadius,
             ),
             child: TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
               controller: _passwordController,
               readOnly: widget.readOnly,
               enabled: enableField(_passwordController),
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 3f832a4af..a94375742 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
@@ -19,6 +19,8 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:url_launcher/url_launcher.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class AutoBackupView extends ConsumerStatefulWidget {
   const AutoBackupView({Key? key}) : super(key: key);
 
@@ -423,6 +425,8 @@ class _AutoBackupViewState extends ConsumerState<AutoBackupView> {
                     height: 10,
                   ),
                   TextField(
+                    autocorrect: Util.isDesktop ? false : true,
+                    enableSuggestions: Util.isDesktop ? false : true,
                     key: const Key("backupFrequencyFieldKey"),
                     controller: frequencyController,
                     enabled: false,
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
index b44a473b4..3b5dbd0b0 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
@@ -27,6 +27,8 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:zxcvbn/zxcvbn.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class CreateAutoBackupView extends ConsumerStatefulWidget {
   const CreateAutoBackupView({
     Key? key,
@@ -146,6 +148,8 @@ class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
                     ),
                     if (!Platform.isAndroid)
                       TextField(
+                        autocorrect: Util.isDesktop ? false : true,
+                        enableSuggestions: Util.isDesktop ? false : true,
                         onTap: Platform.isAndroid
                             ? null
                             : () async {
@@ -411,7 +415,9 @@ class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
                     ),
                     Stack(
                       children: [
-                        const TextField(
+                        TextField(
+                          autocorrect: Util.isDesktop ? false : true,
+                          enableSuggestions: Util.isDesktop ? false : true,
                           readOnly: true,
                           textInputAction: TextInputAction.none,
                         ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 8dfc7588c..9242c0482 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -14,6 +14,7 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -129,6 +130,8 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                           return Container(
                             color: Colors.transparent,
                             child: TextField(
+                              autocorrect: Util.isDesktop ? false : true,
+                              enableSuggestions: Util.isDesktop ? false : true,
                               onTap: Platform.isAndroid
                                   ? null
                                   : () async {
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
index 9368d3b77..105146aa0 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
@@ -27,6 +27,8 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:zxcvbn/zxcvbn.dart';
 
+import '../../../../utilities/util.dart';
+
 class EditAutoBackupView extends ConsumerStatefulWidget {
   const EditAutoBackupView({
     Key? key,
@@ -148,6 +150,8 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
                     ),
                     if (!Platform.isAndroid)
                       TextField(
+                        autocorrect: Util.isDesktop ? false : true,
+                        enableSuggestions: Util.isDesktop ? false : true,
                         onTap: Platform.isAndroid
                             ? null
                             : () async {
@@ -413,7 +417,9 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
                     ),
                     Stack(
                       children: [
-                        const TextField(
+                        TextField(
+                          autocorrect: Util.isDesktop ? false : true,
+                          enableSuggestions: Util.isDesktop ? false : true,
                           readOnly: true,
                           textInputAction: TextInputAction.none,
                         ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index cec114023..232be9028 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -20,6 +20,8 @@ import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:tuple/tuple.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class RestoreFromFileView extends ConsumerStatefulWidget {
   const RestoreFromFileView({Key? key}) : super(key: key);
 
@@ -96,6 +98,8 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                     crossAxisAlignment: CrossAxisAlignment.stretch,
                     children: [
                       TextField(
+                        autocorrect: Util.isDesktop ? false : true,
+                        enableSuggestions: Util.isDesktop ? false : true,
                         onTap: () async {
                           try {
                             await stackFileSystem.prepareStorage();
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
index 6e5cdd5ed..2d8909245 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
@@ -30,6 +30,8 @@ import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:tuple/tuple.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 /// [eventBus] should only be set during testing
 class WalletSettingsView extends StatefulWidget {
   const WalletSettingsView({
@@ -374,6 +376,8 @@ class _EpiBoxInfoFormState extends ConsumerState<EpicBoxInfoForm> {
         crossAxisAlignment: CrossAxisAlignment.stretch,
         children: [
           TextField(
+            autocorrect: Util.isDesktop ? false : true,
+            enableSuggestions: Util.isDesktop ? false : true,
             controller: hostController,
             decoration: const InputDecoration(hintText: "Host"),
           ),
@@ -381,6 +385,8 @@ class _EpiBoxInfoFormState extends ConsumerState<EpicBoxInfoForm> {
             height: 8,
           ),
           TextField(
+            autocorrect: Util.isDesktop ? false : true,
+            enableSuggestions: Util.isDesktop ? false : true,
             controller: portController,
             decoration: const InputDecoration(hintText: "Port"),
             keyboardType: const TextInputType.numberWithOptions(),
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart
index b876216e0..e9eb14868 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart
@@ -11,6 +11,8 @@ 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';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class RenameWalletView extends ConsumerStatefulWidget {
   const RenameWalletView({
     Key? key,
@@ -74,6 +76,8 @@ class _RenameWalletViewState extends ConsumerState<RenameWalletView> {
                 Constants.size.circularBorderRadius,
               ),
               child: TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
                 controller: _controller,
                 focusNode: _focusNode,
                 style: STextStyles.field(context),
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 78f24ba6a..4194a7307 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -21,6 +21,8 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
 import 'package:stackwallet/widgets/transaction_card.dart';
 import 'package:tuple/tuple.dart';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class AllTransactionsView extends ConsumerStatefulWidget {
   const AllTransactionsView({
     Key? key,
@@ -234,6 +236,8 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
                   Constants.size.circularBorderRadius,
                 ),
                 child: TextField(
+                  autocorrect: Util.isDesktop ? false : true,
+                  enableSuggestions: Util.isDesktop ? false : true,
                   controller: _searchController,
                   focusNode: searchFieldFocusNode,
                   onChanged: (value) {
diff --git a/lib/pages/wallet_view/transaction_views/edit_note_view.dart b/lib/pages/wallet_view/transaction_views/edit_note_view.dart
index aa085429b..b811dc62d 100644
--- a/lib/pages/wallet_view/transaction_views/edit_note_view.dart
+++ b/lib/pages/wallet_view/transaction_views/edit_note_view.dart
@@ -9,6 +9,8 @@ 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';
 
+import 'package:stackwallet/utilities/util.dart';
+
 class EditNoteView extends ConsumerStatefulWidget {
   const EditNoteView({
     Key? key,
@@ -87,6 +89,8 @@ class _EditNoteViewState extends ConsumerState<EditNoteView> {
                             Constants.size.circularBorderRadius,
                           ),
                           child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
                             controller: _noteController,
                             style: STextStyles.field(context),
                             focusNode: noteFieldFocusNode,
diff --git a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
index 8175597f6..f9932c672 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
@@ -569,6 +569,8 @@ class _TransactionSearchViewState
                           Constants.size.circularBorderRadius,
                         ),
                         child: TextField(
+                          autocorrect: Util.isDesktop ? false : true,
+                          enableSuggestions: Util.isDesktop ? false : true,
                           key: const Key("transactionSearchViewAmountFieldKey"),
                           controller: _amountTextEditingController,
                           focusNode: amountTextFieldFocusNode,
@@ -636,6 +638,8 @@ class _TransactionSearchViewState
                           Constants.size.circularBorderRadius,
                         ),
                         child: TextField(
+                          autocorrect: Util.isDesktop ? false : true,
+                          enableSuggestions: Util.isDesktop ? false : true,
                           key:
                               const Key("transactionSearchViewKeywordFieldKey"),
                           controller: _keywordTextEditingController,

From 44790dd2df675803e44f6eefb6f467bdbd80df17 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 21 Oct 2022 13:05:39 -0600
Subject: [PATCH 029/426] added nodes and dark theme icon

---
 assets/svg/dark/dark-theme.svg                |  24 ++++
 .../home/settings_menu/nodes_settings.dart    | 117 ++++++++++--------
 lib/utilities/assets.dart                     |   2 +
 pubspec.yaml                                  |   1 +
 4 files changed, 91 insertions(+), 53 deletions(-)
 create mode 100644 assets/svg/dark/dark-theme.svg

diff --git a/assets/svg/dark/dark-theme.svg b/assets/svg/dark/dark-theme.svg
new file mode 100644
index 000000000..47b5e2d5e
--- /dev/null
+++ b/assets/svg/dark/dark-theme.svg
@@ -0,0 +1,24 @@
+<svg width="200" height="162" viewBox="0 0 200 162" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_5863_29353)">
+<rect width="200" height="162" rx="8" fill="#2A2D34"/>
+<rect x="10" y="10" width="180" height="20" rx="2" fill="#444953"/>
+<rect x="16" y="16" width="106" height="8" rx="1" fill="#7E8692"/>
+<rect x="10" y="40" width="180" height="20" rx="2" fill="#333942"/>
+<rect x="16" y="46" width="106" height="8" rx="1" fill="#575C63"/>
+<rect x="10" y="62" width="180" height="20" rx="2" fill="#333942"/>
+<rect x="16" y="68" width="106" height="8" rx="1" fill="#575C63"/>
+<rect x="10" y="84" width="180" height="20" rx="2" fill="#333942"/>
+<rect x="16" y="90" width="106" height="8" rx="1" fill="#575C63"/>
+<rect x="10" y="106" width="180" height="20" rx="2" fill="#333942"/>
+<rect x="16" y="112" width="106" height="8" rx="1" fill="#575C63"/>
+<rect x="10" y="128" width="180" height="20" rx="2" fill="#333942"/>
+<rect x="16" y="134" width="106" height="8" rx="1" fill="#575C63"/>
+<rect x="10" y="150" width="180" height="20" rx="2" fill="#333942"/>
+<rect x="16" y="156" width="106" height="8" rx="1" fill="#575C63"/>
+</g>
+<defs>
+<clipPath id="clip0_5863_29353">
+<rect width="200" height="162" rx="8" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index 4227b537f..1cc6edaaa 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -2,15 +2,15 @@ import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/providers/global/node_service_provider.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import '../../../providers/global/node_service_provider.dart';
-import '../../../providers/global/prefs_provider.dart';
-import '../../../utilities/constants.dart';
-import '../../../utilities/enums/coin_enum.dart';
-
 class NodesSettings extends ConsumerStatefulWidget {
   const NodesSettings({Key? key}) : super(key: key);
 
@@ -37,6 +37,9 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
 
   @override
   Widget build(BuildContext context) {
+    double deviceWidth(BuildContext context) =>
+        MediaQuery.of(context).size.width;
+
     bool showTestNet = ref.watch(
       prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
     );
@@ -85,6 +88,7 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                     ),
                   ],
                 ),
+                //TODO: add search bar
                 SingleChildScrollView(
                   child: Column(
                     crossAxisAlignment: CrossAxisAlignment.stretch,
@@ -97,55 +101,62 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                               .length;
 
                           return Padding(
-                            padding: const EdgeInsets.all(4),
-                            child: RoundedWhiteContainer(
-                              padding: const EdgeInsets.all(0),
-                              child: RawMaterialButton(
-                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
-                                  ),
+                            padding: const EdgeInsets.all(0),
+                            child: RawMaterialButton(
+                              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                              shape: RoundedRectangleBorder(
+                                borderRadius: BorderRadius.circular(
+                                  Constants.size.circularBorderRadius,
                                 ),
-                                materialTapTargetSize:
-                                    MaterialTapTargetSize.shrinkWrap,
-                                onPressed: () {
-                                  // Navigator.of(context).pushNamed(
-                                  //   CoinNodesView.routeName,
-                                  //   arguments: coin,
-                                  // );
-                                },
-                                child: Padding(
-                                  padding: const EdgeInsets.all(12),
-                                  child: Row(
-                                    children: [
-                                      SvgPicture.asset(
-                                        Assets.svg.iconFor(coin: coin),
-                                        width: 24,
-                                        height: 24,
-                                      ),
-                                      const SizedBox(
-                                        width: 12,
-                                      ),
-                                      Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
-                                        children: [
-                                          Text(
-                                            "${coin.prettyName} nodes",
-                                            style: STextStyles.titleBold12(
-                                                context),
-                                          ),
-                                          Text(
-                                            count > 1
-                                                ? "$count nodes"
-                                                : "Default",
-                                            style: STextStyles.label(context),
-                                          ),
-                                        ],
-                                      )
-                                    ],
-                                  ),
+                                side: BorderSide(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .shadow),
+                              ),
+                              materialTapTargetSize:
+                                  MaterialTapTargetSize.shrinkWrap,
+                              onPressed: () {
+                                // Navigator.of(context).pushNamed(
+                                //   CoinNodesView.routeName,
+                                //   arguments: coin,
+                                // );
+                              },
+                              child: Padding(
+                                padding: const EdgeInsets.all(
+                                  12.0,
+                                ),
+                                child: Row(
+                                  children: [
+                                    SvgPicture.asset(
+                                      Assets.svg.iconFor(coin: coin),
+                                      width: 24,
+                                      height: 24,
+                                    ),
+                                    const SizedBox(
+                                      width: 12,
+                                    ),
+                                    Column(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        Text(
+                                          "${coin.prettyName} nodes",
+                                          style:
+                                              STextStyles.titleBold12(context),
+                                        ),
+                                        Text(
+                                          count > 1
+                                              ? "$count nodes"
+                                              : "Default",
+                                          style: STextStyles.label(context),
+                                        ),
+                                      ],
+                                    ),
+                                    // SvgPicture.asset(
+                                    //   Assets.svg.chevronRight,
+                                    //   alignment: Alignment.centerRight,
+                                    // ),
+                                  ],
                                 ),
                               ),
                             ),
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 5136f1a37..407332cf4 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -59,6 +59,8 @@ class _SVG {
   String txExchangeFailed(BuildContext context) =>
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
 
+  // String get themeLight => "assets/svg/light/light-theme.svg";
+  String get themeDark => "assets/svg/dark/dark-theme.svg";
   String get circleNode => "assets/svg/node-circle.svg";
   String get circleSun => "assets/svg/sun-circle.svg";
   String get circleArrowRotate => "assets/svg/rotate-circle.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index 64fe730f6..75a0e8d3f 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -299,6 +299,7 @@ flutter:
     - assets/svg/rotate-circle.svg
     - assets/svg/sun-circle.svg
     - assets/svg/node-circle.svg
+    - assets/svg/dark/dark-theme.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Bitcoincash.svg

From ab5190562d07b8ae04837c70830e34688e22e9d3 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 25 Oct 2022 09:19:45 -0600
Subject: [PATCH 030/426] nodes settings ui and light-theme icon added

---
 assets/svg/light/light-mode.svg               | 24 +++++++++
 .../home/settings_menu/nodes_settings.dart    | 54 ++++++++++---------
 lib/utilities/assets.dart                     |  2 +-
 pubspec.yaml                                  |  1 +
 4 files changed, 56 insertions(+), 25 deletions(-)
 create mode 100644 assets/svg/light/light-mode.svg

diff --git a/assets/svg/light/light-mode.svg b/assets/svg/light/light-mode.svg
new file mode 100644
index 000000000..4ff9e2696
--- /dev/null
+++ b/assets/svg/light/light-mode.svg
@@ -0,0 +1,24 @@
+<svg width="200" height="162" viewBox="0 0 200 162" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_5887_94222)">
+<rect width="200" height="162" rx="8" fill="#E8EAEC"/>
+<rect x="10" y="10" width="180" height="20" rx="2" fill="#DBDDE1"/>
+<rect x="16" y="16" width="106" height="8" rx="1" fill="#C4C8CC"/>
+<rect x="10" y="40" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="46" width="106" height="8" rx="1" fill="#C4C8CC"/>
+<rect x="10" y="62" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="68" width="106" height="8" rx="1" fill="#C4C8CC"/>
+<rect x="10" y="84" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="90" width="106" height="8" rx="1" fill="#C4C8CC"/>
+<rect x="10" y="106" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="112" width="106" height="8" rx="1" fill="#C4C8CC"/>
+<rect x="10" y="128" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="134" width="106" height="8" rx="1" fill="#C4C8CC"/>
+<rect x="10" y="150" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="156" width="106" height="8" rx="1" fill="#C4C8CC"/>
+</g>
+<defs>
+<clipPath id="clip0_5887_94222">
+<rect width="200" height="162" rx="8" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index 1cc6edaaa..8608e79af 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -127,35 +127,41 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                                 ),
                                 child: Row(
                                   children: [
-                                    SvgPicture.asset(
-                                      Assets.svg.iconFor(coin: coin),
-                                      width: 24,
-                                      height: 24,
-                                    ),
-                                    const SizedBox(
-                                      width: 12,
-                                    ),
-                                    Column(
-                                      crossAxisAlignment:
-                                          CrossAxisAlignment.start,
+                                    Row(
                                       children: [
-                                        Text(
-                                          "${coin.prettyName} nodes",
-                                          style:
-                                              STextStyles.titleBold12(context),
+                                        SvgPicture.asset(
+                                          Assets.svg.iconFor(coin: coin),
+                                          width: 24,
+                                          height: 24,
                                         ),
-                                        Text(
-                                          count > 1
-                                              ? "$count nodes"
-                                              : "Default",
-                                          style: STextStyles.label(context),
+                                        const SizedBox(
+                                          width: 12,
+                                        ),
+                                        Column(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            Text(
+                                              "${coin.prettyName} nodes",
+                                              style: STextStyles.titleBold12(
+                                                  context),
+                                            ),
+                                            Text(
+                                              count > 1
+                                                  ? "$count nodes"
+                                                  : "Default",
+                                              style: STextStyles.label(context),
+                                            ),
+                                          ],
                                         ),
                                       ],
                                     ),
-                                    // SvgPicture.asset(
-                                    //   Assets.svg.chevronRight,
-                                    //   alignment: Alignment.centerRight,
-                                    // ),
+                                    Expanded(
+                                      child: SvgPicture.asset(
+                                        Assets.svg.chevronRight,
+                                        alignment: Alignment.centerRight,
+                                      ),
+                                    ),
                                   ],
                                 ),
                               ),
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 407332cf4..2ada80a5d 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -59,7 +59,7 @@ class _SVG {
   String txExchangeFailed(BuildContext context) =>
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
 
-  // String get themeLight => "assets/svg/light/light-theme.svg";
+  String get themeLight => "assets/svg/light/light-mode.svg";
   String get themeDark => "assets/svg/dark/dark-theme.svg";
   String get circleNode => "assets/svg/node-circle.svg";
   String get circleSun => "assets/svg/sun-circle.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index 75a0e8d3f..35fbecf3f 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -300,6 +300,7 @@ flutter:
     - assets/svg/sun-circle.svg
     - assets/svg/node-circle.svg
     - assets/svg/dark/dark-theme.svg
+    - assets/svg/light/light-mode.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Bitcoincash.svg

From aa8b7221746637a375c2081998221b3151c97713 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 26 Oct 2022 11:59:54 -0600
Subject: [PATCH 031/426] basic desktop send layout

---
 .../wallet_view/desktop_wallet_view.dart      |   58 +-
 .../wallet_view/receive/desktop_receive.dart  |   17 +
 .../wallet_view/send/desktop_send.dart        | 1171 +++++++++++++++++
 3 files changed, 1208 insertions(+), 38 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index f8cc7e2dc..959f9c052 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -1,6 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -171,11 +173,13 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
             ),
             Expanded(
               child: Row(
-                children: const [
+                children: [
                   Expanded(
-                    child: MyWallet(),
+                    child: MyWallet(
+                      walletId: walletId,
+                    ),
                   ),
-                  SizedBox(
+                  const SizedBox(
                     width: 16,
                   ),
                   Expanded(
@@ -192,7 +196,12 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
 }
 
 class MyWallet extends StatefulWidget {
-  const MyWallet({Key? key}) : super(key: key);
+  const MyWallet({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
 
   @override
   State<MyWallet> createState() => _MyWalletState();
@@ -246,10 +255,15 @@ class _MyWalletState extends State<MyWallet> {
                       Tab(text: "Receive"),
                     ],
                   ),
-                  const Expanded(
+                  Expanded(
                     child: TabBarView(
                       children: [
-                        DesktopSend(),
+                        Padding(
+                          padding: const EdgeInsets.all(20),
+                          child: DesktopSend(
+                            walletId: widget.walletId,
+                          ),
+                        ),
                         DesktopReceive(),
                       ],
                     ),
@@ -264,38 +278,6 @@ class _MyWalletState extends State<MyWallet> {
   }
 }
 
-class DesktopReceive extends StatefulWidget {
-  const DesktopReceive({Key? key}) : super(key: key);
-
-  @override
-  State<DesktopReceive> createState() => _DesktopReceiveState();
-}
-
-class _DesktopReceiveState extends State<DesktopReceive> {
-  @override
-  Widget build(BuildContext context) {
-    return Container(
-      color: Colors.green,
-    );
-  }
-}
-
-class DesktopSend extends StatefulWidget {
-  const DesktopSend({Key? key}) : super(key: key);
-
-  @override
-  State<DesktopSend> createState() => _DesktopSendState();
-}
-
-class _DesktopSendState extends State<DesktopSend> {
-  @override
-  Widget build(BuildContext context) {
-    return Container(
-      color: Colors.red,
-    );
-  }
-}
-
 class RecentDesktopTransactions extends StatefulWidget {
   const RecentDesktopTransactions({Key? key}) : super(key: key);
 
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
new file mode 100644
index 000000000..319076dfe
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
@@ -0,0 +1,17 @@
+import 'package:flutter/material.dart';
+
+class DesktopReceive extends StatefulWidget {
+  const DesktopReceive({Key? key}) : super(key: key);
+
+  @override
+  State<DesktopReceive> createState() => _DesktopReceiveState();
+}
+
+class _DesktopReceiveState extends State<DesktopReceive> {
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      color: Colors.green,
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
new file mode 100644
index 000000000..8f45b70c4
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
@@ -0,0 +1,1171 @@
+import 'dart:async';
+
+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/send_view_auto_fill_data.dart';
+import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
+import 'package:stackwallet/pages/send_view/sub_widgets/firo_balance_selection_sheet.dart';
+import 'package:stackwallet/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart';
+import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/providers/ui/fee_rate_type_state_provider.dart';
+import 'package:stackwallet/providers/ui/preview_tx_button_state_provider.dart';
+import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
+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/utilities/address_utils.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/barcode_scanner_interface.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/enums/fee_rate_type_enum.dart';
+import 'package:stackwallet/utilities/format.dart';
+import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/utilities/prefs.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/animated_text.dart';
+import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
+import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
+import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
+import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+import 'package:stackwallet/widgets/stack_dialog.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+import 'package:stackwallet/widgets/textfield_icon_button.dart';
+
+import '../../../../../pages/send_view/confirm_transaction_view.dart';
+import '../../../../../pages/send_view/sub_widgets/building_transaction_dialog.dart';
+
+class DesktopSend extends ConsumerStatefulWidget {
+  const DesktopSend({
+    Key? key,
+    required this.walletId,
+    this.autoFillData,
+    this.clipboard = const ClipboardWrapper(),
+    this.barcodeScanner = const BarcodeScannerWrapper(),
+  }) : super(key: key);
+
+  final String walletId;
+  final SendViewAutoFillData? autoFillData;
+  final ClipboardInterface clipboard;
+  final BarcodeScannerInterface barcodeScanner;
+
+  @override
+  ConsumerState<DesktopSend> createState() => _DesktopSendState();
+}
+
+class _DesktopSendState extends ConsumerState<DesktopSend> {
+  late final String walletId;
+  late final Coin coin;
+  late final ClipboardInterface clipboard;
+  late final BarcodeScannerInterface scanner;
+
+  late TextEditingController sendToController;
+  late TextEditingController cryptoAmountController;
+  late TextEditingController baseAmountController;
+  late TextEditingController noteController;
+  late TextEditingController feeController;
+
+  late final SendViewAutoFillData? _data;
+
+  final _addressFocusNode = FocusNode();
+  final _noteFocusNode = FocusNode();
+  final _cryptoFocus = FocusNode();
+  final _baseFocus = FocusNode();
+
+  Decimal? _amountToSend;
+  Decimal? _cachedAmountToSend;
+  String? _address;
+
+  String? _privateBalanceString;
+  String? _publicBalanceString;
+
+  bool _addressToggleFlag = false;
+
+  bool _cryptoAmountChangeLock = false;
+  late VoidCallback onCryptoAmountChanged;
+
+  Decimal? _cachedBalance;
+
+  Future<void> previewSend() 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) {
+      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!);
+    int availableBalance;
+    if ((coin == Coin.firo || coin == Coin.firoTestNet)) {
+      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+          "Private") {
+        availableBalance = Format.decimalAmountToSatoshis(
+            await (manager.wallet as FiroWallet).availablePrivateBalance());
+      } else {
+        availableBalance = Format.decimalAmountToSatoshis(
+            await (manager.wallet as FiroWallet).availablePublicBalance());
+      }
+    } else {
+      availableBalance =
+          Format.decimalAmountToSatoshis(await manager.availableBalance);
+    }
+
+    // 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>()!
+                  .getSecondaryEnabledButtonColor(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>()!
+                  .getPrimaryEnabledButtonColor(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>()!
+                    .getSecondaryEnabledButtonColor(context),
+                child: Text(
+                  "Ok",
+                  style: STextStyles.button(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark),
+                ),
+                onPressed: () {
+                  Navigator.of(context).pop();
+                },
+              ),
+            );
+          },
+        ));
+      }
+    }
+  }
+
+  void _cryptoAmountChanged() async {
+    if (!_cryptoAmountChangeLock) {
+      final String cryptoAmount = cryptoAmountController.text;
+      if (cryptoAmount.isNotEmpty &&
+          cryptoAmount != "." &&
+          cryptoAmount != ",") {
+        _amountToSend = cryptoAmount.contains(",")
+            ? Decimal.parse(cryptoAmount.replaceFirst(",", "."))
+            : Decimal.parse(cryptoAmount);
+        if (_cachedAmountToSend != null &&
+            _cachedAmountToSend == _amountToSend) {
+          return;
+        }
+        _cachedAmountToSend = _amountToSend;
+        Logging.instance.log("it changed $_amountToSend $_cachedAmountToSend",
+            level: LogLevel.Info);
+
+        final price =
+            ref.read(priceAnd24hChangeNotifierProvider).getPrice(coin).item1;
+
+        if (price > Decimal.zero) {
+          final String fiatAmountString = Format.localizedStringAsFixed(
+            value: _amountToSend! * price,
+            locale: ref.read(localeServiceChangeNotifierProvider).locale,
+            decimalPlaces: 2,
+          );
+
+          baseAmountController.text = fiatAmountString;
+        }
+      } else {
+        _amountToSend = null;
+        baseAmountController.text = "";
+      }
+
+      _updatePreviewButtonState(_address, _amountToSend);
+    }
+  }
+
+  String? _updateInvalidAddressText(String address, Manager manager) {
+    if (_data != null && _data!.contactLabel == address) {
+      return null;
+    }
+    if (address.isNotEmpty && !manager.validateAddress(address)) {
+      return "Invalid address";
+    }
+    return null;
+  }
+
+  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);
+  }
+
+  late Future<String> _calculateFeesFuture;
+
+  Map<int, String> cachedFees = {};
+  Map<int, String> cachedFiroPrivateFees = {};
+  Map<int, String> cachedFiroPublicFees = {};
+
+  Future<String> calculateFees(int amount) async {
+    if (amount <= 0) {
+      return "0";
+    }
+
+    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+          "Private") {
+        if (cachedFiroPrivateFees[amount] != null) {
+          return cachedFiroPrivateFees[amount]!;
+        }
+      } else {
+        if (cachedFiroPublicFees[amount] != null) {
+          return cachedFiroPublicFees[amount]!;
+        }
+      }
+    } else if (cachedFees[amount] != null) {
+      return cachedFees[amount]!;
+    }
+
+    final manager =
+        ref.read(walletsChangeNotifierProvider).getManager(walletId);
+    final feeObject = await manager.fees;
+
+    late final int feeRate;
+
+    switch (ref.read(feeRateTypeStateProvider.state).state) {
+      case FeeRateType.fast:
+        feeRate = feeObject.fast;
+        break;
+      case FeeRateType.average:
+        feeRate = feeObject.medium;
+        break;
+      case FeeRateType.slow:
+        feeRate = feeObject.slow;
+        break;
+    }
+
+    int fee;
+
+    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+          "Private") {
+        fee = await manager.estimateFeeFor(amount, feeRate);
+
+        cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee)
+            .toStringAsFixed(Constants.decimalPlaces);
+
+        return cachedFiroPrivateFees[amount]!;
+      } else {
+        fee = await (manager.wallet as FiroWallet)
+            .estimateFeeForPublic(amount, feeRate);
+
+        cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee)
+            .toStringAsFixed(Constants.decimalPlaces);
+
+        return cachedFiroPublicFees[amount]!;
+      }
+    } else {
+      fee = await manager.estimateFeeFor(amount, feeRate);
+      cachedFees[amount] =
+          Format.satoshisToAmount(fee).toStringAsFixed(Constants.decimalPlaces);
+
+      return cachedFees[amount]!;
+    }
+  }
+
+  Future<String?> _firoBalanceFuture(
+      ChangeNotifierProvider<Manager> provider, String locale) async {
+    final wallet = ref.read(provider).wallet as FiroWallet?;
+
+    if (wallet != null) {
+      Decimal? balance;
+      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+          "Private") {
+        balance = await wallet.availablePrivateBalance();
+      } else {
+        balance = await wallet.availablePublicBalance();
+      }
+
+      return Format.localizedStringAsFixed(
+          value: balance, locale: locale, decimalPlaces: 8);
+    }
+
+    return null;
+  }
+
+  @override
+  void initState() {
+    ref.refresh(feeSheetSessionCacheProvider);
+
+    _calculateFeesFuture = calculateFees(0);
+    _data = widget.autoFillData;
+    walletId = widget.walletId;
+    coin = ref.read(walletsChangeNotifierProvider).getManager(walletId).coin;
+    clipboard = widget.clipboard;
+    scanner = widget.barcodeScanner;
+
+    sendToController = TextEditingController();
+    cryptoAmountController = TextEditingController();
+    baseAmountController = TextEditingController();
+    noteController = TextEditingController();
+    feeController = TextEditingController();
+
+    onCryptoAmountChanged = _cryptoAmountChanged;
+    cryptoAmountController.addListener(onCryptoAmountChanged);
+
+    if (_data != null) {
+      if (_data!.amount != null) {
+        cryptoAmountController.text = _data!.amount!.toString();
+      }
+      sendToController.text = _data!.contactLabel;
+      _address = _data!.address;
+      _addressToggleFlag = true;
+    }
+
+    _cryptoFocus.addListener(() {
+      if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
+        if (_amountToSend == null) {
+          setState(() {
+            _calculateFeesFuture = calculateFees(0);
+          });
+        } else {
+          setState(() {
+            _calculateFeesFuture =
+                calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
+          });
+        }
+      }
+    });
+
+    _baseFocus.addListener(() {
+      if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
+        if (_amountToSend == null) {
+          setState(() {
+            _calculateFeesFuture = calculateFees(0);
+          });
+        } else {
+          setState(() {
+            _calculateFeesFuture =
+                calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
+          });
+        }
+      }
+    });
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    cryptoAmountController.removeListener(onCryptoAmountChanged);
+
+    sendToController.dispose();
+    cryptoAmountController.dispose();
+    baseAmountController.dispose();
+    noteController.dispose();
+    feeController.dispose();
+
+    _noteFocusNode.dispose();
+    _addressFocusNode.dispose();
+    _cryptoFocus.dispose();
+    _baseFocus.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    final provider = ref.watch(walletsChangeNotifierProvider
+        .select((value) => value.getManagerProvider(walletId)));
+    final String locale = ref.watch(
+        localeServiceChangeNotifierProvider.select((value) => value.locale));
+
+    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+      ref.listen(publicPrivateBalanceStateProvider, (previous, next) {
+        if (_amountToSend == null) {
+          setState(() {
+            _calculateFeesFuture = calculateFees(0);
+          });
+        } else {
+          setState(() {
+            _calculateFeesFuture =
+                calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
+          });
+        }
+      });
+    }
+
+    return SingleChildScrollView(
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          const SizedBox(
+            height: 4,
+          ),
+          if (coin == Coin.firo)
+            Text(
+              "Send from",
+              style: STextStyles.smallMed12(context),
+              textAlign: TextAlign.left,
+            ),
+          if (coin == Coin.firo)
+            const SizedBox(
+              height: 10,
+            ),
+          if (coin == Coin.firo)
+            Stack(
+              children: [
+                TextField(
+                  autocorrect: Util.isDesktop ? false : true,
+                  enableSuggestions: Util.isDesktop ? false : true,
+                  readOnly: true,
+                  textInputAction: TextInputAction.none,
+                ),
+                Padding(
+                  padding: const EdgeInsets.symmetric(
+                    horizontal: 12,
+                  ),
+                  child: RawMaterialButton(
+                    splashColor:
+                        Theme.of(context).extension<StackColors>()!.highlight,
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
+                      ),
+                    ),
+                    onPressed: () {
+                      showModalBottomSheet<dynamic>(
+                        backgroundColor: Colors.transparent,
+                        context: context,
+                        shape: const RoundedRectangleBorder(
+                          borderRadius: BorderRadius.vertical(
+                            top: Radius.circular(20),
+                          ),
+                        ),
+                        builder: (_) => FiroBalanceSelectionSheet(
+                          walletId: walletId,
+                        ),
+                      );
+                    },
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Row(
+                          children: [
+                            Text(
+                              "${ref.watch(publicPrivateBalanceStateProvider.state).state} balance",
+                              style: STextStyles.itemSubtitle12(context),
+                            ),
+                            const SizedBox(
+                              width: 10,
+                            ),
+                            FutureBuilder(
+                              future: _firoBalanceFuture(provider, locale),
+                              builder:
+                                  (context, AsyncSnapshot<String?> snapshot) {
+                                if (snapshot.connectionState ==
+                                        ConnectionState.done &&
+                                    snapshot.hasData) {
+                                  if (ref
+                                          .read(
+                                              publicPrivateBalanceStateProvider
+                                                  .state)
+                                          .state ==
+                                      "Private") {
+                                    _privateBalanceString = snapshot.data!;
+                                  } else {
+                                    _publicBalanceString = snapshot.data!;
+                                  }
+                                }
+                                if (ref
+                                            .read(
+                                                publicPrivateBalanceStateProvider
+                                                    .state)
+                                            .state ==
+                                        "Private" &&
+                                    _privateBalanceString != null) {
+                                  return Text(
+                                    "$_privateBalanceString ${coin.ticker}",
+                                    style: STextStyles.itemSubtitle(context),
+                                  );
+                                } else if (ref
+                                            .read(
+                                                publicPrivateBalanceStateProvider
+                                                    .state)
+                                            .state ==
+                                        "Public" &&
+                                    _publicBalanceString != null) {
+                                  return Text(
+                                    "$_publicBalanceString ${coin.ticker}",
+                                    style: STextStyles.itemSubtitle(context),
+                                  );
+                                } else {
+                                  return AnimatedText(
+                                    stringsToLoopThrough: const [
+                                      "Loading balance",
+                                      "Loading balance.",
+                                      "Loading balance..",
+                                      "Loading balance...",
+                                    ],
+                                    style: STextStyles.itemSubtitle(context),
+                                  );
+                                }
+                              },
+                            ),
+                          ],
+                        ),
+                        SvgPicture.asset(
+                          Assets.svg.chevronDown,
+                          width: 8,
+                          height: 4,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textSubtitle2,
+                        ),
+                      ],
+                    ),
+                  ),
+                )
+              ],
+            ),
+          if (coin == Coin.firo)
+            const SizedBox(
+              height: 20,
+            ),
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Text(
+                "Amount",
+                style: STextStyles.smallMed12(context),
+                textAlign: TextAlign.left,
+              ),
+              BlueTextButton(
+                text: "Send all ${coin.ticker}",
+                onTap: () async {
+                  if (coin == Coin.firo || coin == Coin.firoTestNet) {
+                    final firoWallet = ref.read(provider).wallet as FiroWallet;
+                    if (ref
+                            .read(publicPrivateBalanceStateProvider.state)
+                            .state ==
+                        "Private") {
+                      cryptoAmountController.text =
+                          (await firoWallet.availablePrivateBalance())
+                              .toStringAsFixed(Constants.decimalPlaces);
+                    } else {
+                      cryptoAmountController.text =
+                          (await firoWallet.availablePublicBalance())
+                              .toStringAsFixed(Constants.decimalPlaces);
+                    }
+                  } else {
+                    cryptoAmountController.text =
+                        (await ref.read(provider).availableBalance)
+                            .toStringAsFixed(Constants.decimalPlaces);
+                  }
+                },
+              ),
+            ],
+          ),
+          const SizedBox(
+            height: 10,
+          ),
+          TextField(
+            autocorrect: Util.isDesktop ? false : true,
+            enableSuggestions: Util.isDesktop ? false : true,
+            style: STextStyles.smallMed14(context).copyWith(
+              color: Theme.of(context).extension<StackColors>()!.textDark,
+            ),
+            key: const Key("amountInputFieldCryptoTextFieldKey"),
+            controller: cryptoAmountController,
+            focusNode: _cryptoFocus,
+            keyboardType: const TextInputType.numberWithOptions(
+              signed: false,
+              decimal: true,
+            ),
+            textAlign: TextAlign.right,
+            inputFormatters: [
+              // regex to validate a crypto amount with 8 decimal places
+              TextInputFormatter.withFunction((oldValue, newValue) =>
+                  RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
+                          .hasMatch(newValue.text)
+                      ? newValue
+                      : oldValue),
+            ],
+            decoration: InputDecoration(
+              contentPadding: const EdgeInsets.only(
+                top: 12,
+                right: 12,
+              ),
+              hintText: "0",
+              hintStyle: STextStyles.fieldLabel(context).copyWith(
+                fontSize: 14,
+              ),
+              prefixIcon: FittedBox(
+                fit: BoxFit.scaleDown,
+                child: Padding(
+                  padding: const EdgeInsets.all(12),
+                  child: Text(
+                    coin.ticker,
+                    style: STextStyles.smallMed14(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark),
+                  ),
+                ),
+              ),
+            ),
+          ),
+          if (Prefs.instance.externalCalls)
+            const SizedBox(
+              height: 10,
+            ),
+          if (Prefs.instance.externalCalls)
+            TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
+              style: STextStyles.smallMed14(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark,
+              ),
+              key: const Key("amountInputFieldFiatTextFieldKey"),
+              controller: baseAmountController,
+              focusNode: _baseFocus,
+              keyboardType: const TextInputType.numberWithOptions(
+                signed: false,
+                decimal: true,
+              ),
+              textAlign: TextAlign.right,
+              inputFormatters: [
+                // regex to validate a fiat amount with 2 decimal places
+                TextInputFormatter.withFunction((oldValue, newValue) =>
+                    RegExp(r'^([0-9]*[,.]?[0-9]{0,2}|[,.][0-9]{0,2})$')
+                            .hasMatch(newValue.text)
+                        ? newValue
+                        : oldValue),
+              ],
+              onChanged: (baseAmountString) {
+                if (baseAmountString.isNotEmpty &&
+                    baseAmountString != "." &&
+                    baseAmountString != ",") {
+                  final baseAmount = baseAmountString.contains(",")
+                      ? Decimal.parse(baseAmountString.replaceFirst(",", "."))
+                      : Decimal.parse(baseAmountString);
+
+                  var _price = ref
+                      .read(priceAnd24hChangeNotifierProvider)
+                      .getPrice(coin)
+                      .item1;
+
+                  if (_price == Decimal.zero) {
+                    _amountToSend = Decimal.zero;
+                  } else {
+                    _amountToSend = baseAmount <= Decimal.zero
+                        ? Decimal.zero
+                        : (baseAmount / _price).toDecimal(
+                            scaleOnInfinitePrecision: Constants.decimalPlaces);
+                  }
+                  if (_cachedAmountToSend != null &&
+                      _cachedAmountToSend == _amountToSend) {
+                    return;
+                  }
+                  _cachedAmountToSend = _amountToSend;
+                  Logging.instance.log(
+                      "it changed $_amountToSend $_cachedAmountToSend",
+                      level: LogLevel.Info);
+
+                  final amountString = Format.localizedStringAsFixed(
+                    value: _amountToSend!,
+                    locale:
+                        ref.read(localeServiceChangeNotifierProvider).locale,
+                    decimalPlaces: Constants.decimalPlaces,
+                  );
+
+                  _cryptoAmountChangeLock = true;
+                  cryptoAmountController.text = amountString;
+                  _cryptoAmountChangeLock = false;
+                } else {
+                  _amountToSend = Decimal.zero;
+                  _cryptoAmountChangeLock = true;
+                  cryptoAmountController.text = "";
+                  _cryptoAmountChangeLock = false;
+                }
+                // setState(() {
+                //   _calculateFeesFuture = calculateFees(
+                //       Format.decimalAmountToSatoshis(
+                //           _amountToSend!));
+                // });
+                _updatePreviewButtonState(_address, _amountToSend);
+              },
+              decoration: InputDecoration(
+                contentPadding: const EdgeInsets.only(
+                  top: 12,
+                  right: 12,
+                ),
+                hintText: "0",
+                hintStyle: STextStyles.fieldLabel(context).copyWith(
+                  fontSize: 14,
+                ),
+                prefixIcon: FittedBox(
+                  fit: BoxFit.scaleDown,
+                  child: Padding(
+                    padding: const EdgeInsets.all(12),
+                    child: Text(
+                      ref.watch(prefsChangeNotifierProvider
+                          .select((value) => value.currency)),
+                      style: STextStyles.smallMed14(context).copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorDark),
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          const SizedBox(
+            height: 20,
+          ),
+          Text(
+            "Send to",
+            style: STextStyles.smallMed12(context),
+            textAlign: TextAlign.left,
+          ),
+          const SizedBox(
+            height: 10,
+          ),
+          ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            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,
+              ),
+              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: coin,
+                              );
+                            },
+                            child: const AddressBookIcon(),
+                          ),
+                        if (sendToController.text.isEmpty)
+                          TextFieldIconButton(
+                            key: const Key("sendViewScanQrButtonKey"),
+                            onTap: () async {
+                              try {
+                                if (FocusScope.of(context).hasFocus) {
+                                  FocusScope.of(context).unfocus();
+                                  await Future<void>.delayed(
+                                      const Duration(milliseconds: 75));
+                                }
+
+                                final qrResult = await scanner.scan();
+
+                                Logging.instance.log(
+                                    "qrResult content: ${qrResult.rawContent}",
+                                    level: LogLevel.Info);
+
+                                final results =
+                                    AddressUtils.parseUri(qrResult.rawContent);
+
+                                Logging.instance.log(
+                                    "qrResult parsed: $results",
+                                    level: LogLevel.Info);
+
+                                if (results.isNotEmpty &&
+                                    results["scheme"] == coin.uriScheme) {
+                                  // auto fill address
+                                  _address = results["address"] ?? "";
+                                  sendToController.text = _address!;
+
+                                  // autofill notes field
+                                  if (results["message"] != null) {
+                                    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.decimalPlaces,
+                                    );
+                                    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) {
+                                // 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(),
+                          )
+                      ],
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          ),
+          Builder(
+            builder: (_) {
+              final error = _updateInvalidAddressText(
+                _address ?? "",
+                ref.read(walletsChangeNotifierProvider).getManager(walletId),
+              );
+
+              if (error == null || error.isEmpty) {
+                return Container();
+              } else {
+                return Align(
+                  alignment: Alignment.topLeft,
+                  child: Padding(
+                    padding: const EdgeInsets.only(
+                      left: 12.0,
+                      top: 4.0,
+                    ),
+                    child: Text(
+                      error,
+                      textAlign: TextAlign.left,
+                      style: STextStyles.label(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textError,
+                      ),
+                    ),
+                  ),
+                );
+              }
+            },
+          ),
+          const SizedBox(
+            height: 20,
+          ),
+          Text(
+            "Note (optional)",
+            style: STextStyles.smallMed12(context),
+            textAlign: TextAlign.left,
+          ),
+          const SizedBox(
+            height: 10,
+          ),
+          ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
+              controller: noteController,
+              focusNode: _noteFocusNode,
+              style: STextStyles.field(context),
+              onChanged: (_) => setState(() {}),
+              decoration: standardInputDecoration(
+                "Type something...",
+                _noteFocusNode,
+                context,
+              ).copyWith(
+                suffixIcon: noteController.text.isNotEmpty
+                    ? Padding(
+                        padding: const EdgeInsets.only(right: 0),
+                        child: UnconstrainedBox(
+                          child: Row(
+                            children: [
+                              TextFieldIconButton(
+                                child: const XIcon(),
+                                onTap: () async {
+                                  setState(() {
+                                    noteController.text = "";
+                                  });
+                                },
+                              ),
+                            ],
+                          ),
+                        ),
+                      )
+                    : null,
+              ),
+            ),
+          ),
+          const SizedBox(
+            height: 36,
+          ),
+          PrimaryButton(
+            label: "Preview send",
+            enabled: ref.watch(previewTxButtonStateProvider.state).state,
+            onPressed: ref.watch(previewTxButtonStateProvider.state).state
+                ? previewSend
+                : null,
+          )
+        ],
+      ),
+    );
+  }
+}

From 77354123039ce24d3089fe26156f3ad5220a01bb Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 26 Oct 2022 13:43:22 -0600
Subject: [PATCH 032/426] basic desktop receive layout

---
 .../wallet_view/desktop_wallet_view.dart      |   7 +-
 .../wallet_view/receive/desktop_receive.dart  | 237 +++++++++++++++++-
 .../wallet_view/send/desktop_send.dart        |   1 +
 3 files changed, 237 insertions(+), 8 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 959f9c052..510c4bc7c 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -264,7 +264,12 @@ class _MyWalletState extends State<MyWallet> {
                             walletId: widget.walletId,
                           ),
                         ),
-                        DesktopReceive(),
+                        Padding(
+                          padding: const EdgeInsets.all(20),
+                          child: DesktopReceive(
+                            walletId: widget.walletId,
+                          ),
+                        ),
                       ],
                     ),
                   ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
index 319076dfe..2efbcd84f 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
@@ -1,17 +1,240 @@
-import 'package:flutter/material.dart';
+import 'dart:async';
 
-class DesktopReceive extends StatefulWidget {
-  const DesktopReceive({Key? key}) : super(key: key);
+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:qr_flutter/qr_flutter.dart';
+import 'package:stackwallet/notifications/show_flush_bar.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/enums/flush_bar_type.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/custom_loading_overlay.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class DesktopReceive extends ConsumerStatefulWidget {
+  const DesktopReceive({
+    Key? key,
+    required this.walletId,
+    this.clipboard = const ClipboardWrapper(),
+  }) : super(key: key);
+
+  final String walletId;
+  final ClipboardInterface clipboard;
 
   @override
-  State<DesktopReceive> createState() => _DesktopReceiveState();
+  ConsumerState<DesktopReceive> createState() => _DesktopReceiveState();
 }
 
-class _DesktopReceiveState extends State<DesktopReceive> {
+class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
+  late final Coin coin;
+  late final String walletId;
+  late final ClipboardInterface clipboard;
+
+  Future<void> generateNewAddress() async {
+    bool shouldPop = false;
+    unawaited(
+      showDialog(
+        context: context,
+        builder: (_) {
+          return WillPopScope(
+            onWillPop: () async => shouldPop,
+            child: Container(
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .overlay
+                  .withOpacity(0.5),
+              child: const CustomLoadingOverlay(
+                message: "Generating address",
+                eventBus: null,
+              ),
+            ),
+          );
+        },
+      ),
+    );
+
+    await ref
+        .read(walletsChangeNotifierProvider)
+        .getManager(walletId)
+        .generateNewAddress();
+
+    shouldPop = true;
+
+    if (mounted) {
+      Navigator.of(context, rootNavigator: true).pop();
+    }
+  }
+
+  String receivingAddress = "";
+
+  @override
+  void initState() {
+    walletId = widget.walletId;
+    coin = ref.read(walletsChangeNotifierProvider).getManager(walletId).coin;
+    clipboard = widget.clipboard;
+
+    WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
+      final address = await ref
+          .read(walletsChangeNotifierProvider)
+          .getManager(walletId)
+          .currentReceivingAddress;
+      setState(() {
+        receivingAddress = address;
+      });
+    });
+
+    super.initState();
+  }
+
   @override
   Widget build(BuildContext context) {
-    return Container(
-      color: Colors.green,
+    debugPrint("BUILD: $runtimeType");
+
+    ref.listen(
+        ref
+            .read(walletsChangeNotifierProvider)
+            .getManagerProvider(walletId)
+            .select((value) => value.currentReceivingAddress),
+        (previous, next) {
+      if (next is Future<String>) {
+        next.then((value) => setState(() => receivingAddress = value));
+      }
+    });
+
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.stretch,
+      children: [
+        GestureDetector(
+          onTap: () {
+            clipboard.setData(
+              ClipboardData(text: receivingAddress),
+            );
+            showFloatingFlushBar(
+              type: FlushBarType.info,
+              message: "Copied to clipboard",
+              iconAsset: Assets.svg.copy,
+              context: context,
+            );
+          },
+          child: Container(
+            decoration: BoxDecoration(
+              border: Border.all(
+                color: Theme.of(context).extension<StackColors>()!.background,
+                width: 2,
+              ),
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+            ),
+            child: RoundedWhiteContainer(
+              child: Column(
+                children: [
+                  Row(
+                    children: [
+                      Text(
+                        "Your ${coin.ticker} address",
+                        style: STextStyles.itemSubtitle(context),
+                      ),
+                      const Spacer(),
+                      Row(
+                        children: [
+                          SvgPicture.asset(
+                            Assets.svg.copy,
+                            width: 10,
+                            height: 10,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .infoItemIcons,
+                          ),
+                          const SizedBox(
+                            width: 4,
+                          ),
+                          Text(
+                            "Copy",
+                            style: STextStyles.link2(context),
+                          ),
+                        ],
+                      ),
+                    ],
+                  ),
+                  const SizedBox(
+                    height: 4,
+                  ),
+                  Row(
+                    children: [
+                      Expanded(
+                        child: Text(
+                          receivingAddress,
+                          style: STextStyles.itemSubtitle12(context),
+                        ),
+                      ),
+                    ],
+                  ),
+                ],
+              ),
+            ),
+          ),
+        ),
+        if (coin != Coin.epicCash)
+          const SizedBox(
+            height: 20,
+          ),
+        if (coin != Coin.epicCash)
+          SecondaryButton(
+            height: 56,
+            onPressed: generateNewAddress,
+            label: "Generate new address",
+          ),
+        const SizedBox(
+          height: 32,
+        ),
+        Center(
+          child: SizedBox(
+            width: 200,
+            height: 200,
+            child: QrImage(
+                data: "${coin.uriScheme}:$receivingAddress",
+                size: MediaQuery.of(context).size.width / 2,
+                foregroundColor: Theme.of(context)
+                    .extension<StackColors>()!
+                    .accentColorDark),
+          ),
+        ),
+        const SizedBox(
+          height: 32,
+        ),
+        Center(
+          child: BlueTextButton(
+            text: "Create new QR code",
+            onTap: () async {
+              unawaited(
+                Navigator.of(context).push(
+                  RouteGenerator.getRoute(
+                    shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
+                    builder: (_) => GenerateUriQrCodeView(
+                      coin: coin,
+                      receivingAddress: receivingAddress,
+                    ),
+                    settings: const RouteSettings(
+                      name: GenerateUriQrCodeView.routeName,
+                    ),
+                  ),
+                ),
+              );
+            },
+          ),
+        ),
+      ],
     );
   }
 }
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
index 8f45b70c4..866f1ab56 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
@@ -1158,6 +1158,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             height: 36,
           ),
           PrimaryButton(
+            height: 56,
             label: "Preview send",
             enabled: ref.watch(previewTxButtonStateProvider.state).state,
             onPressed: ref.watch(previewTxButtonStateProvider.state).state

From 992debc86ae98a2635af18551c20fd31cf0a10f7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 26 Oct 2022 15:04:04 -0600
Subject: [PATCH 033/426] desktop menu icons update and exit functionality
 implemented

---
 assets/svg/about-desktop.svg                  |   3 +
 assets/svg/address-book-desktop.svg           |   3 +
 assets/svg/exchange-desktop.svg               |   3 +
 assets/svg/exit-desktop.svg                   |   3 +
 assets/svg/wallet-desktop.svg                 |   3 +
 .../home/desktop_home_view.dart               |   3 -
 .../home/desktop_menu.dart                    | 303 +++++++++++-------
 lib/utilities/assets.dart                     |   5 +
 pubspec.yaml                                  |   5 +
 9 files changed, 208 insertions(+), 123 deletions(-)
 create mode 100644 assets/svg/about-desktop.svg
 create mode 100644 assets/svg/address-book-desktop.svg
 create mode 100644 assets/svg/exchange-desktop.svg
 create mode 100644 assets/svg/exit-desktop.svg
 create mode 100644 assets/svg/wallet-desktop.svg

diff --git a/assets/svg/about-desktop.svg b/assets/svg/about-desktop.svg
new file mode 100644
index 000000000..a80067d9c
--- /dev/null
+++ b/assets/svg/about-desktop.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3.44444 2.21973C2.09618 2.21973 1 3.31591 1 4.66417V15.6642C1 17.0124 2.09618 18.1086 3.44444 18.1086H10.1667L9.75799 19.3308H7.11111C6.43507 19.3308 5.88889 19.877 5.88889 20.5531C5.88889 21.2291 6.43507 21.7753 7.11111 21.7753H16.8889C17.5649 21.7753 18.1111 21.2291 18.1111 20.5531C18.1111 19.877 17.5649 19.3308 16.8889 19.3308H14.242L13.8333 18.1086H20.5556C21.9038 18.1086 23 17.0124 23 15.6642V4.66417C23 3.31591 21.9038 2.21973 20.5556 2.21973H3.44444ZM20.5556 4.66417V13.2197H3.44444V4.66417H20.5556Z" fill="#232323"/>
+</svg>
diff --git a/assets/svg/address-book-desktop.svg b/assets/svg/address-book-desktop.svg
new file mode 100644
index 000000000..fb85e3e11
--- /dev/null
+++ b/assets/svg/address-book-desktop.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M16.8242 1H4.44922C2.93027 1 1.69922 2.23105 1.69922 3.75V20.25C1.69922 21.7689 2.93027 23 4.44922 23H16.8242C18.3432 23 19.5742 21.7689 19.5742 20.25V3.75C19.5742 2.23105 18.341 1 16.8242 1ZM10.6367 6.5C12.1557 6.5 13.3867 7.73105 13.3867 9.25C13.3867 10.7689 12.1557 12 10.6367 12C9.1182 12 7.88672 10.7689 7.88672 9.25C7.88672 7.73105 9.11992 6.5 10.6367 6.5ZM14.7617 17.5H6.51172C6.13359 17.5 5.82422 17.1906 5.82422 16.8125C5.82422 14.9133 7.3625 13.375 9.26172 13.375H12.0117C13.9101 13.375 15.4492 14.9141 15.4492 16.8125C15.4492 17.1906 15.1398 17.5 14.7617 17.5ZM21.6367 3.75H20.9492V7.875H21.6367C22.0148 7.875 22.3242 7.56563 22.3242 7.1875V4.4375C22.3242 4.05766 22.0148 3.75 21.6367 3.75ZM21.6367 9.25H20.9492V13.375H21.6367C22.0148 13.375 22.3242 13.0656 22.3242 12.6875V9.9375C22.3242 9.55937 22.0148 9.25 21.6367 9.25ZM21.6367 14.75H20.9492V18.875H21.6367C22.0164 18.875 22.3242 18.5672 22.3242 18.1875V15.4375C22.3242 15.0594 22.0148 14.75 21.6367 14.75Z" fill="#232323"/>
+</svg>
diff --git a/assets/svg/exchange-desktop.svg b/assets/svg/exchange-desktop.svg
new file mode 100644
index 000000000..8eacfa84e
--- /dev/null
+++ b/assets/svg/exchange-desktop.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M6.69844 6.70024C9.61406 3.78461 14.325 3.77055 17.2594 6.65336L15.3281 8.57993C15.0047 8.90336 14.9109 9.38618 15.0844 9.80805C15.2578 10.2299 15.6703 10.5018 16.125 10.5018H21.7266H22.125C22.7484 10.5018 23.25 10.0002 23.25 9.3768V3.3768C23.25 2.92211 22.9781 2.50961 22.5563 2.33618C22.1344 2.16274 21.6516 2.25649 21.3281 2.57993L19.3781 4.52993C15.2719 0.475238 8.65781 0.489301 4.575 4.5768C3.43125 5.72055 2.60625 7.06586 2.1 8.50492C1.82344 9.28774 2.23594 10.1409 3.01406 10.4174C3.79219 10.694 4.65 10.2815 4.92656 9.50336C5.2875 8.48149 5.87344 7.52055 6.69844 6.70024ZM0.75 14.6268V14.9831V15.0159V20.6268C0.75 21.0815 1.02187 21.494 1.44375 21.6674C1.86562 21.8409 2.34844 21.7471 2.67188 21.4237L4.62187 19.4737C8.72812 23.5284 15.3422 23.5143 19.425 19.4268C20.5688 18.2831 21.3984 16.9377 21.9047 15.5034C22.1812 14.7206 21.7687 13.8674 20.9906 13.5909C20.2125 13.3143 19.3547 13.7268 19.0781 14.5049C18.7172 15.5268 18.1313 16.4877 17.3063 17.3081C14.3906 20.2237 9.67969 20.2377 6.74531 17.3549L8.67188 15.4237C8.99531 15.1002 9.08906 14.6174 8.91562 14.1956C8.74219 13.7737 8.32969 13.5018 7.875 13.5018H2.26875H2.23594H1.875C1.25156 13.5018 0.75 14.0034 0.75 14.6268Z" fill="#232323"/>
+</svg>
diff --git a/assets/svg/exit-desktop.svg b/assets/svg/exit-desktop.svg
new file mode 100644
index 000000000..abba264cd
--- /dev/null
+++ b/assets/svg/exit-desktop.svg
@@ -0,0 +1,3 @@
+<svg width="22" height="20" viewBox="0 0 22 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M6.875 3.12012C7.63555 3.12012 8.25 2.50566 8.25 1.74512C8.25 0.98457 7.63555 0.370117 6.875 0.370117H4.125C1.84766 0.370117 0 2.21777 0 4.49512V15.4951C0 17.7725 1.84766 19.6201 4.125 19.6201H6.875C7.63555 19.6201 8.25 19.0057 8.25 18.2451C8.25 17.4846 7.63555 16.8701 6.875 16.8701H4.125C3.36445 16.8701 2.75 16.2557 2.75 15.4951V4.49512C2.75 3.73457 3.36445 3.12012 4.125 3.12012H6.875ZM21.6777 10.7428C21.884 10.5494 22 10.2787 22 9.99512C22 9.71152 21.884 9.44082 21.6777 9.24746L15.4902 3.40371C15.1895 3.12012 14.7512 3.04277 14.373 3.20605C13.9949 3.36934 13.75 3.74316 13.75 4.15137V7.24512H8.25C7.48945 7.24512 6.875 7.85957 6.875 8.62012V11.3701C6.875 12.1307 7.48945 12.7451 8.25 12.7451H13.75V15.8389C13.75 16.2514 13.9949 16.6209 14.373 16.7842C14.7512 16.9475 15.1895 16.8701 15.4902 16.5865L21.6777 10.7428Z" fill="#232323"/>
+</svg>
diff --git a/assets/svg/wallet-desktop.svg b/assets/svg/wallet-desktop.svg
new file mode 100644
index 000000000..0b0acdae3
--- /dev/null
+++ b/assets/svg/wallet-desktop.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M20.25 2.83008C21.0105 2.83008 21.625 3.4165 21.625 4.1396C21.625 4.8627 21.0105 5.44913 20.25 5.44913H4.4375C4.05766 5.44913 3.75 5.74377 3.75 6.10389C3.75 6.46401 4.05766 6.75865 4.4375 6.75865H20.25C21.7668 6.75865 23 7.93313 23 9.3777V18.5444C23 19.9889 21.7668 21.1634 20.25 21.1634H3.75C2.23105 21.1634 1 19.9889 1 18.5444V5.44913C1 4.00251 2.23105 2.83008 3.75 2.83008H20.25ZM18.875 15.2706C19.6355 15.2706 20.25 14.6854 20.25 13.961C20.25 13.2367 19.6355 12.6515 18.875 12.6515C18.1145 12.6515 17.5 13.2367 17.5 13.961C17.5 14.6854 18.1145 15.2706 18.875 15.2706Z" fill="#232323"/>
+</svg>
diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index 41f4b5041..6aa104081 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -43,9 +43,6 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
     Container(
       color: Colors.pink,
     ),
-    Container(
-      color: Colors.purple,
-    ),
   ];
 
   void onMenuSelectionChanged(int newIndex) {
diff --git a/lib/pages_desktop_specific/home/desktop_menu.dart b/lib/pages_desktop_specific/home/desktop_menu.dart
index b71c20f6e..7409a4156 100644
--- a/lib/pages_desktop_specific/home/desktop_menu.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu.dart
@@ -1,3 +1,5 @@
+import 'dart:io';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
@@ -70,136 +72,197 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
             const SizedBox(
               height: 60,
             ),
-            SizedBox(
-              width: _width == expandedWidth
-                  ? _width - 32 // 16 padding on either side
-                  : _width - 16, // 8 padding on either side
-              child: Column(
-                crossAxisAlignment: CrossAxisAlignment.stretch,
-                children: [
-                  DesktopMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.walletFa,
-                      width: 20,
-                      height: 20,
+            Expanded(
+              child: SizedBox(
+                width: _width == expandedWidth
+                    ? _width - 32 // 16 padding on either side
+                    : _width - 16, // 8 padding on either side
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.stretch,
+                  children: [
+                    DesktopMenuItem(
+                      icon: SvgPicture.asset(
+                        Assets.svg.walletDesktop,
+                        width: 20,
+                        height: 20,
+                        color: 0 == selectedMenuItem
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                                .withOpacity(0.8),
+                      ),
+                      label: "My Stack",
+                      value: 0,
+                      group: selectedMenuItem,
+                      onChanged: updateSelectedMenuItem,
+                      iconOnly: _width == minimizedWidth,
                     ),
-                    label: "My Stack",
-                    value: 0,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                    iconOnly: _width == minimizedWidth,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  DesktopMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.exchange3,
-                      width: 20,
-                      height: 20,
+                    const SizedBox(
+                      height: 2,
                     ),
-                    label: "Exchange",
-                    value: 1,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                    iconOnly: _width == minimizedWidth,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  DesktopMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.bell,
-                      width: 20,
-                      height: 20,
+                    DesktopMenuItem(
+                      icon: SvgPicture.asset(
+                        Assets.svg.exchangeDesktop,
+                        width: 20,
+                        height: 20,
+                        color: 1 == selectedMenuItem
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                                .withOpacity(0.8),
+                      ),
+                      label: "Exchange",
+                      value: 1,
+                      group: selectedMenuItem,
+                      onChanged: updateSelectedMenuItem,
+                      iconOnly: _width == minimizedWidth,
                     ),
-                    label: "Notifications",
-                    value: 2,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                    iconOnly: _width == minimizedWidth,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  DesktopMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.addressBook2,
-                      width: 20,
-                      height: 20,
+                    const SizedBox(
+                      height: 2,
                     ),
-                    label: "Address Book",
-                    value: 3,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                    iconOnly: _width == minimizedWidth,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  DesktopMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.gear,
-                      width: 20,
-                      height: 20,
+                    DesktopMenuItem(
+                      icon: SvgPicture.asset(
+                        Assets.svg.bell,
+                        width: 20,
+                        height: 20,
+                        color: 2 == selectedMenuItem
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                                .withOpacity(0.8),
+                      ),
+                      label: "Notifications",
+                      value: 2,
+                      group: selectedMenuItem,
+                      onChanged: updateSelectedMenuItem,
+                      iconOnly: _width == minimizedWidth,
                     ),
-                    label: "Settings",
-                    value: 4,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                    iconOnly: _width == minimizedWidth,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  DesktopMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.messageQuestion,
-                      width: 20,
-                      height: 20,
+                    const SizedBox(
+                      height: 2,
                     ),
-                    label: "Support",
-                    value: 5,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                    iconOnly: _width == minimizedWidth,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  DesktopMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.messageQuestion,
-                      width: 20,
-                      height: 20,
+                    DesktopMenuItem(
+                      icon: SvgPicture.asset(
+                        Assets.svg.addressBookDesktop,
+                        width: 20,
+                        height: 20,
+                        color: 3 == selectedMenuItem
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                                .withOpacity(0.8),
+                      ),
+                      label: "Address Book",
+                      value: 3,
+                      group: selectedMenuItem,
+                      onChanged: updateSelectedMenuItem,
+                      iconOnly: _width == minimizedWidth,
                     ),
-                    label: "About",
-                    value: 6,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                    iconOnly: _width == minimizedWidth,
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  DesktopMenuItem(
-                    icon: SvgPicture.asset(
-                      Assets.svg.messageQuestion,
-                      width: 20,
-                      height: 20,
+                    const SizedBox(
+                      height: 2,
                     ),
-                    label: "Exit",
-                    value: 7,
-                    group: selectedMenuItem,
-                    onChanged: updateSelectedMenuItem,
-                    iconOnly: _width == minimizedWidth,
-                  ),
-                ],
+                    DesktopMenuItem(
+                      icon: SvgPicture.asset(
+                        Assets.svg.gear,
+                        width: 20,
+                        height: 20,
+                        color: 4 == selectedMenuItem
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                                .withOpacity(0.8),
+                      ),
+                      label: "Settings",
+                      value: 4,
+                      group: selectedMenuItem,
+                      onChanged: updateSelectedMenuItem,
+                      iconOnly: _width == minimizedWidth,
+                    ),
+                    const SizedBox(
+                      height: 2,
+                    ),
+                    DesktopMenuItem(
+                      icon: SvgPicture.asset(
+                        Assets.svg.messageQuestion,
+                        width: 20,
+                        height: 20,
+                        color: 5 == selectedMenuItem
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                                .withOpacity(0.8),
+                      ),
+                      label: "Support",
+                      value: 5,
+                      group: selectedMenuItem,
+                      onChanged: updateSelectedMenuItem,
+                      iconOnly: _width == minimizedWidth,
+                    ),
+                    const SizedBox(
+                      height: 2,
+                    ),
+                    DesktopMenuItem(
+                      icon: SvgPicture.asset(
+                        Assets.svg.aboutDesktop,
+                        width: 20,
+                        height: 20,
+                        color: 6 == selectedMenuItem
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                                .withOpacity(0.8),
+                      ),
+                      label: "About",
+                      value: 6,
+                      group: selectedMenuItem,
+                      onChanged: updateSelectedMenuItem,
+                      iconOnly: _width == minimizedWidth,
+                    ),
+                    const Spacer(),
+                    DesktopMenuItem(
+                      icon: SvgPicture.asset(
+                        Assets.svg.exitDesktop,
+                        width: 20,
+                        height: 20,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark
+                            .withOpacity(0.8),
+                      ),
+                      label: "Exit",
+                      value: 7,
+                      group: selectedMenuItem,
+                      onChanged: (_) {
+                        // todo: save stuff/ notify before exit?
+                        exit(0);
+                      },
+                      iconOnly: _width == minimizedWidth,
+                    ),
+                  ],
+                ),
               ),
             ),
-            const Spacer(),
             Row(
-              mainAxisAlignment: MainAxisAlignment.end,
               children: [
                 const Spacer(),
                 IconButton(
@@ -212,7 +275,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                   ),
                 ),
               ],
-            )
+            ),
           ],
         ),
       ),
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 2ada80a5d..ebe2d9848 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -139,6 +139,11 @@ class _SVG {
   String get anonymize => "assets/svg/tx-icon-anonymize.svg";
   String get anonymizePending => "assets/svg/tx-icon-anonymize-pending.svg";
   String get anonymizeFailed => "assets/svg/tx-icon-anonymize-failed.svg";
+  String get addressBookDesktop => "assets/svg/address-book-desktop.svg";
+  String get exchangeDesktop => "assets/svg/exchange-desktop.svg";
+  String get aboutDesktop => "assets/svg/about-desktop.svg";
+  String get walletDesktop => "assets/svg/wallet-desktop.svg";
+  String get exitDesktop => "assets/svg/exit-desktop.svg";
 
   String get ellipse1 => "assets/svg/Ellipse-43.svg";
   String get ellipse2 => "assets/svg/Ellipse-42.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index 35fbecf3f..aabf3f3de 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -301,6 +301,11 @@ flutter:
     - assets/svg/node-circle.svg
     - assets/svg/dark/dark-theme.svg
     - assets/svg/light/light-mode.svg
+    - assets/svg/address-book-desktop.svg
+    - assets/svg/about-desktop.svg
+    - assets/svg/exchange-desktop.svg
+    - assets/svg/wallet-desktop.svg
+    - assets/svg/exit-desktop.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Bitcoincash.svg

From 480266ef5f236078443df76786c222b549e598f6 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 26 Oct 2022 15:09:58 -0600
Subject: [PATCH 034/426] lock send/receive width

---
 .../home/my_stack_view/wallet_view/desktop_wallet_view.dart    | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 510c4bc7c..8a5c35d8d 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -174,7 +174,8 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
             Expanded(
               child: Row(
                 children: [
-                  Expanded(
+                  SizedBox(
+                    width: 450,
                     child: MyWallet(
                       walletId: walletId,
                     ),

From b4e7e219a4a465f21d9cb86213e4a0e0b57bd76c Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 26 Oct 2022 16:07:37 -0600
Subject: [PATCH 035/426] started nodes dialog popup

---
 .../manage_nodes_views/coin_nodes_view.dart   | 187 ++++++++++++------
 .../settings_menu/enable_backup_dialog.dart   |   0
 .../home/settings_menu/nodes_settings.dart    |  24 ++-
 3 files changed, 141 insertions(+), 70 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart

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 12573042e..e3743d54e 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
@@ -7,7 +7,10 @@ import 'package:stackwallet/utilities/assets.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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:tuple/tuple.dart';
 
 class CoinNodesView extends ConsumerStatefulWidget {
@@ -37,69 +40,139 @@ class _CoinNodesViewState extends ConsumerState<CoinNodesView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "${widget.coin.prettyName} nodes",
-          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("manageNodesAddNewNodeButtonKey"),
-                size: 36,
-                shadows: const [],
-                color: Theme.of(context).extension<StackColors>()!.background,
-                icon: SvgPicture.asset(
-                  Assets.svg.plus,
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .accentColorDark,
-                  width: 20,
-                  height: 20,
+    if (Util.isDesktop) {
+      return DesktopDialog(
+        child: Column(
+          children: [
+            Row(
+              children: [
+                const SizedBox(
+                  width: 32,
                 ),
-                onPressed: () {
-                  Navigator.of(context).pushNamed(
-                    AddEditNodeView.routeName,
-                    arguments: Tuple4(
-                      AddEditNodeViewType.add,
-                      widget.coin,
-                      null,
-                      CoinNodesView.routeName,
+                SvgPicture.asset(
+                  Assets.svg.iconFor(coin: widget.coin),
+                  width: 24,
+                  height: 24,
+                ),
+                const SizedBox(
+                  width: 12,
+                ),
+                Text(
+                  "${widget.coin.prettyName} nodes",
+                  style: STextStyles.desktopH3(context),
+                  textAlign: TextAlign.center,
+                ),
+                Expanded(
+                  child: const DesktopDialogCloseButton(),
+                ),
+              ],
+            ),
+            Padding(
+              padding: EdgeInsets.only(
+                left: 32,
+                right: 32,
+              ),
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Text(
+                    "${widget.coin.prettyName} nodes",
+                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color:
+                          Theme.of(context).extension<StackColors>()!.textDark3,
                     ),
-                  );
-                },
+                    textAlign: TextAlign.left,
+                  ),
+                  RichText(
+                    text: TextSpan(
+                      text: 'Add new nodes',
+                      style:
+                          STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color: Colors.blueAccent,
+                      ),
+                    ),
+                  ),
+                ],
               ),
             ),
-          ),
-        ],
-      ),
-      body: Padding(
-        padding: const EdgeInsets.only(
-          top: 12,
-          left: 12,
-          right: 12,
+            const SizedBox(
+              width: 12,
+            ),
+            Padding(
+              padding: const EdgeInsets.all(20),
+              child: NodesList(
+                coin: widget.coin,
+                popBackToRoute: CoinNodesView.routeName,
+              ),
+            ),
+          ],
         ),
-        child: SingleChildScrollView(
-          child: NodesList(
-            coin: widget.coin,
-            popBackToRoute: CoinNodesView.routeName,
+      );
+    } else {
+      return Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "${widget.coin.prettyName} nodes",
+            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("manageNodesAddNewNodeButtonKey"),
+                  size: 36,
+                  shadows: const [],
+                  color: Theme.of(context).extension<StackColors>()!.background,
+                  icon: SvgPicture.asset(
+                    Assets.svg.plus,
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .accentColorDark,
+                    width: 20,
+                    height: 20,
+                  ),
+                  onPressed: () {
+                    Navigator.of(context).pushNamed(
+                      AddEditNodeView.routeName,
+                      arguments: Tuple4(
+                        AddEditNodeViewType.add,
+                        widget.coin,
+                        null,
+                        CoinNodesView.routeName,
+                      ),
+                    );
+                  },
+                ),
+              ),
+            ),
+          ],
+        ),
+        body: Padding(
+          padding: const EdgeInsets.only(
+            top: 12,
+            left: 12,
+            right: 12,
+          ),
+          child: SingleChildScrollView(
+            child: NodesList(
+              coin: widget.coin,
+              popBackToRoute: CoinNodesView.routeName,
+            ),
           ),
         ),
-      ),
-    );
+      );
+    }
   }
 }
diff --git a/lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart
new file mode 100644
index 000000000..e69de29bb
diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index 8608e79af..f354927c4 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -5,12 +5,13 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/providers/global/node_service_provider.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
+import '../../../pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
+import '../../../utilities/constants.dart';
+
 class NodesSettings extends ConsumerStatefulWidget {
   const NodesSettings({Key? key}) : super(key: key);
 
@@ -37,9 +38,6 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
 
   @override
   Widget build(BuildContext context) {
-    double deviceWidth(BuildContext context) =>
-        MediaQuery.of(context).size.width;
-
     bool showTestNet = ref.watch(
       prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
     );
@@ -108,18 +106,18 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                                 borderRadius: BorderRadius.circular(
                                   Constants.size.circularBorderRadius,
                                 ),
-                                side: BorderSide(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .shadow),
+                                // side: BorderSide(
+                                //     color: Theme.of(context)
+                                //         .extension<StackColors>()!
+                                //         .shadow),
                               ),
                               materialTapTargetSize:
                                   MaterialTapTargetSize.shrinkWrap,
                               onPressed: () {
-                                // Navigator.of(context).pushNamed(
-                                //   CoinNodesView.routeName,
-                                //   arguments: coin,
-                                // );
+                                Navigator.of(context).pushNamed(
+                                  CoinNodesView.routeName,
+                                  arguments: coin,
+                                );
                               },
                               child: Padding(
                                 padding: const EdgeInsets.all(

From da408860126e6f4989f8dd5c6fd91517abb674de Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 26 Oct 2022 16:17:39 -0600
Subject: [PATCH 036/426] auto backup dialog started

---
 .../settings_menu/enable_backup_dialog.dart   | 73 +++++++++++++++++++
 .../home/settings_menu/security_settings.dart | 43 ++++++++++-
 2 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart
index e69de29bb..4925177c3 100644
--- a/lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart
@@ -0,0 +1,73 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+class EnableBackupDialog extends StatelessWidget {
+  const EnableBackupDialog({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.all(32),
+                child: Text(
+                  "Enable Auto Backup",
+                  style: STextStyles.desktopH3(context),
+                  textAlign: TextAlign.center,
+                ),
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+          const SizedBox(
+            height: 30,
+          ),
+          Text(
+            "To enable Auto Backup, you need to create a backup file.",
+            style: STextStyles.desktopTextSmall(context).copyWith(
+              color: Theme.of(context).extension<StackColors>()!.textDark3,
+            ),
+            textAlign: TextAlign.center,
+          ),
+          const Spacer(),
+          Padding(
+            padding: const EdgeInsets.all(32),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    onPressed: () {
+                      Navigator.of(context).pop();
+                    },
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Continue",
+                    onPressed: () {
+                      // Navigator.of(context).pop();
+                      // onConfirm.call();
+                    },
+                  ),
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index febb1dc1b..7c36be8cd 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -4,9 +4,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
+import '../../../utilities/theme/stack_colors.dart';
+import 'enable_backup_dialog.dart';
+
 class SecuritySettings extends ConsumerStatefulWidget {
   const SecuritySettings({Key? key}) : super(key: key);
 
@@ -17,6 +19,23 @@ class SecuritySettings extends ConsumerStatefulWidget {
 }
 
 class _SecuritySettings extends ConsumerState<SecuritySettings> {
+  Future<void> enableAutoBackup() async {
+    // wait for keyboard to disappear
+    FocusScope.of(context).unfocus();
+    await Future<void>.delayed(
+      const Duration(milliseconds: 100),
+    );
+
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) {
+        return EnableBackupDialog();
+      },
+    );
+  }
+
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
@@ -82,8 +101,26 @@ class NewPasswordButton extends ConsumerWidget {
   const NewPasswordButton({
     Key? key,
   }) : super(key: key);
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    Future<void> enableAutoBackup() async {
+      // wait for keyboard to disappear
+      FocusScope.of(context).unfocus();
+      await Future<void>.delayed(
+        const Duration(milliseconds: 100),
+      );
+
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: true,
+        builder: (context) {
+          return EnableBackupDialog();
+        },
+      );
+    }
+
     return SizedBox(
       width: 200,
       height: 48,
@@ -91,7 +128,9 @@ class NewPasswordButton extends ConsumerWidget {
         style: Theme.of(context)
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
+        onPressed: () {
+          enableAutoBackup();
+        },
         child: Text(
           "Set up new password",
           style: STextStyles.button(context),

From 2a27776acfe287061d567bcedb508c832ab435cc Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 26 Oct 2022 16:00:54 -0600
Subject: [PATCH 037/426] lock send/receive height to fit

---
 .../wallet_view/desktop_wallet_view.dart      |  206 ++-
 .../wallet_view/receive/desktop_receive.dart  |   14 +-
 .../wallet_view/send/desktop_send.dart        | 1114 ++++++++---------
 3 files changed, 721 insertions(+), 613 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 8a5c35d8d..4c2b510de 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -209,6 +209,8 @@ class MyWallet extends StatefulWidget {
 }
 
 class _MyWalletState extends State<MyWallet> {
+  int _selectedIndex = 0;
+
   @override
   Widget build(BuildContext context) {
     return Column(
@@ -225,53 +227,171 @@ class _MyWalletState extends State<MyWallet> {
         const SizedBox(
           height: 16,
         ),
+        Container(
+          decoration: BoxDecoration(
+            color: Theme.of(context).extension<StackColors>()!.popupBG,
+            borderRadius: BorderRadius.vertical(
+              top: Radius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+            ),
+          ),
+          child: SendReceiveTabMenu(
+            onChanged: (index) {
+              setState(() {
+                _selectedIndex = index;
+              });
+            },
+          ),
+        ),
+        Container(
+          decoration: BoxDecoration(
+            color: Theme.of(context).extension<StackColors>()!.popupBG,
+            borderRadius: BorderRadius.vertical(
+              bottom: Radius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+            ),
+          ),
+          child: IndexedStack(
+            index: _selectedIndex,
+            children: [
+              Padding(
+                key: const Key("desktopSendViewPortKey"),
+                padding: const EdgeInsets.all(20),
+                child: DesktopSend(
+                  walletId: widget.walletId,
+                ),
+              ),
+              Padding(
+                key: const Key("desktopReceiveViewPortKey"),
+                padding: const EdgeInsets.all(20),
+                child: DesktopReceive(
+                  walletId: widget.walletId,
+                ),
+              ),
+            ],
+          ),
+        ),
+        const Spacer(),
+      ],
+    );
+  }
+}
+
+class SendReceiveTabMenu extends StatefulWidget {
+  const SendReceiveTabMenu({
+    Key? key,
+    this.initialIndex = 0,
+    this.onChanged,
+  }) : super(key: key);
+
+  final int initialIndex;
+  final void Function(int)? onChanged;
+
+  @override
+  State<SendReceiveTabMenu> createState() => _SendReceiveTabMenuState();
+}
+
+class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
+  late int _selectedIndex;
+
+  void _onChanged(int newIndex) {
+    if (_selectedIndex != newIndex) {
+      setState(() {
+        _selectedIndex = newIndex;
+      });
+      widget.onChanged?.call(_selectedIndex);
+    }
+  }
+
+  @override
+  void initState() {
+    _selectedIndex = widget.initialIndex;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      children: [
         Expanded(
-          child: RoundedWhiteContainer(
-            padding: const EdgeInsets.all(0),
-            child: DefaultTabController(
-              length: 2,
+          child: GestureDetector(
+            onTap: () => _onChanged(0),
+            child: Container(
+              color: Colors.transparent,
               child: Column(
                 children: [
-                  TabBar(
-                    indicatorColor: Theme.of(context)
-                        .extension<StackColors>()!
-                        .accentColorBlue,
-                    labelStyle: STextStyles.desktopTextExtraSmall(context),
-                    labelColor: Theme.of(context)
-                        .extension<StackColors>()!
-                        .accentColorBlue,
-                    unselectedLabelColor: Theme.of(context)
-                        .extension<StackColors>()!
-                        .textSubtitle1,
-                    labelPadding: const EdgeInsets.symmetric(
-                      vertical: 6,
-                    ),
-                    splashBorderRadius: BorderRadius.vertical(
-                      top: Radius.circular(
-                        Constants.size.circularBorderRadius,
-                      ),
-                    ),
-                    tabs: const [
-                      Tab(text: "Send"),
-                      Tab(text: "Receive"),
-                    ],
+                  const SizedBox(
+                    height: 16,
                   ),
-                  Expanded(
-                    child: TabBarView(
-                      children: [
-                        Padding(
-                          padding: const EdgeInsets.all(20),
-                          child: DesktopSend(
-                            walletId: widget.walletId,
-                          ),
-                        ),
-                        Padding(
-                          padding: const EdgeInsets.all(20),
-                          child: DesktopReceive(
-                            walletId: widget.walletId,
-                          ),
-                        ),
-                      ],
+                  Text(
+                    "Send",
+                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color: _selectedIndex == 0
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .textSubtitle1,
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 19,
+                  ),
+                  Container(
+                    height: 2,
+                    decoration: BoxDecoration(
+                      color: _selectedIndex == 0
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                    ),
+                  ),
+                ],
+              ),
+            ),
+          ),
+        ),
+        Expanded(
+          child: GestureDetector(
+            onTap: () => _onChanged(1),
+            child: Container(
+              color: Colors.transparent,
+              child: Column(
+                children: [
+                  const SizedBox(
+                    height: 16,
+                  ),
+                  Text(
+                    "Receive",
+                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color: _selectedIndex == 1
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .textSubtitle1,
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 19,
+                  ),
+                  Container(
+                    height: 2,
+                    decoration: BoxDecoration(
+                      color: _selectedIndex == 1
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
                     ),
                   ),
                 ],
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
index 2efbcd84f..79e3b81cf 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
@@ -199,15 +199,11 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
           height: 32,
         ),
         Center(
-          child: SizedBox(
-            width: 200,
-            height: 200,
-            child: QrImage(
-                data: "${coin.uriScheme}:$receivingAddress",
-                size: MediaQuery.of(context).size.width / 2,
-                foregroundColor: Theme.of(context)
-                    .extension<StackColors>()!
-                    .accentColorDark),
+          child: QrImage(
+            data: "${coin.uriScheme}:$receivingAddress",
+            size: 200,
+            foregroundColor:
+                Theme.of(context).extension<StackColors>()!.accentColorDark,
           ),
         ),
         const SizedBox(
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
index 866f1ab56..1579b2367 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
@@ -541,202 +541,301 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
       });
     }
 
-    return SingleChildScrollView(
-      child: Column(
-        crossAxisAlignment: CrossAxisAlignment.start,
-        children: [
-          const SizedBox(
-            height: 4,
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        const SizedBox(
+          height: 4,
+        ),
+        if (coin == Coin.firo)
+          Text(
+            "Send from",
+            style: STextStyles.smallMed12(context),
+            textAlign: TextAlign.left,
           ),
-          if (coin == Coin.firo)
-            Text(
-              "Send from",
-              style: STextStyles.smallMed12(context),
-              textAlign: TextAlign.left,
-            ),
-          if (coin == Coin.firo)
-            const SizedBox(
-              height: 10,
-            ),
-          if (coin == Coin.firo)
-            Stack(
-              children: [
-                TextField(
-                  autocorrect: Util.isDesktop ? false : true,
-                  enableSuggestions: Util.isDesktop ? false : true,
-                  readOnly: true,
-                  textInputAction: TextInputAction.none,
+        if (coin == Coin.firo)
+          const SizedBox(
+            height: 10,
+          ),
+        if (coin == Coin.firo)
+          Stack(
+            children: [
+              TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
+                readOnly: true,
+                textInputAction: TextInputAction.none,
+              ),
+              Padding(
+                padding: const EdgeInsets.symmetric(
+                  horizontal: 12,
                 ),
-                Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                  ),
-                  child: RawMaterialButton(
-                    splashColor:
-                        Theme.of(context).extension<StackColors>()!.highlight,
-                    shape: RoundedRectangleBorder(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
-                      ),
+                child: RawMaterialButton(
+                  splashColor:
+                      Theme.of(context).extension<StackColors>()!.highlight,
+                  shape: RoundedRectangleBorder(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
                     ),
-                    onPressed: () {
-                      showModalBottomSheet<dynamic>(
-                        backgroundColor: Colors.transparent,
-                        context: context,
-                        shape: const RoundedRectangleBorder(
-                          borderRadius: BorderRadius.vertical(
-                            top: Radius.circular(20),
+                  ),
+                  onPressed: () {
+                    showModalBottomSheet<dynamic>(
+                      backgroundColor: Colors.transparent,
+                      context: context,
+                      shape: const RoundedRectangleBorder(
+                        borderRadius: BorderRadius.vertical(
+                          top: Radius.circular(20),
+                        ),
+                      ),
+                      builder: (_) => FiroBalanceSelectionSheet(
+                        walletId: walletId,
+                      ),
+                    );
+                  },
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Row(
+                        children: [
+                          Text(
+                            "${ref.watch(publicPrivateBalanceStateProvider.state).state} balance",
+                            style: STextStyles.itemSubtitle12(context),
                           ),
-                        ),
-                        builder: (_) => FiroBalanceSelectionSheet(
-                          walletId: walletId,
-                        ),
-                      );
-                    },
-                    child: Row(
-                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                      children: [
-                        Row(
-                          children: [
-                            Text(
-                              "${ref.watch(publicPrivateBalanceStateProvider.state).state} balance",
-                              style: STextStyles.itemSubtitle12(context),
-                            ),
-                            const SizedBox(
-                              width: 10,
-                            ),
-                            FutureBuilder(
-                              future: _firoBalanceFuture(provider, locale),
-                              builder:
-                                  (context, AsyncSnapshot<String?> snapshot) {
-                                if (snapshot.connectionState ==
-                                        ConnectionState.done &&
-                                    snapshot.hasData) {
-                                  if (ref
+                          const SizedBox(
+                            width: 10,
+                          ),
+                          FutureBuilder(
+                            future: _firoBalanceFuture(provider, locale),
+                            builder:
+                                (context, AsyncSnapshot<String?> snapshot) {
+                              if (snapshot.connectionState ==
+                                      ConnectionState.done &&
+                                  snapshot.hasData) {
+                                if (ref
+                                        .read(publicPrivateBalanceStateProvider
+                                            .state)
+                                        .state ==
+                                    "Private") {
+                                  _privateBalanceString = snapshot.data!;
+                                } else {
+                                  _publicBalanceString = snapshot.data!;
+                                }
+                              }
+                              if (ref
                                           .read(
                                               publicPrivateBalanceStateProvider
                                                   .state)
                                           .state ==
-                                      "Private") {
-                                    _privateBalanceString = snapshot.data!;
-                                  } else {
-                                    _publicBalanceString = snapshot.data!;
-                                  }
-                                }
-                                if (ref
-                                            .read(
-                                                publicPrivateBalanceStateProvider
-                                                    .state)
-                                            .state ==
-                                        "Private" &&
-                                    _privateBalanceString != null) {
-                                  return Text(
-                                    "$_privateBalanceString ${coin.ticker}",
-                                    style: STextStyles.itemSubtitle(context),
-                                  );
-                                } else if (ref
-                                            .read(
-                                                publicPrivateBalanceStateProvider
-                                                    .state)
-                                            .state ==
-                                        "Public" &&
-                                    _publicBalanceString != null) {
-                                  return Text(
-                                    "$_publicBalanceString ${coin.ticker}",
-                                    style: STextStyles.itemSubtitle(context),
-                                  );
-                                } else {
-                                  return AnimatedText(
-                                    stringsToLoopThrough: const [
-                                      "Loading balance",
-                                      "Loading balance.",
-                                      "Loading balance..",
-                                      "Loading balance...",
-                                    ],
-                                    style: STextStyles.itemSubtitle(context),
-                                  );
-                                }
-                              },
-                            ),
-                          ],
-                        ),
-                        SvgPicture.asset(
-                          Assets.svg.chevronDown,
-                          width: 8,
-                          height: 4,
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .textSubtitle2,
-                        ),
-                      ],
-                    ),
+                                      "Private" &&
+                                  _privateBalanceString != null) {
+                                return Text(
+                                  "$_privateBalanceString ${coin.ticker}",
+                                  style: STextStyles.itemSubtitle(context),
+                                );
+                              } else if (ref
+                                          .read(
+                                              publicPrivateBalanceStateProvider
+                                                  .state)
+                                          .state ==
+                                      "Public" &&
+                                  _publicBalanceString != null) {
+                                return Text(
+                                  "$_publicBalanceString ${coin.ticker}",
+                                  style: STextStyles.itemSubtitle(context),
+                                );
+                              } else {
+                                return AnimatedText(
+                                  stringsToLoopThrough: const [
+                                    "Loading balance",
+                                    "Loading balance.",
+                                    "Loading balance..",
+                                    "Loading balance...",
+                                  ],
+                                  style: STextStyles.itemSubtitle(context),
+                                );
+                              }
+                            },
+                          ),
+                        ],
+                      ),
+                      SvgPicture.asset(
+                        Assets.svg.chevronDown,
+                        width: 8,
+                        height: 4,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textSubtitle2,
+                      ),
+                    ],
                   ),
-                )
-              ],
-            ),
-          if (coin == Coin.firo)
-            const SizedBox(
-              height: 20,
-            ),
-          Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            children: [
-              Text(
-                "Amount",
-                style: STextStyles.smallMed12(context),
-                textAlign: TextAlign.left,
-              ),
-              BlueTextButton(
-                text: "Send all ${coin.ticker}",
-                onTap: () async {
-                  if (coin == Coin.firo || coin == Coin.firoTestNet) {
-                    final firoWallet = ref.read(provider).wallet as FiroWallet;
-                    if (ref
-                            .read(publicPrivateBalanceStateProvider.state)
-                            .state ==
-                        "Private") {
-                      cryptoAmountController.text =
-                          (await firoWallet.availablePrivateBalance())
-                              .toStringAsFixed(Constants.decimalPlaces);
-                    } else {
-                      cryptoAmountController.text =
-                          (await firoWallet.availablePublicBalance())
-                              .toStringAsFixed(Constants.decimalPlaces);
-                    }
-                  } else {
-                    cryptoAmountController.text =
-                        (await ref.read(provider).availableBalance)
-                            .toStringAsFixed(Constants.decimalPlaces);
-                  }
-                },
-              ),
+                ),
+              )
             ],
           ),
+        if (coin == Coin.firo)
+          const SizedBox(
+            height: 20,
+          ),
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: [
+            Text(
+              "Amount",
+              style: STextStyles.smallMed12(context),
+              textAlign: TextAlign.left,
+            ),
+            BlueTextButton(
+              text: "Send all ${coin.ticker}",
+              onTap: () async {
+                if (coin == Coin.firo || coin == Coin.firoTestNet) {
+                  final firoWallet = ref.read(provider).wallet as FiroWallet;
+                  if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+                      "Private") {
+                    cryptoAmountController.text =
+                        (await firoWallet.availablePrivateBalance())
+                            .toStringAsFixed(Constants.decimalPlaces);
+                  } else {
+                    cryptoAmountController.text =
+                        (await firoWallet.availablePublicBalance())
+                            .toStringAsFixed(Constants.decimalPlaces);
+                  }
+                } else {
+                  cryptoAmountController.text =
+                      (await ref.read(provider).availableBalance)
+                          .toStringAsFixed(Constants.decimalPlaces);
+                }
+              },
+            ),
+          ],
+        ),
+        const SizedBox(
+          height: 10,
+        ),
+        TextField(
+          autocorrect: Util.isDesktop ? false : true,
+          enableSuggestions: Util.isDesktop ? false : true,
+          style: STextStyles.smallMed14(context).copyWith(
+            color: Theme.of(context).extension<StackColors>()!.textDark,
+          ),
+          key: const Key("amountInputFieldCryptoTextFieldKey"),
+          controller: cryptoAmountController,
+          focusNode: _cryptoFocus,
+          keyboardType: const TextInputType.numberWithOptions(
+            signed: false,
+            decimal: true,
+          ),
+          textAlign: TextAlign.right,
+          inputFormatters: [
+            // regex to validate a crypto amount with 8 decimal places
+            TextInputFormatter.withFunction((oldValue, newValue) =>
+                RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
+                        .hasMatch(newValue.text)
+                    ? newValue
+                    : oldValue),
+          ],
+          decoration: InputDecoration(
+            contentPadding: const EdgeInsets.only(
+              top: 12,
+              right: 12,
+            ),
+            hintText: "0",
+            hintStyle: STextStyles.fieldLabel(context).copyWith(
+              fontSize: 14,
+            ),
+            prefixIcon: FittedBox(
+              fit: BoxFit.scaleDown,
+              child: Padding(
+                padding: const EdgeInsets.all(12),
+                child: Text(
+                  coin.ticker,
+                  style: STextStyles.smallMed14(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark),
+                ),
+              ),
+            ),
+          ),
+        ),
+        if (Prefs.instance.externalCalls)
           const SizedBox(
             height: 10,
           ),
+        if (Prefs.instance.externalCalls)
           TextField(
             autocorrect: Util.isDesktop ? false : true,
             enableSuggestions: Util.isDesktop ? false : true,
             style: STextStyles.smallMed14(context).copyWith(
               color: Theme.of(context).extension<StackColors>()!.textDark,
             ),
-            key: const Key("amountInputFieldCryptoTextFieldKey"),
-            controller: cryptoAmountController,
-            focusNode: _cryptoFocus,
+            key: const Key("amountInputFieldFiatTextFieldKey"),
+            controller: baseAmountController,
+            focusNode: _baseFocus,
             keyboardType: const TextInputType.numberWithOptions(
               signed: false,
               decimal: true,
             ),
             textAlign: TextAlign.right,
             inputFormatters: [
-              // regex to validate a crypto amount with 8 decimal places
+              // regex to validate a fiat amount with 2 decimal places
               TextInputFormatter.withFunction((oldValue, newValue) =>
-                  RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
+                  RegExp(r'^([0-9]*[,.]?[0-9]{0,2}|[,.][0-9]{0,2})$')
                           .hasMatch(newValue.text)
                       ? newValue
                       : oldValue),
             ],
+            onChanged: (baseAmountString) {
+              if (baseAmountString.isNotEmpty &&
+                  baseAmountString != "." &&
+                  baseAmountString != ",") {
+                final baseAmount = baseAmountString.contains(",")
+                    ? Decimal.parse(baseAmountString.replaceFirst(",", "."))
+                    : Decimal.parse(baseAmountString);
+
+                var _price = ref
+                    .read(priceAnd24hChangeNotifierProvider)
+                    .getPrice(coin)
+                    .item1;
+
+                if (_price == Decimal.zero) {
+                  _amountToSend = Decimal.zero;
+                } else {
+                  _amountToSend = baseAmount <= Decimal.zero
+                      ? Decimal.zero
+                      : (baseAmount / _price).toDecimal(
+                          scaleOnInfinitePrecision: Constants.decimalPlaces);
+                }
+                if (_cachedAmountToSend != null &&
+                    _cachedAmountToSend == _amountToSend) {
+                  return;
+                }
+                _cachedAmountToSend = _amountToSend;
+                Logging.instance.log(
+                    "it changed $_amountToSend $_cachedAmountToSend",
+                    level: LogLevel.Info);
+
+                final amountString = Format.localizedStringAsFixed(
+                  value: _amountToSend!,
+                  locale: ref.read(localeServiceChangeNotifierProvider).locale,
+                  decimalPlaces: Constants.decimalPlaces,
+                );
+
+                _cryptoAmountChangeLock = true;
+                cryptoAmountController.text = amountString;
+                _cryptoAmountChangeLock = false;
+              } else {
+                _amountToSend = Decimal.zero;
+                _cryptoAmountChangeLock = true;
+                cryptoAmountController.text = "";
+                _cryptoAmountChangeLock = false;
+              }
+              // setState(() {
+              //   _calculateFeesFuture = calculateFees(
+              //       Format.decimalAmountToSatoshis(
+              //           _amountToSend!));
+              // });
+              _updatePreviewButtonState(_address, _amountToSend);
+            },
             decoration: InputDecoration(
               contentPadding: const EdgeInsets.only(
                 top: 12,
@@ -751,7 +850,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                 child: Padding(
                   padding: const EdgeInsets.all(12),
                   child: Text(
-                    coin.ticker,
+                    ref.watch(prefsChangeNotifierProvider
+                        .select((value) => value.currency)),
                     style: STextStyles.smallMed14(context).copyWith(
                         color: Theme.of(context)
                             .extension<StackColors>()!
@@ -761,412 +861,304 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
               ),
             ),
           ),
-          if (Prefs.instance.externalCalls)
-            const SizedBox(
-              height: 10,
-            ),
-          if (Prefs.instance.externalCalls)
-            TextField(
-              autocorrect: Util.isDesktop ? false : true,
-              enableSuggestions: Util.isDesktop ? false : true,
-              style: STextStyles.smallMed14(context).copyWith(
-                color: Theme.of(context).extension<StackColors>()!.textDark,
-              ),
-              key: const Key("amountInputFieldFiatTextFieldKey"),
-              controller: baseAmountController,
-              focusNode: _baseFocus,
-              keyboardType: const TextInputType.numberWithOptions(
-                signed: false,
-                decimal: true,
-              ),
-              textAlign: TextAlign.right,
-              inputFormatters: [
-                // regex to validate a fiat amount with 2 decimal places
-                TextInputFormatter.withFunction((oldValue, newValue) =>
-                    RegExp(r'^([0-9]*[,.]?[0-9]{0,2}|[,.][0-9]{0,2})$')
-                            .hasMatch(newValue.text)
-                        ? newValue
-                        : oldValue),
-              ],
-              onChanged: (baseAmountString) {
-                if (baseAmountString.isNotEmpty &&
-                    baseAmountString != "." &&
-                    baseAmountString != ",") {
-                  final baseAmount = baseAmountString.contains(",")
-                      ? Decimal.parse(baseAmountString.replaceFirst(",", "."))
-                      : Decimal.parse(baseAmountString);
-
-                  var _price = ref
-                      .read(priceAnd24hChangeNotifierProvider)
-                      .getPrice(coin)
-                      .item1;
-
-                  if (_price == Decimal.zero) {
-                    _amountToSend = Decimal.zero;
-                  } else {
-                    _amountToSend = baseAmount <= Decimal.zero
-                        ? Decimal.zero
-                        : (baseAmount / _price).toDecimal(
-                            scaleOnInfinitePrecision: Constants.decimalPlaces);
-                  }
-                  if (_cachedAmountToSend != null &&
-                      _cachedAmountToSend == _amountToSend) {
-                    return;
-                  }
-                  _cachedAmountToSend = _amountToSend;
-                  Logging.instance.log(
-                      "it changed $_amountToSend $_cachedAmountToSend",
-                      level: LogLevel.Info);
-
-                  final amountString = Format.localizedStringAsFixed(
-                    value: _amountToSend!,
-                    locale:
-                        ref.read(localeServiceChangeNotifierProvider).locale,
-                    decimalPlaces: Constants.decimalPlaces,
-                  );
-
-                  _cryptoAmountChangeLock = true;
-                  cryptoAmountController.text = amountString;
-                  _cryptoAmountChangeLock = false;
-                } else {
-                  _amountToSend = Decimal.zero;
-                  _cryptoAmountChangeLock = true;
-                  cryptoAmountController.text = "";
-                  _cryptoAmountChangeLock = false;
-                }
-                // setState(() {
-                //   _calculateFeesFuture = calculateFees(
-                //       Format.decimalAmountToSatoshis(
-                //           _amountToSend!));
-                // });
-                _updatePreviewButtonState(_address, _amountToSend);
-              },
-              decoration: InputDecoration(
-                contentPadding: const EdgeInsets.only(
-                  top: 12,
-                  right: 12,
-                ),
-                hintText: "0",
-                hintStyle: STextStyles.fieldLabel(context).copyWith(
-                  fontSize: 14,
-                ),
-                prefixIcon: FittedBox(
-                  fit: BoxFit.scaleDown,
-                  child: Padding(
-                    padding: const EdgeInsets.all(12),
-                    child: Text(
-                      ref.watch(prefsChangeNotifierProvider
-                          .select((value) => value.currency)),
-                      style: STextStyles.smallMed14(context).copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorDark),
-                    ),
-                  ),
-                ),
-              ),
-            ),
-          const SizedBox(
-            height: 20,
+        const SizedBox(
+          height: 20,
+        ),
+        Text(
+          "Send to",
+          style: STextStyles.smallMed12(context),
+          textAlign: TextAlign.left,
+        ),
+        const SizedBox(
+          height: 10,
+        ),
+        ClipRRect(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
           ),
-          Text(
-            "Send to",
-            style: STextStyles.smallMed12(context),
-            textAlign: TextAlign.left,
-          ),
-          const SizedBox(
-            height: 10,
-          ),
-          ClipRRect(
-            borderRadius: BorderRadius.circular(
-              Constants.size.circularBorderRadius,
+          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,
             ),
-            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,
-              ),
-              onChanged: (newValue) {
-                _address = newValue;
-                _updatePreviewButtonState(_address, _amountToSend);
+            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: coin,
-                              );
-                            },
-                            child: const AddressBookIcon(),
-                          ),
-                        if (sendToController.text.isEmpty)
-                          TextFieldIconButton(
-                            key: const Key("sendViewScanQrButtonKey"),
-                            onTap: () async {
-                              try {
-                                if (FocusScope.of(context).hasFocus) {
-                                  FocusScope.of(context).unfocus();
-                                  await Future<void>.delayed(
-                                      const Duration(milliseconds: 75));
-                                }
-
-                                final qrResult = await scanner.scan();
-
-                                Logging.instance.log(
-                                    "qrResult content: ${qrResult.rawContent}",
-                                    level: LogLevel.Info);
-
-                                final results =
-                                    AddressUtils.parseUri(qrResult.rawContent);
-
-                                Logging.instance.log(
-                                    "qrResult parsed: $results",
-                                    level: LogLevel.Info);
-
-                                if (results.isNotEmpty &&
-                                    results["scheme"] == coin.uriScheme) {
-                                  // auto fill address
-                                  _address = results["address"] ?? "";
-                                  sendToController.text = _address!;
-
-                                  // autofill notes field
-                                  if (results["message"] != null) {
-                                    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.decimalPlaces,
-                                    );
-                                    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) {
-                                // 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(),
-                          )
-                      ],
-                    ),
-                  ),
-                ),
-              ),
-            ),
-          ),
-          Builder(
-            builder: (_) {
-              final error = _updateInvalidAddressText(
-                _address ?? "",
-                ref.read(walletsChangeNotifierProvider).getManager(walletId),
-              );
-
-              if (error == null || error.isEmpty) {
-                return Container();
-              } else {
-                return Align(
-                  alignment: Alignment.topLeft,
-                  child: Padding(
-                    padding: const EdgeInsets.only(
-                      left: 12.0,
-                      top: 4.0,
-                    ),
-                    child: Text(
-                      error,
-                      textAlign: TextAlign.left,
-                      style: STextStyles.label(context).copyWith(
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textError,
-                      ),
-                    ),
-                  ),
-                );
-              }
+              setState(() {
+                _addressToggleFlag = newValue.isNotEmpty;
+              });
             },
-          ),
-          const SizedBox(
-            height: 20,
-          ),
-          Text(
-            "Note (optional)",
-            style: STextStyles.smallMed12(context),
-            textAlign: TextAlign.left,
-          ),
-          const SizedBox(
-            height: 10,
-          ),
-          ClipRRect(
-            borderRadius: BorderRadius.circular(
-              Constants.size.circularBorderRadius,
-            ),
-            child: TextField(
-              autocorrect: Util.isDesktop ? false : true,
-              enableSuggestions: Util.isDesktop ? false : true,
-              controller: noteController,
-              focusNode: _noteFocusNode,
-              style: STextStyles.field(context),
-              onChanged: (_) => setState(() {}),
-              decoration: standardInputDecoration(
-                "Type something...",
-                _noteFocusNode,
-                context,
-              ).copyWith(
-                suffixIcon: noteController.text.isNotEmpty
-                    ? Padding(
-                        padding: const EdgeInsets.only(right: 0),
-                        child: UnconstrainedBox(
-                          child: Row(
-                            children: [
-                              TextFieldIconButton(
-                                child: const XIcon(),
-                                onTap: () async {
+            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(() {
-                                    noteController.text = "";
+                                    _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: coin,
+                            );
+                          },
+                          child: const AddressBookIcon(),
                         ),
-                      )
-                    : null,
+                      if (sendToController.text.isEmpty)
+                        TextFieldIconButton(
+                          key: const Key("sendViewScanQrButtonKey"),
+                          onTap: () async {
+                            try {
+                              if (FocusScope.of(context).hasFocus) {
+                                FocusScope.of(context).unfocus();
+                                await Future<void>.delayed(
+                                    const Duration(milliseconds: 75));
+                              }
+
+                              final qrResult = await scanner.scan();
+
+                              Logging.instance.log(
+                                  "qrResult content: ${qrResult.rawContent}",
+                                  level: LogLevel.Info);
+
+                              final results =
+                                  AddressUtils.parseUri(qrResult.rawContent);
+
+                              Logging.instance.log("qrResult parsed: $results",
+                                  level: LogLevel.Info);
+
+                              if (results.isNotEmpty &&
+                                  results["scheme"] == coin.uriScheme) {
+                                // auto fill address
+                                _address = results["address"] ?? "";
+                                sendToController.text = _address!;
+
+                                // autofill notes field
+                                if (results["message"] != null) {
+                                  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.decimalPlaces,
+                                  );
+                                  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) {
+                              // 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(),
+                        )
+                    ],
+                  ),
+                ),
               ),
             ),
           ),
-          const SizedBox(
-            height: 36,
+        ),
+        Builder(
+          builder: (_) {
+            final error = _updateInvalidAddressText(
+              _address ?? "",
+              ref.read(walletsChangeNotifierProvider).getManager(walletId),
+            );
+
+            if (error == null || error.isEmpty) {
+              return Container();
+            } else {
+              return Align(
+                alignment: Alignment.topLeft,
+                child: Padding(
+                  padding: const EdgeInsets.only(
+                    left: 12.0,
+                    top: 4.0,
+                  ),
+                  child: Text(
+                    error,
+                    textAlign: TextAlign.left,
+                    style: STextStyles.label(context).copyWith(
+                      color:
+                          Theme.of(context).extension<StackColors>()!.textError,
+                    ),
+                  ),
+                ),
+              );
+            }
+          },
+        ),
+        const SizedBox(
+          height: 20,
+        ),
+        Text(
+          "Note (optional)",
+          style: STextStyles.smallMed12(context),
+          textAlign: TextAlign.left,
+        ),
+        const SizedBox(
+          height: 10,
+        ),
+        ClipRRect(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
           ),
-          PrimaryButton(
-            height: 56,
-            label: "Preview send",
-            enabled: ref.watch(previewTxButtonStateProvider.state).state,
-            onPressed: ref.watch(previewTxButtonStateProvider.state).state
-                ? previewSend
-                : null,
-          )
-        ],
-      ),
+          child: TextField(
+            autocorrect: Util.isDesktop ? false : true,
+            enableSuggestions: Util.isDesktop ? false : true,
+            controller: noteController,
+            focusNode: _noteFocusNode,
+            style: STextStyles.field(context),
+            onChanged: (_) => setState(() {}),
+            decoration: standardInputDecoration(
+              "Type something...",
+              _noteFocusNode,
+              context,
+            ).copyWith(
+              suffixIcon: noteController.text.isNotEmpty
+                  ? Padding(
+                      padding: const EdgeInsets.only(right: 0),
+                      child: UnconstrainedBox(
+                        child: Row(
+                          children: [
+                            TextFieldIconButton(
+                              child: const XIcon(),
+                              onTap: () async {
+                                setState(() {
+                                  noteController.text = "";
+                                });
+                              },
+                            ),
+                          ],
+                        ),
+                      ),
+                    )
+                  : null,
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 36,
+        ),
+        PrimaryButton(
+          height: 56,
+          label: "Preview send",
+          enabled: ref.watch(previewTxButtonStateProvider.state).state,
+          onPressed: ref.watch(previewTxButtonStateProvider.state).state
+              ? previewSend
+              : null,
+        )
+      ],
     );
   }
 }

From 5bec4962e4490efbc456f96fc5a0dfb9011a4252 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 26 Oct 2022 16:27:45 -0600
Subject: [PATCH 038/426] WIP: desktop wallet balance display

---
 .../wallet_view/desktop_wallet_summary.dart   | 283 ++++++++++++++++++
 .../wallet_view/desktop_wallet_view.dart      |  72 +++--
 2 files changed, 325 insertions(+), 30 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart
new file mode 100644
index 000000000..fe2cfa7b2
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart
@@ -0,0 +1,283 @@
+import 'package:decimal/decimal.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart';
+import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_refresh_button.dart';
+import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
+import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
+import 'package:stackwallet/services/coins/manager.dart';
+import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
+import 'package:stackwallet/utilities/format.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/animated_text.dart';
+
+class DesktopWalletSummary extends StatefulWidget {
+  const DesktopWalletSummary({
+    Key? key,
+    required this.walletId,
+    required this.managerProvider,
+    required this.initialSyncStatus,
+  }) : super(key: key);
+
+  final String walletId;
+  final ChangeNotifierProvider<Manager> managerProvider;
+  final WalletSyncStatus initialSyncStatus;
+
+  @override
+  State<DesktopWalletSummary> createState() => _WDesktopWalletSummaryState();
+}
+
+class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
+  late final String walletId;
+  late final ChangeNotifierProvider<Manager> managerProvider;
+
+  void showSheet() {
+    showModalBottomSheet<dynamic>(
+      backgroundColor: Colors.transparent,
+      context: context,
+      shape: const RoundedRectangleBorder(
+        borderRadius: BorderRadius.vertical(
+          top: Radius.circular(20),
+        ),
+      ),
+      builder: (_) => WalletBalanceToggleSheet(walletId: walletId),
+    );
+  }
+
+  Decimal? _balanceTotalCached;
+  Decimal? _balanceCached;
+
+  @override
+  void initState() {
+    walletId = widget.walletId;
+    managerProvider = widget.managerProvider;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return Row(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Column(
+          children: [
+            Consumer(
+              builder: (_, ref, __) {
+                final Coin coin =
+                    ref.watch(managerProvider.select((value) => value.coin));
+                final externalCalls = ref.watch(prefsChangeNotifierProvider
+                    .select((value) => value.externalCalls));
+
+                Future<Decimal>? totalBalanceFuture;
+                Future<Decimal>? availableBalanceFuture;
+                if (coin == Coin.firo || coin == Coin.firoTestNet) {
+                  final firoWallet =
+                      ref.watch(managerProvider.select((value) => value.wallet))
+                          as FiroWallet;
+                  totalBalanceFuture = firoWallet.availablePublicBalance();
+                  availableBalanceFuture = firoWallet.availablePrivateBalance();
+                } else {
+                  totalBalanceFuture = ref.watch(
+                      managerProvider.select((value) => value.totalBalance));
+
+                  availableBalanceFuture = ref.watch(managerProvider
+                      .select((value) => value.availableBalance));
+                }
+
+                final locale = ref.watch(localeServiceChangeNotifierProvider
+                    .select((value) => value.locale));
+
+                final baseCurrency = ref.watch(prefsChangeNotifierProvider
+                    .select((value) => value.currency));
+
+                final priceTuple = ref.watch(priceAnd24hChangeNotifierProvider
+                    .select((value) => value.getPrice(coin)));
+
+                final _showAvailable =
+                    ref.watch(walletBalanceToggleStateProvider.state).state ==
+                        WalletBalanceToggleState.available;
+
+                return FutureBuilder(
+                  future: _showAvailable
+                      ? availableBalanceFuture
+                      : totalBalanceFuture,
+                  builder: (fbContext, AsyncSnapshot<Decimal> snapshot) {
+                    if (snapshot.connectionState == ConnectionState.done &&
+                        snapshot.hasData &&
+                        snapshot.data != null) {
+                      if (_showAvailable) {
+                        _balanceCached = snapshot.data!;
+                      } else {
+                        _balanceTotalCached = snapshot.data!;
+                      }
+                    }
+                    Decimal? balanceToShow =
+                        _showAvailable ? _balanceCached : _balanceTotalCached;
+
+                    if (balanceToShow != null) {
+                      return Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          GestureDetector(
+                            onTap: showSheet,
+                            child: Row(
+                              children: [
+                                if (coin == Coin.firo ||
+                                    coin == Coin.firoTestNet)
+                                  Text(
+                                    "${_showAvailable ? "Private" : "Public"} Balance",
+                                    style: STextStyles.subtitle500(context)
+                                        .copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textFavoriteCard,
+                                    ),
+                                  ),
+                                if (coin != Coin.firo &&
+                                    coin != Coin.firoTestNet)
+                                  Text(
+                                    "${_showAvailable ? "Available" : "Full"} Balance",
+                                    style: STextStyles.subtitle500(context)
+                                        .copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textFavoriteCard,
+                                    ),
+                                  ),
+                                const SizedBox(
+                                  width: 4,
+                                ),
+                                SvgPicture.asset(
+                                  Assets.svg.chevronDown,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textFavoriteCard,
+                                  width: 8,
+                                  height: 4,
+                                ),
+                              ],
+                            ),
+                          ),
+                          FittedBox(
+                            fit: BoxFit.scaleDown,
+                            child: Text(
+                              "${Format.localizedStringAsFixed(
+                                value: balanceToShow,
+                                locale: locale,
+                                decimalPlaces: 8,
+                              )} ${coin.ticker}",
+                              style: STextStyles.desktopH3(context),
+                            ),
+                          ),
+                          if (externalCalls)
+                            Text(
+                              "${Format.localizedStringAsFixed(
+                                value: priceTuple.item1 * balanceToShow,
+                                locale: locale,
+                                decimalPlaces: 2,
+                              )} $baseCurrency",
+                              style: STextStyles.desktopTextExtraSmall(context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textSubtitle1,
+                              ),
+                            ),
+                        ],
+                      );
+                    } else {
+                      return Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          GestureDetector(
+                            onTap: showSheet,
+                            child: Row(
+                              children: [
+                                if (coin == Coin.firo ||
+                                    coin == Coin.firoTestNet)
+                                  Text(
+                                    "${_showAvailable ? "Private" : "Public"} Balance",
+                                    style: STextStyles.subtitle500(context)
+                                        .copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textFavoriteCard,
+                                    ),
+                                  ),
+                                if (coin != Coin.firo &&
+                                    coin != Coin.firoTestNet)
+                                  Text(
+                                    "${_showAvailable ? "Available" : "Full"} Balance",
+                                    style: STextStyles.subtitle500(context)
+                                        .copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textFavoriteCard,
+                                    ),
+                                  ),
+                                const SizedBox(
+                                  width: 4,
+                                ),
+                                SvgPicture.asset(
+                                  Assets.svg.chevronDown,
+                                  width: 8,
+                                  height: 4,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textFavoriteCard,
+                                ),
+                              ],
+                            ),
+                          ),
+                          AnimatedText(
+                            stringsToLoopThrough: const [
+                              "Loading balance   ",
+                              "Loading balance.  ",
+                              "Loading balance.. ",
+                              "Loading balance..."
+                            ],
+                            style: STextStyles.desktopH3(context).copyWith(
+                              fontSize: 24,
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textFavoriteCard,
+                            ),
+                          ),
+                          AnimatedText(
+                            stringsToLoopThrough: const [
+                              "Loading balance   ",
+                              "Loading balance.  ",
+                              "Loading balance.. ",
+                              "Loading balance..."
+                            ],
+                            style: STextStyles.desktopTextExtraSmall(context)
+                                .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textSubtitle1,
+                            ),
+                          ),
+                        ],
+                      );
+                    }
+                  },
+                );
+              },
+            ),
+          ],
+        ),
+        WalletRefreshButton(
+          walletId: walletId,
+          initialSyncStatus: widget.initialSyncStatus,
+        )
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 4c2b510de..7f13c7fd8 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -1,9 +1,11 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -48,6 +50,8 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
     final manager = ref.watch(walletsChangeNotifierProvider
         .select((value) => value.getManager(walletId)));
     final coin = manager.coin;
+    final managerProvider = ref.watch(walletsChangeNotifierProvider
+        .select((value) => value.getManagerProvider(walletId)));
 
     return DesktopScaffold(
       appBar: DesktopAppBar(
@@ -120,37 +124,45 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                   const SizedBox(
                     width: 10,
                   ),
-                  Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Row(
-                        children: [
-                          Text(
-                            "TODO: balance",
-                            style: STextStyles.desktopH3(context),
-                          ),
-                          const SizedBox(
-                            width: 8,
-                          ),
-                          Container(
-                            color: Colors.red,
-                            width: 20,
-                            height: 20,
-                          ),
-                        ],
-                      ),
-                      Text(
-                        "todo: fiat balance",
-                        style:
-                            STextStyles.desktopTextExtraSmall(context).copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .textSubtitle1,
-                        ),
-                      )
-                    ],
+                  DesktopWalletSummary(
+                    walletId: walletId,
+                    managerProvider: managerProvider,
+                    initialSyncStatus: ref.watch(managerProvider
+                            .select((value) => value.isRefreshing))
+                        ? WalletSyncStatus.syncing
+                        : WalletSyncStatus.synced,
                   ),
+                  // Column(
+                  //   crossAxisAlignment: CrossAxisAlignment.start,
+                  //   mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  //   children: [
+                  //     Row(
+                  //       children: [
+                  //         Text(
+                  //           "TODO: balance",
+                  //           style: STextStyles.desktopH3(context),
+                  //         ),
+                  //         const SizedBox(
+                  //           width: 8,
+                  //         ),
+                  //         Container(
+                  //           color: Colors.red,
+                  //           width: 20,
+                  //           height: 20,
+                  //         ),
+                  //       ],
+                  //     ),
+                  //     Text(
+                  //       "todo: fiat balance",
+                  //       style:
+                  //           STextStyles.desktopTextExtraSmall(context).copyWith(
+                  //         color: Theme.of(context)
+                  //             .extension<StackColors>()!
+                  //             .textSubtitle1,
+                  //       ),
+                  //     )
+                  //   ],
+                  // ),
                   const Spacer(),
                   SecondaryButton(
                     width: 180,

From fa48ab30f531d966a6a6bbcf24fe5b852807c1eb Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 26 Oct 2022 16:29:51 -0600
Subject: [PATCH 039/426] working on theme toggles

---
 .../settings_menu/appearance_settings.dart    | 244 ++++++++++++++++++
 1 file changed, 244 insertions(+)

diff --git a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
index c0b2c0ca5..d524453e2 100644
--- a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
@@ -4,8 +4,13 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
+import '../../../providers/global/prefs_provider.dart';
+import '../../../utilities/constants.dart';
+import '../../../widgets/custom_buttons/draggable_switch_button.dart';
+
 class AppearanceOptionSettings extends ConsumerStatefulWidget {
   const AppearanceOptionSettings({Key? key}) : super(key: key);
 
@@ -61,6 +66,74 @@ class _AppearanceOptionSettings
                     ),
                   ],
                 ),
+                const Padding(
+                  padding: EdgeInsets.all(10.0),
+                  child: Divider(
+                    thickness: 0.5,
+                  ),
+                ),
+                Padding(
+                  padding: const EdgeInsets.all(10.0),
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Text(
+                        "Display favorite wallets",
+                        style: STextStyles.desktopTextExtraSmall(context)
+                            .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark),
+                        textAlign: TextAlign.left,
+                      ),
+                      SizedBox(
+                        height: 20,
+                        width: 40,
+                        child: DraggableSwitchButton(
+                          isOn: ref.watch(
+                            prefsChangeNotifierProvider
+                                .select((value) => value.showFavoriteWallets),
+                          ),
+                          onValueChanged: (newValue) {
+                            ref
+                                .read(prefsChangeNotifierProvider)
+                                .showFavoriteWallets = newValue;
+                          },
+                        ),
+                      )
+                    ],
+                  ),
+                ),
+                const Padding(
+                  padding: EdgeInsets.all(10.0),
+                  child: Divider(
+                    thickness: 0.5,
+                  ),
+                ),
+                Padding(
+                  padding: const EdgeInsets.all(10.0),
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Text(
+                        "Choose theme",
+                        style: STextStyles.desktopTextExtraSmall(context)
+                            .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark),
+                        textAlign: TextAlign.left,
+                      ),
+                    ],
+                  ),
+                ),
+                const Padding(
+                  padding: EdgeInsets.only(
+                    left: 10,
+                    right: 10,
+                  ),
+                  child: ThemeToggle(),
+                ),
               ],
             ),
           ),
@@ -69,3 +142,174 @@ class _AppearanceOptionSettings
     );
   }
 }
+
+class ThemeToggle extends StatefulWidget {
+  const ThemeToggle({
+    Key? key,
+  }) : super(key: key);
+
+  // final bool externalCallsEnabled;
+  // final void Function(bool)? onChanged;
+
+  @override
+  State<StatefulWidget> createState() => _ThemeToggle();
+}
+
+class _ThemeToggle extends State<ThemeToggle> {
+  // late bool externalCallsEnabled;
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      // mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+      children: [
+        Padding(
+          padding: const EdgeInsets.all(8.0),
+          child: RawMaterialButton(
+            elevation: 0,
+            hoverColor: Colors.transparent,
+            shape: RoundedRectangleBorder(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius * 2,
+              ),
+            ),
+            onPressed: () {}, //onPressed
+            child: Stack(
+              children: [
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.only(
+                        left: 24,
+                      ),
+                      child: SvgPicture.asset(
+                        Assets.svg.themeLight,
+                      ),
+                    ),
+                    Padding(
+                      padding: const EdgeInsets.only(
+                        left: 50,
+                        top: 12,
+                      ),
+                      child: Text(
+                        "Light",
+                        style:
+                            STextStyles.desktopTextExtraSmall(context).copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark,
+                        ),
+                      ),
+                    )
+                  ],
+                ),
+                // if (externalCallsEnabled)
+                Positioned(
+                  bottom: 0,
+                  left: 6,
+                  child: SvgPicture.asset(
+                    Assets.svg.checkCircle,
+                    width: 20,
+                    height: 20,
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .infoItemIcons,
+                  ),
+                ),
+                // if (!externalCallsEnabled)
+                //   Positioned(
+                //     top: 4,
+                //     right: 4,
+                //     child: Container(
+                //       width: 20,
+                //       height: 20,
+                //       decoration: BoxDecoration(
+                //         borderRadius: BorderRadius.circular(1000),
+                //         color: Theme.of(context)
+                //             .extension<StackColors>()!
+                //             .textFieldDefaultBG,
+                //       ),
+                //     ),
+                //   ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          width: 1,
+        ),
+        Expanded(
+          child: Padding(
+            padding: const EdgeInsets.all(8.0),
+            child: RawMaterialButton(
+              elevation: 0,
+              hoverColor: Colors.transparent,
+              shape: RoundedRectangleBorder(
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius * 2,
+                ),
+              ),
+              onPressed: () {}, //onPressed
+              child: Stack(
+                children: [
+                  Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      SvgPicture.asset(
+                        Assets.svg.themeDark,
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.only(
+                          left: 50,
+                          top: 12,
+                        ),
+                        child: Text(
+                          "Dark",
+                          style: STextStyles.desktopTextExtraSmall(context)
+                              .copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark,
+                          ),
+                        ),
+                      ),
+                    ],
+                  ),
+                  // if (externalCallsEnabled)
+                  Positioned(
+                    bottom: 0,
+                    left: 0,
+                    child: SvgPicture.asset(
+                      Assets.svg.checkCircle,
+                      width: 20,
+                      height: 20,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .infoItemIcons,
+                    ),
+                  ),
+                  // if (!externalCallsEnabled)
+                  //   Positioned(
+                  //     top: 4,
+                  //     right: 4,
+                  //     child: Container(
+                  //       width: 20,
+                  //       height: 20,
+                  //       decoration: BoxDecoration(
+                  //         borderRadius: BorderRadius.circular(1000),
+                  //         color: Theme.of(context)
+                  //             .extension<StackColors>()!
+                  //             .textFieldDefaultBG,
+                  //       ),
+                  //     ),
+                  //   ),
+                ],
+              ),
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}

From df7871fa6ba06261957dc88ba393994d35993290 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 26 Oct 2022 16:49:38 -0600
Subject: [PATCH 040/426] WIP: keys + sync status

---
 .../wallet_view/desktop_wallet_view.dart      | 51 +++++++++++++++++--
 1 file changed, 46 insertions(+), 5 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 7f13c7fd8..f86eba750 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -98,7 +98,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
           children: const [
             NetworkInfoButton(),
             SizedBox(
-              width: 12,
+              width: 32,
             ),
             WalletKeysButton(),
             SizedBox(
@@ -467,8 +467,28 @@ class NetworkInfoButton extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Container(
-      child: Text("todo: sync status"),
+    return GestureDetector(
+      child: Container(
+        color: Colors.transparent,
+        child: Row(
+          children: [
+            SvgPicture.asset(
+              Assets.svg.network,
+              width: 24,
+              height: 24,
+              color:
+                  Theme.of(context).extension<StackColors>()!.accentColorGreen,
+            ),
+            const SizedBox(
+              width: 6,
+            ),
+            Text(
+              "Synchronised",
+              style: STextStyles.desktopMenuItemSelected(context),
+            )
+          ],
+        ),
+      ),
     );
   }
 }
@@ -478,8 +498,29 @@ class WalletKeysButton extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Container(
-      child: Text("todo: wallet keys"),
+    return GestureDetector(
+      child: Container(
+        color: Colors.transparent,
+        child: Row(
+          children: [
+            SvgPicture.asset(
+              Assets.svg.key,
+              width: 20,
+              height: 20,
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .buttonTextSecondary,
+            ),
+            const SizedBox(
+              width: 6,
+            ),
+            Text(
+              "Wallet keys",
+              style: STextStyles.desktopMenuItemSelected(context),
+            )
+          ],
+        ),
+      ),
     );
   }
 }

From a736c9a5032344a4f99533b254c74115397cb53c Mon Sep 17 00:00:00 2001
From: Marco <marco@cypherstack.com>
Date: Wed, 26 Oct 2022 18:26:40 -0600
Subject: [PATCH 041/426] fix price not showing

---
 lib/pages/stack_privacy_calls.dart | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index 2aa2a5c8a..7ca21c494 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
@@ -6,12 +8,17 @@ import 'package:stackwallet/pages_desktop_specific/create_password/create_passwo
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/prefs.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
+import '../hive/db.dart';
+import '../providers/global/price_provider.dart';
+import '../services/exchange/exchange_data_loading_service.dart';
+
 class StackPrivacyCalls extends ConsumerStatefulWidget {
   const StackPrivacyCalls({
     Key? key,
@@ -160,6 +167,21 @@ class _StackPrivacyCalls extends ConsumerState<StackPrivacyCalls> {
                         onPressed: () {
                           ref.read(prefsChangeNotifierProvider).externalCalls =
                               isEasy;
+
+                          DB.instance
+                              .put<dynamic>(
+                                  boxName: DB.boxNamePrefs,
+                                  key: "externalCalls",
+                                  value: isEasy)
+                              .then((_) {
+                            if (isEasy) {
+                              unawaited(
+                                  ExchangeDataLoadingService().loadAll(ref));
+                              ref
+                                  .read(priceAnd24hChangeNotifierProvider)
+                                  .start(true);
+                            }
+                          });
                           if (!widget.isSettings) {
                             if (isDesktop) {
                               Navigator.of(context).pushNamed(

From 89e301df45f8202962d7c67c0d5ea1642e13f172 Mon Sep 17 00:00:00 2001
From: Marco <marco@cypherstack.com>
Date: Wed, 26 Oct 2022 18:26:40 -0600
Subject: [PATCH 042/426] fix price not showing

(cherry picked from commit a736c9a5032344a4f99533b254c74115397cb53c)
---
 lib/pages/stack_privacy_calls.dart | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index 2aa2a5c8a..7ca21c494 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
@@ -6,12 +8,17 @@ import 'package:stackwallet/pages_desktop_specific/create_password/create_passwo
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/prefs.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
+import '../hive/db.dart';
+import '../providers/global/price_provider.dart';
+import '../services/exchange/exchange_data_loading_service.dart';
+
 class StackPrivacyCalls extends ConsumerStatefulWidget {
   const StackPrivacyCalls({
     Key? key,
@@ -160,6 +167,21 @@ class _StackPrivacyCalls extends ConsumerState<StackPrivacyCalls> {
                         onPressed: () {
                           ref.read(prefsChangeNotifierProvider).externalCalls =
                               isEasy;
+
+                          DB.instance
+                              .put<dynamic>(
+                                  boxName: DB.boxNamePrefs,
+                                  key: "externalCalls",
+                                  value: isEasy)
+                              .then((_) {
+                            if (isEasy) {
+                              unawaited(
+                                  ExchangeDataLoadingService().loadAll(ref));
+                              ref
+                                  .read(priceAnd24hChangeNotifierProvider)
+                                  .start(true);
+                            }
+                          });
                           if (!widget.isSettings) {
                             if (isDesktop) {
                               Navigator.of(context).pushNamed(

From 49c3c15a7d2eccff80c40f66ff736149f1dd951e Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 08:31:25 -0600
Subject: [PATCH 043/426] disable fee preview calculation for desktop send form

---
 .../wallet_view/send/desktop_send.dart        | 242 +++++++++---------
 pubspec.lock                                  |   2 +-
 2 files changed, 120 insertions(+), 124 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
index 1579b2367..0ffe3b962 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
@@ -7,6 +7,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.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';
+import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/firo_balance_selection_sheet.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart';
 import 'package:stackwallet/providers/providers.dart';
@@ -22,7 +24,6 @@ import 'package:stackwallet/utilities/barcode_scanner_interface.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/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
@@ -40,9 +41,6 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-import '../../../../../pages/send_view/confirm_transaction_view.dart';
-import '../../../../../pages/send_view/sub_widgets/building_transaction_dialog.dart';
-
 class DesktopSend extends ConsumerStatefulWidget {
   const DesktopSend({
     Key? key,
@@ -71,7 +69,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
   late TextEditingController cryptoAmountController;
   late TextEditingController baseAmountController;
   late TextEditingController noteController;
-  late TextEditingController feeController;
+  // late TextEditingController feeController;
 
   late final SendViewAutoFillData? _data;
 
@@ -92,8 +90,6 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
   bool _cryptoAmountChangeLock = false;
   late VoidCallback onCryptoAmountChanged;
 
-  Decimal? _cachedBalance;
-
   Future<void> previewSend() async {
     // wait for keyboard to disappear
     FocusScope.of(context).unfocus();
@@ -346,78 +342,78 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         (isValidAddress && amount != null && amount > Decimal.zero);
   }
 
-  late Future<String> _calculateFeesFuture;
+  // late Future<String> _calculateFeesFuture;
 
-  Map<int, String> cachedFees = {};
-  Map<int, String> cachedFiroPrivateFees = {};
-  Map<int, String> cachedFiroPublicFees = {};
+  // Map<int, String> cachedFees = {};
+  // Map<int, String> cachedFiroPrivateFees = {};
+  // Map<int, String> cachedFiroPublicFees = {};
 
-  Future<String> calculateFees(int amount) async {
-    if (amount <= 0) {
-      return "0";
-    }
-
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
-      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
-          "Private") {
-        if (cachedFiroPrivateFees[amount] != null) {
-          return cachedFiroPrivateFees[amount]!;
-        }
-      } else {
-        if (cachedFiroPublicFees[amount] != null) {
-          return cachedFiroPublicFees[amount]!;
-        }
-      }
-    } else if (cachedFees[amount] != null) {
-      return cachedFees[amount]!;
-    }
-
-    final manager =
-        ref.read(walletsChangeNotifierProvider).getManager(walletId);
-    final feeObject = await manager.fees;
-
-    late final int feeRate;
-
-    switch (ref.read(feeRateTypeStateProvider.state).state) {
-      case FeeRateType.fast:
-        feeRate = feeObject.fast;
-        break;
-      case FeeRateType.average:
-        feeRate = feeObject.medium;
-        break;
-      case FeeRateType.slow:
-        feeRate = feeObject.slow;
-        break;
-    }
-
-    int fee;
-
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
-      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
-          "Private") {
-        fee = await manager.estimateFeeFor(amount, feeRate);
-
-        cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee)
-            .toStringAsFixed(Constants.decimalPlaces);
-
-        return cachedFiroPrivateFees[amount]!;
-      } else {
-        fee = await (manager.wallet as FiroWallet)
-            .estimateFeeForPublic(amount, feeRate);
-
-        cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee)
-            .toStringAsFixed(Constants.decimalPlaces);
-
-        return cachedFiroPublicFees[amount]!;
-      }
-    } else {
-      fee = await manager.estimateFeeFor(amount, feeRate);
-      cachedFees[amount] =
-          Format.satoshisToAmount(fee).toStringAsFixed(Constants.decimalPlaces);
-
-      return cachedFees[amount]!;
-    }
-  }
+  // Future<String> calculateFees(int amount) async {
+  //   if (amount <= 0) {
+  //     return "0";
+  //   }
+  //
+  //   if (coin == Coin.firo || coin == Coin.firoTestNet) {
+  //     if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+  //         "Private") {
+  //       if (cachedFiroPrivateFees[amount] != null) {
+  //         return cachedFiroPrivateFees[amount]!;
+  //       }
+  //     } else {
+  //       if (cachedFiroPublicFees[amount] != null) {
+  //         return cachedFiroPublicFees[amount]!;
+  //       }
+  //     }
+  //   } else if (cachedFees[amount] != null) {
+  //     return cachedFees[amount]!;
+  //   }
+  //
+  //   final manager =
+  //       ref.read(walletsChangeNotifierProvider).getManager(walletId);
+  //   final feeObject = await manager.fees;
+  //
+  //   late final int feeRate;
+  //
+  //   switch (ref.read(feeRateTypeStateProvider.state).state) {
+  //     case FeeRateType.fast:
+  //       feeRate = feeObject.fast;
+  //       break;
+  //     case FeeRateType.average:
+  //       feeRate = feeObject.medium;
+  //       break;
+  //     case FeeRateType.slow:
+  //       feeRate = feeObject.slow;
+  //       break;
+  //   }
+  //
+  //   int fee;
+  //
+  //   if (coin == Coin.firo || coin == Coin.firoTestNet) {
+  //     if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+  //         "Private") {
+  //       fee = await manager.estimateFeeFor(amount, feeRate);
+  //
+  //       cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee)
+  //           .toStringAsFixed(Constants.decimalPlaces);
+  //
+  //       return cachedFiroPrivateFees[amount]!;
+  //     } else {
+  //       fee = await (manager.wallet as FiroWallet)
+  //           .estimateFeeForPublic(amount, feeRate);
+  //
+  //       cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee)
+  //           .toStringAsFixed(Constants.decimalPlaces);
+  //
+  //       return cachedFiroPublicFees[amount]!;
+  //     }
+  //   } else {
+  //     fee = await manager.estimateFeeFor(amount, feeRate);
+  //     cachedFees[amount] =
+  //         Format.satoshisToAmount(fee).toStringAsFixed(Constants.decimalPlaces);
+  //
+  //     return cachedFees[amount]!;
+  //   }
+  // }
 
   Future<String?> _firoBalanceFuture(
       ChangeNotifierProvider<Manager> provider, String locale) async {
@@ -443,7 +439,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
   void initState() {
     ref.refresh(feeSheetSessionCacheProvider);
 
-    _calculateFeesFuture = calculateFees(0);
+    // _calculateFeesFuture = calculateFees(0);
     _data = widget.autoFillData;
     walletId = widget.walletId;
     coin = ref.read(walletsChangeNotifierProvider).getManager(walletId).coin;
@@ -454,7 +450,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
     cryptoAmountController = TextEditingController();
     baseAmountController = TextEditingController();
     noteController = TextEditingController();
-    feeController = TextEditingController();
+    // feeController = TextEditingController();
 
     onCryptoAmountChanged = _cryptoAmountChanged;
     cryptoAmountController.addListener(onCryptoAmountChanged);
@@ -468,35 +464,35 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
       _addressToggleFlag = true;
     }
 
-    _cryptoFocus.addListener(() {
-      if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
-        if (_amountToSend == null) {
-          setState(() {
-            _calculateFeesFuture = calculateFees(0);
-          });
-        } else {
-          setState(() {
-            _calculateFeesFuture =
-                calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
-          });
-        }
-      }
-    });
-
-    _baseFocus.addListener(() {
-      if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
-        if (_amountToSend == null) {
-          setState(() {
-            _calculateFeesFuture = calculateFees(0);
-          });
-        } else {
-          setState(() {
-            _calculateFeesFuture =
-                calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
-          });
-        }
-      }
-    });
+    // _cryptoFocus.addListener(() {
+    //   if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
+    //     if (_amountToSend == null) {
+    //       setState(() {
+    //         _calculateFeesFuture = calculateFees(0);
+    //       });
+    //     } else {
+    //       setState(() {
+    //         _calculateFeesFuture =
+    //             calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
+    //       });
+    //     }
+    //   }
+    // });
+    //
+    // _baseFocus.addListener(() {
+    //   if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
+    //     if (_amountToSend == null) {
+    //       setState(() {
+    //         _calculateFeesFuture = calculateFees(0);
+    //       });
+    //     } else {
+    //       setState(() {
+    //         _calculateFeesFuture =
+    //             calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
+    //       });
+    //     }
+    //   }
+    // });
 
     super.initState();
   }
@@ -509,7 +505,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
     cryptoAmountController.dispose();
     baseAmountController.dispose();
     noteController.dispose();
-    feeController.dispose();
+    // feeController.dispose();
 
     _noteFocusNode.dispose();
     _addressFocusNode.dispose();
@@ -526,20 +522,20 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
     final String locale = ref.watch(
         localeServiceChangeNotifierProvider.select((value) => value.locale));
 
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
-      ref.listen(publicPrivateBalanceStateProvider, (previous, next) {
-        if (_amountToSend == null) {
-          setState(() {
-            _calculateFeesFuture = calculateFees(0);
-          });
-        } else {
-          setState(() {
-            _calculateFeesFuture =
-                calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
-          });
-        }
-      });
-    }
+    // if (coin == Coin.firo || coin == Coin.firoTestNet) {
+    //   ref.listen(publicPrivateBalanceStateProvider, (previous, next) {
+    //     if (_amountToSend == null) {
+    //       setState(() {
+    //         _calculateFeesFuture = calculateFees(0);
+    //       });
+    //     } else {
+    //       setState(() {
+    //         _calculateFeesFuture =
+    //             calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
+    //       });
+    //     }
+    //   });
+    // }
 
     return Column(
       crossAxisAlignment: CrossAxisAlignment.start,
diff --git a/pubspec.lock b/pubspec.lock
index 394d1ec8e..20992d827 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1410,7 +1410,7 @@ packages:
       name: string_scanner
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.1"
+    version: "1.1.0"
   string_validator:
     dependency: "direct main"
     description:

From d263bf1b5ea1599a47cdbea4a42e5a848231187c Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 08:39:52 -0600
Subject: [PATCH 044/426] set maxLines in desktop send address and note fields
 to 5

---
 .../home/my_stack_view/wallet_view/send/desktop_send.dart     | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
index 0ffe3b962..0d458e03b 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
@@ -873,6 +873,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             Constants.size.circularBorderRadius,
           ),
           child: TextField(
+            minLines: 1,
+            maxLines: 5,
             key: const Key("sendViewAddressFieldKey"),
             controller: sendToController,
             readOnly: false,
@@ -1110,6 +1112,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             Constants.size.circularBorderRadius,
           ),
           child: TextField(
+            minLines: 1,
+            maxLines: 5,
             autocorrect: Util.isDesktop ? false : true,
             enableSuggestions: Util.isDesktop ? false : true,
             controller: noteController,

From 3eff509c3295ad334810b013cbbbd22342730128 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 08:50:50 -0600
Subject: [PATCH 045/426] refactor longer bits of logic out of the build method

---
 .../wallet_view/send/desktop_send.dart        | 428 +++++++++---------
 1 file changed, 205 insertions(+), 223 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
index 0d458e03b..c353caa5e 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
@@ -416,7 +416,9 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
   // }
 
   Future<String?> _firoBalanceFuture(
-      ChangeNotifierProvider<Manager> provider, String locale) async {
+    ChangeNotifierProvider<Manager> provider,
+    String locale,
+  ) async {
     final wallet = ref.read(provider).wallet as FiroWallet?;
 
     if (wallet != null) {
@@ -435,6 +437,203 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
     return null;
   }
 
+  Widget firoBalanceFutureBuilder(
+    BuildContext context,
+    AsyncSnapshot<String?> snapshot,
+  ) {
+    if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
+      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+          "Private") {
+        _privateBalanceString = snapshot.data!;
+      } else {
+        _publicBalanceString = snapshot.data!;
+      }
+    }
+    if (ref.read(publicPrivateBalanceStateProvider.state).state == "Private" &&
+        _privateBalanceString != null) {
+      return Text(
+        "$_privateBalanceString ${coin.ticker}",
+        style: STextStyles.itemSubtitle(context),
+      );
+    } else if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+            "Public" &&
+        _publicBalanceString != null) {
+      return Text(
+        "$_publicBalanceString ${coin.ticker}",
+        style: STextStyles.itemSubtitle(context),
+      );
+    } else {
+      return AnimatedText(
+        stringsToLoopThrough: const [
+          "Loading balance",
+          "Loading balance.",
+          "Loading balance..",
+          "Loading balance...",
+        ],
+        style: STextStyles.itemSubtitle(context),
+      );
+    }
+  }
+
+  Future<void> scanQr() async {
+    try {
+      if (FocusScope.of(context).hasFocus) {
+        FocusScope.of(context).unfocus();
+        await Future<void>.delayed(const Duration(milliseconds: 75));
+      }
+
+      final qrResult = await scanner.scan();
+
+      Logging.instance.log("qrResult content: ${qrResult.rawContent}",
+          level: LogLevel.Info);
+
+      final results = AddressUtils.parseUri(qrResult.rawContent);
+
+      Logging.instance.log("qrResult parsed: $results", level: LogLevel.Info);
+
+      if (results.isNotEmpty && results["scheme"] == coin.uriScheme) {
+        // auto fill address
+        _address = results["address"] ?? "";
+        sendToController.text = _address!;
+
+        // autofill notes field
+        if (results["message"] != null) {
+          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.decimalPlaces,
+          );
+          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) {
+      // 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);
+    }
+  }
+
+  Future<void> pasteAddress() 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;
+      });
+    }
+  }
+
+  void fiatTextFieldOnChanged(String baseAmountString) {
+    if (baseAmountString.isNotEmpty &&
+        baseAmountString != "." &&
+        baseAmountString != ",") {
+      final baseAmount = baseAmountString.contains(",")
+          ? Decimal.parse(baseAmountString.replaceFirst(",", "."))
+          : Decimal.parse(baseAmountString);
+
+      var _price =
+          ref.read(priceAnd24hChangeNotifierProvider).getPrice(coin).item1;
+
+      if (_price == Decimal.zero) {
+        _amountToSend = Decimal.zero;
+      } else {
+        _amountToSend = baseAmount <= Decimal.zero
+            ? Decimal.zero
+            : (baseAmount / _price)
+                .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces);
+      }
+      if (_cachedAmountToSend != null && _cachedAmountToSend == _amountToSend) {
+        return;
+      }
+      _cachedAmountToSend = _amountToSend;
+      Logging.instance.log("it changed $_amountToSend $_cachedAmountToSend",
+          level: LogLevel.Info);
+
+      final amountString = Format.localizedStringAsFixed(
+        value: _amountToSend!,
+        locale: ref.read(localeServiceChangeNotifierProvider).locale,
+        decimalPlaces: Constants.decimalPlaces,
+      );
+
+      _cryptoAmountChangeLock = true;
+      cryptoAmountController.text = amountString;
+      _cryptoAmountChangeLock = false;
+    } else {
+      _amountToSend = Decimal.zero;
+      _cryptoAmountChangeLock = true;
+      cryptoAmountController.text = "";
+      _cryptoAmountChangeLock = false;
+    }
+    // setState(() {
+    //   _calculateFeesFuture = calculateFees(
+    //       Format.decimalAmountToSatoshis(
+    //           _amountToSend!));
+    // });
+    _updatePreviewButtonState(_address, _amountToSend);
+  }
+
+  Future<void> sendAllTapped() async {
+    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+      final firoWallet = ref
+          .read(walletsChangeNotifierProvider)
+          .getManager(walletId)
+          .wallet as FiroWallet;
+      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
+          "Private") {
+        cryptoAmountController.text =
+            (await firoWallet.availablePrivateBalance())
+                .toStringAsFixed(Constants.decimalPlaces);
+      } else {
+        cryptoAmountController.text =
+            (await firoWallet.availablePublicBalance())
+                .toStringAsFixed(Constants.decimalPlaces);
+      }
+    } else {
+      cryptoAmountController.text = (await ref
+              .read(walletsChangeNotifierProvider)
+              .getManager(walletId)
+              .availableBalance)
+          .toStringAsFixed(Constants.decimalPlaces);
+    }
+  }
+
   @override
   void initState() {
     ref.refresh(feeSheetSessionCacheProvider);
@@ -602,55 +801,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                           ),
                           FutureBuilder(
                             future: _firoBalanceFuture(provider, locale),
-                            builder:
-                                (context, AsyncSnapshot<String?> snapshot) {
-                              if (snapshot.connectionState ==
-                                      ConnectionState.done &&
-                                  snapshot.hasData) {
-                                if (ref
-                                        .read(publicPrivateBalanceStateProvider
-                                            .state)
-                                        .state ==
-                                    "Private") {
-                                  _privateBalanceString = snapshot.data!;
-                                } else {
-                                  _publicBalanceString = snapshot.data!;
-                                }
-                              }
-                              if (ref
-                                          .read(
-                                              publicPrivateBalanceStateProvider
-                                                  .state)
-                                          .state ==
-                                      "Private" &&
-                                  _privateBalanceString != null) {
-                                return Text(
-                                  "$_privateBalanceString ${coin.ticker}",
-                                  style: STextStyles.itemSubtitle(context),
-                                );
-                              } else if (ref
-                                          .read(
-                                              publicPrivateBalanceStateProvider
-                                                  .state)
-                                          .state ==
-                                      "Public" &&
-                                  _publicBalanceString != null) {
-                                return Text(
-                                  "$_publicBalanceString ${coin.ticker}",
-                                  style: STextStyles.itemSubtitle(context),
-                                );
-                              } else {
-                                return AnimatedText(
-                                  stringsToLoopThrough: const [
-                                    "Loading balance",
-                                    "Loading balance.",
-                                    "Loading balance..",
-                                    "Loading balance...",
-                                  ],
-                                  style: STextStyles.itemSubtitle(context),
-                                );
-                              }
-                            },
+                            builder: firoBalanceFutureBuilder,
                           ),
                         ],
                       ),
@@ -682,25 +833,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             ),
             BlueTextButton(
               text: "Send all ${coin.ticker}",
-              onTap: () async {
-                if (coin == Coin.firo || coin == Coin.firoTestNet) {
-                  final firoWallet = ref.read(provider).wallet as FiroWallet;
-                  if (ref.read(publicPrivateBalanceStateProvider.state).state ==
-                      "Private") {
-                    cryptoAmountController.text =
-                        (await firoWallet.availablePrivateBalance())
-                            .toStringAsFixed(Constants.decimalPlaces);
-                  } else {
-                    cryptoAmountController.text =
-                        (await firoWallet.availablePublicBalance())
-                            .toStringAsFixed(Constants.decimalPlaces);
-                  }
-                } else {
-                  cryptoAmountController.text =
-                      (await ref.read(provider).availableBalance)
-                          .toStringAsFixed(Constants.decimalPlaces);
-                }
-              },
+              onTap: sendAllTapped,
             ),
           ],
         ),
@@ -780,58 +913,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                       ? newValue
                       : oldValue),
             ],
-            onChanged: (baseAmountString) {
-              if (baseAmountString.isNotEmpty &&
-                  baseAmountString != "." &&
-                  baseAmountString != ",") {
-                final baseAmount = baseAmountString.contains(",")
-                    ? Decimal.parse(baseAmountString.replaceFirst(",", "."))
-                    : Decimal.parse(baseAmountString);
-
-                var _price = ref
-                    .read(priceAnd24hChangeNotifierProvider)
-                    .getPrice(coin)
-                    .item1;
-
-                if (_price == Decimal.zero) {
-                  _amountToSend = Decimal.zero;
-                } else {
-                  _amountToSend = baseAmount <= Decimal.zero
-                      ? Decimal.zero
-                      : (baseAmount / _price).toDecimal(
-                          scaleOnInfinitePrecision: Constants.decimalPlaces);
-                }
-                if (_cachedAmountToSend != null &&
-                    _cachedAmountToSend == _amountToSend) {
-                  return;
-                }
-                _cachedAmountToSend = _amountToSend;
-                Logging.instance.log(
-                    "it changed $_amountToSend $_cachedAmountToSend",
-                    level: LogLevel.Info);
-
-                final amountString = Format.localizedStringAsFixed(
-                  value: _amountToSend!,
-                  locale: ref.read(localeServiceChangeNotifierProvider).locale,
-                  decimalPlaces: Constants.decimalPlaces,
-                );
-
-                _cryptoAmountChangeLock = true;
-                cryptoAmountController.text = amountString;
-                _cryptoAmountChangeLock = false;
-              } else {
-                _amountToSend = Decimal.zero;
-                _cryptoAmountChangeLock = true;
-                cryptoAmountController.text = "";
-                _cryptoAmountChangeLock = false;
-              }
-              // setState(() {
-              //   _calculateFeesFuture = calculateFees(
-              //       Format.decimalAmountToSatoshis(
-              //           _amountToSend!));
-              // });
-              _updatePreviewButtonState(_address, _amountToSend);
-            },
+            onChanged: fiatTextFieldOnChanged,
             decoration: InputDecoration(
               contentPadding: const EdgeInsets.only(
                 top: 12,
@@ -937,28 +1019,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                           : 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;
-                                  });
-                                }
-                              },
+                              onTap: pasteAddress,
                               child: sendToController.text.isEmpty
                                   ? const ClipboardIcon()
                                   : const XIcon(),
@@ -977,86 +1038,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                       if (sendToController.text.isEmpty)
                         TextFieldIconButton(
                           key: const Key("sendViewScanQrButtonKey"),
-                          onTap: () async {
-                            try {
-                              if (FocusScope.of(context).hasFocus) {
-                                FocusScope.of(context).unfocus();
-                                await Future<void>.delayed(
-                                    const Duration(milliseconds: 75));
-                              }
-
-                              final qrResult = await scanner.scan();
-
-                              Logging.instance.log(
-                                  "qrResult content: ${qrResult.rawContent}",
-                                  level: LogLevel.Info);
-
-                              final results =
-                                  AddressUtils.parseUri(qrResult.rawContent);
-
-                              Logging.instance.log("qrResult parsed: $results",
-                                  level: LogLevel.Info);
-
-                              if (results.isNotEmpty &&
-                                  results["scheme"] == coin.uriScheme) {
-                                // auto fill address
-                                _address = results["address"] ?? "";
-                                sendToController.text = _address!;
-
-                                // autofill notes field
-                                if (results["message"] != null) {
-                                  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.decimalPlaces,
-                                  );
-                                  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) {
-                              // here we ignore the exception caused by not giving permission
-                              // to use the camera to scan a qr code
-                              Logging.instance.log(
-                                  "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
-                                  level: LogLevel.Warning);
-                            }
-                          },
+                          onTap: scanQr,
                           child: const QrCodeIcon(),
                         )
                     ],

From d3656145332e352fca5a6957c338960dc5c10ca1 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 10:51:56 -0600
Subject: [PATCH 046/426] desktop send fields restyle

---
 .../wallet_view/send/desktop_send.dart        | 68 +++++++++++++++----
 lib/widgets/stack_text_field.dart             | 20 +++++-
 2 files changed, 71 insertions(+), 17 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
index c353caa5e..b084603b6 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
@@ -745,7 +745,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         if (coin == Coin.firo)
           Text(
             "Send from",
-            style: STextStyles.smallMed12(context),
+            style: STextStyles.desktopTextExtraSmall(context).copyWith(
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .textFieldActiveSearchIconRight,
+            ),
             textAlign: TextAlign.left,
           ),
         if (coin == Coin.firo)
@@ -828,7 +832,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           children: [
             Text(
               "Amount",
-              style: STextStyles.smallMed12(context),
+              style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldActiveSearchIconRight,
+              ),
               textAlign: TextAlign.left,
             ),
             BlueTextButton(
@@ -864,12 +872,15 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           ],
           decoration: InputDecoration(
             contentPadding: const EdgeInsets.only(
-              top: 12,
+              top: 22,
               right: 12,
+              bottom: 22,
             ),
             hintText: "0",
-            hintStyle: STextStyles.fieldLabel(context).copyWith(
-              fontSize: 14,
+            hintStyle: STextStyles.desktopTextExtraSmall(context).copyWith(
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .textFieldDefaultText,
             ),
             prefixIcon: FittedBox(
               fit: BoxFit.scaleDown,
@@ -916,12 +927,15 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             onChanged: fiatTextFieldOnChanged,
             decoration: InputDecoration(
               contentPadding: const EdgeInsets.only(
-                top: 12,
+                top: 22,
                 right: 12,
+                bottom: 22,
               ),
               hintText: "0",
-              hintStyle: STextStyles.fieldLabel(context).copyWith(
-                fontSize: 14,
+              hintStyle: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultText,
               ),
               prefixIcon: FittedBox(
                 fit: BoxFit.scaleDown,
@@ -944,7 +958,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         ),
         Text(
           "Send to",
-          style: STextStyles.smallMed12(context),
+          style: STextStyles.desktopTextExtraSmall(context).copyWith(
+            color: Theme.of(context)
+                .extension<StackColors>()!
+                .textFieldActiveSearchIconRight,
+          ),
           textAlign: TextAlign.left,
         ),
         const SizedBox(
@@ -981,16 +999,22 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
               });
             },
             focusNode: _addressFocusNode,
-            style: STextStyles.field(context),
+            style: STextStyles.desktopTextExtraSmall(context).copyWith(
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .textFieldActiveText,
+              height: 1.8,
+            ),
             decoration: standardInputDecoration(
               "Enter ${coin.ticker} address",
               _addressFocusNode,
               context,
+              desktopMed: true,
             ).copyWith(
               contentPadding: const EdgeInsets.only(
                 left: 16,
-                top: 6,
-                bottom: 8,
+                top: 11,
+                bottom: 12,
                 right: 5,
               ),
               suffixIcon: Padding(
@@ -1083,7 +1107,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         ),
         Text(
           "Note (optional)",
-          style: STextStyles.smallMed12(context),
+          style: STextStyles.desktopTextExtraSmall(context).copyWith(
+            color: Theme.of(context)
+                .extension<StackColors>()!
+                .textFieldActiveSearchIconRight,
+          ),
           textAlign: TextAlign.left,
         ),
         const SizedBox(
@@ -1100,13 +1128,25 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             enableSuggestions: Util.isDesktop ? false : true,
             controller: noteController,
             focusNode: _noteFocusNode,
-            style: STextStyles.field(context),
+            style: STextStyles.desktopTextExtraSmall(context).copyWith(
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .textFieldActiveText,
+              height: 1.8,
+            ),
             onChanged: (_) => setState(() {}),
             decoration: standardInputDecoration(
               "Type something...",
               _noteFocusNode,
               context,
+              desktopMed: true,
             ).copyWith(
+              contentPadding: const EdgeInsets.only(
+                left: 16,
+                top: 11,
+                bottom: 12,
+                right: 5,
+              ),
               suffixIcon: noteController.text.isNotEmpty
                   ? Padding(
                       padding: const EdgeInsets.only(right: 0),
diff --git a/lib/widgets/stack_text_field.dart b/lib/widgets/stack_text_field.dart
index 9858c18db..1f1e9f8de 100644
--- a/lib/widgets/stack_text_field.dart
+++ b/lib/widgets/stack_text_field.dart
@@ -4,7 +4,11 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
 
 InputDecoration standardInputDecoration(
-    String? labelText, FocusNode textFieldFocusNode, BuildContext context) {
+  String? labelText,
+  FocusNode textFieldFocusNode,
+  BuildContext context, {
+  bool desktopMed = false,
+}) {
   final isDesktop = Util.isDesktop;
 
   return InputDecoration(
@@ -13,10 +17,20 @@ InputDecoration standardInputDecoration(
         ? Theme.of(context).extension<StackColors>()!.textFieldActiveBG
         : Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
     labelStyle: isDesktop
-        ? STextStyles.desktopTextFieldLabel(context)
+        ? desktopMed
+            ? STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultText)
+            : STextStyles.desktopTextFieldLabel(context)
         : STextStyles.fieldLabel(context),
     hintStyle: isDesktop
-        ? STextStyles.desktopTextFieldLabel(context)
+        ? desktopMed
+            ? STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultText)
+            : STextStyles.desktopTextFieldLabel(context)
         : STextStyles.fieldLabel(context),
     enabledBorder: InputBorder.none,
     focusedBorder: InputBorder.none,

From 51b6a953903b0dc1ca18447c5e6c47ddcb08e469 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 11:05:23 -0600
Subject: [PATCH 047/426] medium desktop buttons

---
 .../wallet_view/receive/desktop_receive.dart  |  2 +-
 .../wallet_view/send/desktop_send.dart        |  2 +-
 lib/widgets/desktop/primary_button.dart       | 44 +++++++++++++------
 lib/widgets/desktop/secondary_button.dart     | 44 +++++++++++++------
 4 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
index 79e3b81cf..71f708e35 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
@@ -191,7 +191,7 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
           ),
         if (coin != Coin.epicCash)
           SecondaryButton(
-            height: 56,
+            desktopMed: true,
             onPressed: generateNewAddress,
             label: "Generate new address",
           ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
index b084603b6..116262d23 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
@@ -1173,7 +1173,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           height: 36,
         ),
         PrimaryButton(
-          height: 56,
+          desktopMed: true,
           label: "Preview send",
           enabled: ref.watch(previewTxButtonStateProvider.state).state,
           onPressed: ref.watch(previewTxButtonStateProvider.state).state
diff --git a/lib/widgets/desktop/primary_button.dart b/lib/widgets/desktop/primary_button.dart
index 6034cc08b..f3c900c34 100644
--- a/lib/widgets/desktop/primary_button.dart
+++ b/lib/widgets/desktop/primary_button.dart
@@ -13,6 +13,7 @@ class PrimaryButton extends StatelessWidget {
     this.icon,
     this.onPressed,
     this.enabled = true,
+    this.desktopMed = false,
   }) : super(key: key);
 
   final double? width;
@@ -21,13 +22,40 @@ class PrimaryButton extends StatelessWidget {
   final VoidCallback? onPressed;
   final bool enabled;
   final Widget? icon;
+  final bool desktopMed;
+
+  TextStyle getStyle(bool isDesktop, BuildContext context) {
+    if (isDesktop) {
+      if (desktopMed) {
+        return STextStyles.desktopTextExtraSmall(context).copyWith(
+          color: enabled
+              ? Theme.of(context).extension<StackColors>()!.buttonTextPrimary
+              : Theme.of(context)
+                  .extension<StackColors>()!
+                  .buttonTextPrimaryDisabled,
+        );
+      } else {
+        return enabled
+            ? STextStyles.desktopButtonEnabled(context)
+            : STextStyles.desktopButtonDisabled(context);
+      }
+    } else {
+      return STextStyles.button(context).copyWith(
+        color: enabled
+            ? Theme.of(context).extension<StackColors>()!.buttonTextPrimary
+            : Theme.of(context)
+                .extension<StackColors>()!
+                .buttonTextPrimaryDisabled,
+      );
+    }
+  }
 
   @override
   Widget build(BuildContext context) {
     final isDesktop = Util.isDesktop;
 
     return CustomTextButtonBase(
-      height: height,
+      height: desktopMed ? 56 : height,
       width: width,
       textButton: TextButton(
         onPressed: enabled ? onPressed : null,
@@ -49,19 +77,7 @@ class PrimaryButton extends StatelessWidget {
             if (label != null)
               Text(
                 label!,
-                style: isDesktop
-                    ? enabled
-                        ? STextStyles.desktopButtonEnabled(context)
-                        : STextStyles.desktopButtonDisabled(context)
-                    : STextStyles.button(context).copyWith(
-                        color: enabled
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .buttonTextPrimary
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .buttonTextPrimaryDisabled,
-                      ),
+                style: getStyle(isDesktop, context),
               ),
           ],
         ),
diff --git a/lib/widgets/desktop/secondary_button.dart b/lib/widgets/desktop/secondary_button.dart
index 2a88e548d..8d5eae0ce 100644
--- a/lib/widgets/desktop/secondary_button.dart
+++ b/lib/widgets/desktop/secondary_button.dart
@@ -13,6 +13,7 @@ class SecondaryButton extends StatelessWidget {
     this.icon,
     this.onPressed,
     this.enabled = true,
+    this.desktopMed = false,
   }) : super(key: key);
 
   final double? width;
@@ -21,13 +22,40 @@ class SecondaryButton extends StatelessWidget {
   final VoidCallback? onPressed;
   final bool enabled;
   final Widget? icon;
+  final bool desktopMed;
+
+  TextStyle getStyle(bool isDesktop, BuildContext context) {
+    if (isDesktop) {
+      if (desktopMed) {
+        return STextStyles.desktopTextExtraSmall(context).copyWith(
+          color: enabled
+              ? Theme.of(context).extension<StackColors>()!.buttonTextSecondary
+              : Theme.of(context)
+                  .extension<StackColors>()!
+                  .buttonTextSecondaryDisabled,
+        );
+      } else {
+        return enabled
+            ? STextStyles.desktopButtonSecondaryEnabled(context)
+            : STextStyles.desktopButtonSecondaryDisabled(context);
+      }
+    } else {
+      return STextStyles.button(context).copyWith(
+        color: enabled
+            ? Theme.of(context).extension<StackColors>()!.buttonTextSecondary
+            : Theme.of(context)
+                .extension<StackColors>()!
+                .buttonTextSecondaryDisabled,
+      );
+    }
+  }
 
   @override
   Widget build(BuildContext context) {
     final isDesktop = Util.isDesktop;
 
     return CustomTextButtonBase(
-      height: height,
+      height: desktopMed ? 56 : height,
       width: width,
       textButton: TextButton(
         onPressed: enabled ? onPressed : null,
@@ -49,19 +77,7 @@ class SecondaryButton extends StatelessWidget {
             if (label != null)
               Text(
                 label!,
-                style: isDesktop
-                    ? enabled
-                        ? STextStyles.desktopButtonSecondaryEnabled(context)
-                        : STextStyles.desktopButtonSecondaryDisabled(context)
-                    : STextStyles.button(context).copyWith(
-                        color: enabled
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .buttonTextSecondary
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .buttonTextSecondaryDisabled,
-                      ),
+                style: getStyle(isDesktop, context),
               ),
           ],
         ),

From 00e80196398432465dfc7ca0dbe4b1679afeea40 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 11:21:22 -0600
Subject: [PATCH 048/426] desktop wallet balance info style fixes

---
 .../sub_widgets/wallet_refresh_button.dart    |  25 ++-
 .../wallet_view/desktop_wallet_summary.dart   | 200 +++++++++---------
 2 files changed, 119 insertions(+), 106 deletions(-)

diff --git a/lib/pages/wallet_view/sub_widgets/wallet_refresh_button.dart b/lib/pages/wallet_view/sub_widgets/wallet_refresh_button.dart
index 7faae106f..603b72338 100644
--- a/lib/pages/wallet_view/sub_widgets/wallet_refresh_button.dart
+++ b/lib/pages/wallet_view/sub_widgets/wallet_refresh_button.dart
@@ -10,6 +10,7 @@ import 'package:stackwallet/services/event_bus/global_event_bus.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
 
 /// [eventBus] should only be set during testing
 class WalletRefreshButton extends ConsumerStatefulWidget {
@@ -70,7 +71,7 @@ class _RefreshButtonState extends ConsumerState<WalletRefreshButton>
               _spinController?.stop();
               break;
             case WalletSyncStatus.syncing:
-              _spinController?.repeat();
+              unawaited(_spinController?.repeat());
               break;
           }
         }
@@ -92,10 +93,15 @@ class _RefreshButtonState extends ConsumerState<WalletRefreshButton>
 
   @override
   Widget build(BuildContext context) {
+    final isDesktop = Util.isDesktop;
+
     return SizedBox(
-      height: 36,
-      width: 36,
+      height: isDesktop ? 22 : 36,
+      width: isDesktop ? 22 : 36,
       child: MaterialButton(
+        color: isDesktop
+            ? Theme.of(context).extension<StackColors>()!.buttonBackSecondary
+            : null,
         splashColor: Theme.of(context).extension<StackColors>()!.highlight,
         onPressed: () {
           final managerProvider = ref
@@ -110,6 +116,9 @@ class _RefreshButtonState extends ConsumerState<WalletRefreshButton>
                 .then((_) => _spinController?.stop());
           }
         },
+        elevation: 0,
+        highlightElevation: 0,
+        hoverElevation: 0,
         padding: EdgeInsets.zero,
         materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
         shape: RoundedRectangleBorder(
@@ -121,9 +130,13 @@ class _RefreshButtonState extends ConsumerState<WalletRefreshButton>
           turns: _spinAnimation,
           child: SvgPicture.asset(
             Assets.svg.arrowRotate,
-            width: 24,
-            height: 24,
-            color: Theme.of(context).extension<StackColors>()!.textFavoriteCard,
+            width: isDesktop ? 12 : 24,
+            height: isDesktop ? 12 : 24,
+            color: isDesktop
+                ? Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultSearchIconRight
+                : Theme.of(context).extension<StackColors>()!.textFavoriteCard,
           ),
         ),
       ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart
index fe2cfa7b2..7a9e93467 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart
@@ -1,17 +1,13 @@
 import 'package:decimal/decimal.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart';
 import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_refresh_button.dart';
 import 'package:stackwallet/providers/providers.dart';
-import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
-import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -100,9 +96,9 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
                 final priceTuple = ref.watch(priceAnd24hChangeNotifierProvider
                     .select((value) => value.getPrice(coin)));
 
-                final _showAvailable =
-                    ref.watch(walletBalanceToggleStateProvider.state).state ==
-                        WalletBalanceToggleState.available;
+                final _showAvailable = false;
+                // ref.watch(walletBalanceToggleStateProvider.state).state ==
+                //     WalletBalanceToggleState.available;
 
                 return FutureBuilder(
                   future: _showAvailable
@@ -125,46 +121,46 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
                       return Column(
                         crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
-                          GestureDetector(
-                            onTap: showSheet,
-                            child: Row(
-                              children: [
-                                if (coin == Coin.firo ||
-                                    coin == Coin.firoTestNet)
-                                  Text(
-                                    "${_showAvailable ? "Private" : "Public"} Balance",
-                                    style: STextStyles.subtitle500(context)
-                                        .copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textFavoriteCard,
-                                    ),
-                                  ),
-                                if (coin != Coin.firo &&
-                                    coin != Coin.firoTestNet)
-                                  Text(
-                                    "${_showAvailable ? "Available" : "Full"} Balance",
-                                    style: STextStyles.subtitle500(context)
-                                        .copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textFavoriteCard,
-                                    ),
-                                  ),
-                                const SizedBox(
-                                  width: 4,
-                                ),
-                                SvgPicture.asset(
-                                  Assets.svg.chevronDown,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textFavoriteCard,
-                                  width: 8,
-                                  height: 4,
-                                ),
-                              ],
-                            ),
-                          ),
+                          // GestureDetector(
+                          //   onTap: showSheet,
+                          //   child: Row(
+                          //     children: [
+                          //       if (coin == Coin.firo ||
+                          //           coin == Coin.firoTestNet)
+                          //         Text(
+                          //           "${_showAvailable ? "Private" : "Public"} Balance",
+                          //           style: STextStyles.subtitle500(context)
+                          //               .copyWith(
+                          //             color: Theme.of(context)
+                          //                 .extension<StackColors>()!
+                          //                 .textFavoriteCard,
+                          //           ),
+                          //         ),
+                          //       if (coin != Coin.firo &&
+                          //           coin != Coin.firoTestNet)
+                          //         Text(
+                          //           "${_showAvailable ? "Available" : "Full"} Balance",
+                          //           style: STextStyles.subtitle500(context)
+                          //               .copyWith(
+                          //             color: Theme.of(context)
+                          //                 .extension<StackColors>()!
+                          //                 .textFavoriteCard,
+                          //           ),
+                          //         ),
+                          //       const SizedBox(
+                          //         width: 4,
+                          //       ),
+                          //       SvgPicture.asset(
+                          //         Assets.svg.chevronDown,
+                          //         color: Theme.of(context)
+                          //             .extension<StackColors>()!
+                          //             .textFavoriteCard,
+                          //         width: 8,
+                          //         height: 4,
+                          //       ),
+                          //     ],
+                          //   ),
+                          // ),
                           FittedBox(
                             fit: BoxFit.scaleDown,
                             child: Text(
@@ -196,46 +192,46 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
                       return Column(
                         crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
-                          GestureDetector(
-                            onTap: showSheet,
-                            child: Row(
-                              children: [
-                                if (coin == Coin.firo ||
-                                    coin == Coin.firoTestNet)
-                                  Text(
-                                    "${_showAvailable ? "Private" : "Public"} Balance",
-                                    style: STextStyles.subtitle500(context)
-                                        .copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textFavoriteCard,
-                                    ),
-                                  ),
-                                if (coin != Coin.firo &&
-                                    coin != Coin.firoTestNet)
-                                  Text(
-                                    "${_showAvailable ? "Available" : "Full"} Balance",
-                                    style: STextStyles.subtitle500(context)
-                                        .copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textFavoriteCard,
-                                    ),
-                                  ),
-                                const SizedBox(
-                                  width: 4,
-                                ),
-                                SvgPicture.asset(
-                                  Assets.svg.chevronDown,
-                                  width: 8,
-                                  height: 4,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textFavoriteCard,
-                                ),
-                              ],
-                            ),
-                          ),
+                          // GestureDetector(
+                          //   onTap: showSheet,
+                          //   child: Row(
+                          //     children: [
+                          //       if (coin == Coin.firo ||
+                          //           coin == Coin.firoTestNet)
+                          //         Text(
+                          //           "${_showAvailable ? "Private" : "Public"} Balance",
+                          //           style: STextStyles.subtitle500(context)
+                          //               .copyWith(
+                          //             color: Theme.of(context)
+                          //                 .extension<StackColors>()!
+                          //                 .textFavoriteCard,
+                          //           ),
+                          //         ),
+                          //       if (coin != Coin.firo &&
+                          //           coin != Coin.firoTestNet)
+                          //         Text(
+                          //           "${_showAvailable ? "Available" : "Full"} Balance",
+                          //           style: STextStyles.subtitle500(context)
+                          //               .copyWith(
+                          //             color: Theme.of(context)
+                          //                 .extension<StackColors>()!
+                          //                 .textFavoriteCard,
+                          //           ),
+                          //         ),
+                          //       const SizedBox(
+                          //         width: 4,
+                          //       ),
+                          //       SvgPicture.asset(
+                          //         Assets.svg.chevronDown,
+                          //         width: 8,
+                          //         height: 4,
+                          //         color: Theme.of(context)
+                          //             .extension<StackColors>()!
+                          //             .textFavoriteCard,
+                          //       ),
+                          //     ],
+                          //   ),
+                          // ),
                           AnimatedText(
                             stringsToLoopThrough: const [
                               "Loading balance   ",
@@ -250,20 +246,21 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
                                   .textFavoriteCard,
                             ),
                           ),
-                          AnimatedText(
-                            stringsToLoopThrough: const [
-                              "Loading balance   ",
-                              "Loading balance.  ",
-                              "Loading balance.. ",
-                              "Loading balance..."
-                            ],
-                            style: STextStyles.desktopTextExtraSmall(context)
-                                .copyWith(
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textSubtitle1,
+                          if (externalCalls)
+                            AnimatedText(
+                              stringsToLoopThrough: const [
+                                "Loading balance   ",
+                                "Loading balance.  ",
+                                "Loading balance.. ",
+                                "Loading balance..."
+                              ],
+                              style: STextStyles.desktopTextExtraSmall(context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textSubtitle1,
+                              ),
                             ),
-                          ),
                         ],
                       );
                     }
@@ -273,6 +270,9 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
             ),
           ],
         ),
+        const SizedBox(
+          width: 8,
+        ),
         WalletRefreshButton(
           walletId: walletId,
           initialSyncStatus: widget.initialSyncStatus,

From 6ca5b557144984429bdce391c44933daea318a41 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 11:34:46 -0600
Subject: [PATCH 049/426] desktop receive style fixes

---
 .../wallet_view/receive/desktop_receive.dart  | 75 +++++++++++++------
 1 file changed, 54 insertions(+), 21 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
index 71f708e35..46b4cfcfc 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
@@ -16,7 +16,6 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_loading_overlay.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -150,8 +149,8 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
                         children: [
                           SvgPicture.asset(
                             Assets.svg.copy,
-                            width: 10,
-                            height: 10,
+                            width: 15,
+                            height: 15,
                             color: Theme.of(context)
                                 .extension<StackColors>()!
                                 .infoItemIcons,
@@ -168,14 +167,19 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
                     ],
                   ),
                   const SizedBox(
-                    height: 4,
+                    height: 8,
                   ),
                   Row(
                     children: [
                       Expanded(
                         child: Text(
                           receivingAddress,
-                          style: STextStyles.itemSubtitle12(context),
+                          style: STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark,
+                          ),
                         ),
                       ),
                     ],
@@ -209,25 +213,54 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
         const SizedBox(
           height: 32,
         ),
-        Center(
-          child: BlueTextButton(
-            text: "Create new QR code",
-            onTap: () async {
-              unawaited(
-                Navigator.of(context).push(
-                  RouteGenerator.getRoute(
-                    shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
-                    builder: (_) => GenerateUriQrCodeView(
-                      coin: coin,
-                      receivingAddress: receivingAddress,
-                    ),
-                    settings: const RouteSettings(
-                      name: GenerateUriQrCodeView.routeName,
+        // TODO: create transparent button class to account for hover
+        GestureDetector(
+          onTap: () async {
+            unawaited(
+              Navigator.of(context).push(
+                RouteGenerator.getRoute(
+                  shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
+                  builder: (_) => GenerateUriQrCodeView(
+                    coin: coin,
+                    receivingAddress: receivingAddress,
+                  ),
+                  settings: const RouteSettings(
+                    name: GenerateUriQrCodeView.routeName,
+                  ),
+                ),
+              ),
+            );
+          },
+          child: Container(
+            color: Colors.transparent,
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.center,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.qrcode,
+                  width: 14,
+                  height: 16,
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .accentColorBlue,
+                ),
+                const SizedBox(
+                  width: 8,
+                ),
+                Padding(
+                  padding: const EdgeInsets.only(bottom: 2),
+                  child: Text(
+                    "Create new QR code",
+                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorBlue,
                     ),
                   ),
                 ),
-              );
-            },
+              ],
+            ),
           ),
         ),
       ],

From 8b136b003c820687acf8d1ba9066379c3e0702d0 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 11:39:06 -0600
Subject: [PATCH 050/426] overflow fix

---
 .../home/my_stack_view/wallet_view/desktop_wallet_view.dart    | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index f86eba750..e411def59 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -225,8 +225,7 @@ class _MyWalletState extends State<MyWallet> {
 
   @override
   Widget build(BuildContext context) {
-    return Column(
-      crossAxisAlignment: CrossAxisAlignment.start,
+    return ListView(
       children: [
         Text(
           "My wallet",

From 7203f09eb036e7655e93e2aa6758c9a7dabe1b48 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 12:47:30 -0600
Subject: [PATCH 051/426] desktop sync status styling and basic functionality

---
 .../wallet_view/desktop_wallet_view.dart      | 276 ++++++++++++++----
 1 file changed, 223 insertions(+), 53 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index e411def59..2bcb9eeb4 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -1,13 +1,24 @@
+import 'dart:async';
+
+import 'package:event_bus/event_bus.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart';
+import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
+import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_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/exchange/exchange_data_loading_service.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
+import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -16,16 +27,20 @@ import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:tuple/tuple.dart';
 
+/// [eventBus] should only be set during testing
 class DesktopWalletView extends ConsumerStatefulWidget {
   const DesktopWalletView({
     Key? key,
     required this.walletId,
+    this.eventBus,
   }) : super(key: key);
 
   static const String routeName = "/desktopWalletView";
 
   final String walletId;
+  final EventBus? eventBus;
 
   @override
   ConsumerState<DesktopWalletView> createState() => _DesktopWalletViewState();
@@ -33,15 +48,69 @@ class DesktopWalletView extends ConsumerStatefulWidget {
 
 class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
   late final String walletId;
+  late final EventBus eventBus;
+
+  late final bool _shouldDisableAutoSyncOnLogOut;
+
+  final _cnLoadingService = ExchangeDataLoadingService();
 
   Future<void> onBackPressed() async {
-    // TODO log out and close wallet before popping back
-    Navigator.of(context).pop();
+    await _logout();
+    if (mounted) {
+      Navigator.of(context).pop();
+    }
+  }
+
+  Future<void> _logout() async {
+    final managerProvider =
+        ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
+    if (_shouldDisableAutoSyncOnLogOut) {
+      // disable auto sync if it was enabled only when loading wallet
+      ref.read(managerProvider).shouldAutoSync = false;
+    }
+    ref.read(managerProvider.notifier).isActiveWallet = false;
+    ref.read(transactionFilterProvider.state).state = null;
+    if (ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled &&
+        ref.read(prefsChangeNotifierProvider).backupFrequencyType ==
+            BackupFrequencyType.afterClosingAWallet) {
+      unawaited(ref.read(autoSWBServiceProvider).doBackup());
+    }
+  }
+
+  void _loadCNData() {
+    // unawaited future
+    if (ref.read(prefsChangeNotifierProvider).externalCalls) {
+      _cnLoadingService.loadAll(ref,
+          coin: ref
+              .read(walletsChangeNotifierProvider)
+              .getManager(walletId)
+              .coin);
+    } else {
+      Logging.instance.log("User does not want to use external calls",
+          level: LogLevel.Info);
+    }
   }
 
   @override
   void initState() {
     walletId = widget.walletId;
+    final managerProvider =
+        ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
+
+    eventBus =
+        widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
+
+    ref.read(managerProvider).isActiveWallet = true;
+    if (!ref.read(managerProvider).shouldAutoSync) {
+      // enable auto sync if it wasn't enabled when loading wallet
+      ref.read(managerProvider).shouldAutoSync = true;
+      _shouldDisableAutoSyncOnLogOut = true;
+    } else {
+      _shouldDisableAutoSyncOnLogOut = false;
+    }
+
+    ref.read(managerProvider).refresh();
+
     super.initState();
   }
 
@@ -95,13 +164,16 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
           ],
         ),
         trailing: Row(
-          children: const [
-            NetworkInfoButton(),
-            SizedBox(
+          children: [
+            NetworkInfoButton(
+              walletId: walletId,
+              eventBus: eventBus,
+            ),
+            const SizedBox(
               width: 32,
             ),
-            WalletKeysButton(),
-            SizedBox(
+            const WalletKeysButton(),
+            const SizedBox(
               width: 32,
             ),
           ],
@@ -132,37 +204,6 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                         ? WalletSyncStatus.syncing
                         : WalletSyncStatus.synced,
                   ),
-                  // Column(
-                  //   crossAxisAlignment: CrossAxisAlignment.start,
-                  //   mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  //   children: [
-                  //     Row(
-                  //       children: [
-                  //         Text(
-                  //           "TODO: balance",
-                  //           style: STextStyles.desktopH3(context),
-                  //         ),
-                  //         const SizedBox(
-                  //           width: 8,
-                  //         ),
-                  //         Container(
-                  //           color: Colors.red,
-                  //           width: 20,
-                  //           height: 20,
-                  //         ),
-                  //       ],
-                  //     ),
-                  //     Text(
-                  //       "todo: fiat balance",
-                  //       style:
-                  //           STextStyles.desktopTextExtraSmall(context).copyWith(
-                  //         color: Theme.of(context)
-                  //             .extension<StackColors>()!
-                  //             .textSubtitle1,
-                  //       ),
-                  //     )
-                  //   ],
-                  // ),
                   const Spacer(),
                   SecondaryButton(
                     width: 180,
@@ -195,7 +236,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                   const SizedBox(
                     width: 16,
                   ),
-                  Expanded(
+                  const Expanded(
                     child: RecentDesktopTransactions(),
                   ),
                 ],
@@ -284,7 +325,6 @@ class _MyWalletState extends State<MyWallet> {
             ],
           ),
         ),
-        const Spacer(),
       ],
     );
   }
@@ -461,30 +501,160 @@ class _RecentDesktopTransactionsState extends State<RecentDesktopTransactions> {
   }
 }
 
-class NetworkInfoButton extends StatelessWidget {
-  const NetworkInfoButton({Key? key}) : super(key: key);
+class NetworkInfoButton extends ConsumerStatefulWidget {
+  const NetworkInfoButton({
+    Key? key,
+    required this.walletId,
+    this.eventBus,
+  }) : super(key: key);
+
+  final String walletId;
+  final EventBus? eventBus;
+
+  @override
+  ConsumerState<NetworkInfoButton> createState() => _NetworkInfoButtonState();
+}
+
+class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
+  late final String walletId;
+  late final EventBus eventBus;
+
+  late WalletSyncStatus _currentSyncStatus;
+  late NodeConnectionStatus _currentNodeStatus;
+
+  late StreamSubscription<dynamic> _syncStatusSubscription;
+  late StreamSubscription<dynamic> _nodeStatusSubscription;
+
+  @override
+  void initState() {
+    walletId = widget.walletId;
+    final managerProvider =
+        ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
+
+    eventBus =
+        widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
+
+    if (ref.read(managerProvider).isRefreshing) {
+      _currentSyncStatus = WalletSyncStatus.syncing;
+      _currentNodeStatus = NodeConnectionStatus.connected;
+    } else {
+      _currentSyncStatus = WalletSyncStatus.synced;
+      if (ref.read(managerProvider).isConnected) {
+        _currentNodeStatus = NodeConnectionStatus.connected;
+      } else {
+        _currentNodeStatus = NodeConnectionStatus.disconnected;
+        _currentSyncStatus = WalletSyncStatus.unableToSync;
+      }
+    }
+
+    _syncStatusSubscription =
+        eventBus.on<WalletSyncStatusChangedEvent>().listen(
+      (event) async {
+        if (event.walletId == widget.walletId) {
+          setState(() {
+            _currentSyncStatus = event.newStatus;
+          });
+        }
+      },
+    );
+
+    _nodeStatusSubscription =
+        eventBus.on<NodeConnectionStatusChangedEvent>().listen(
+      (event) async {
+        if (event.walletId == widget.walletId) {
+          setState(() {
+            _currentNodeStatus = event.newStatus;
+          });
+        }
+      },
+    );
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _nodeStatusSubscription.cancel();
+    _syncStatusSubscription.cancel();
+    super.dispose();
+  }
+
+  Widget _buildNetworkIcon(WalletSyncStatus status, BuildContext context) {
+    const size = 24.0;
+    switch (status) {
+      case WalletSyncStatus.unableToSync:
+        return SvgPicture.asset(
+          Assets.svg.radioProblem,
+          color: Theme.of(context).extension<StackColors>()!.accentColorRed,
+          width: size,
+          height: size,
+        );
+      case WalletSyncStatus.synced:
+        return SvgPicture.asset(
+          Assets.svg.radio,
+          color: Theme.of(context).extension<StackColors>()!.accentColorGreen,
+          width: size,
+          height: size,
+        );
+      case WalletSyncStatus.syncing:
+        return SvgPicture.asset(
+          Assets.svg.radioSyncing,
+          color: Theme.of(context).extension<StackColors>()!.accentColorYellow,
+          width: size,
+          height: size,
+        );
+    }
+  }
+
+  Widget _buildText(WalletSyncStatus status, BuildContext context) {
+    String label;
+    Color color;
+
+    switch (status) {
+      case WalletSyncStatus.unableToSync:
+        label = "Unable to sync";
+        color = Theme.of(context).extension<StackColors>()!.accentColorRed;
+        break;
+      case WalletSyncStatus.synced:
+        label = "Synchronised";
+        color = Theme.of(context).extension<StackColors>()!.accentColorGreen;
+        break;
+      case WalletSyncStatus.syncing:
+        label = "Synchronising";
+        color = Theme.of(context).extension<StackColors>()!.accentColorYellow;
+        break;
+    }
+
+    return Text(
+      label,
+      style: STextStyles.desktopMenuItemSelected(context).copyWith(
+        color: color,
+      ),
+    );
+  }
 
   @override
   Widget build(BuildContext context) {
     return GestureDetector(
+      onTap: () {
+        Navigator.of(context).pushNamed(
+          WalletNetworkSettingsView.routeName,
+          arguments: Tuple3(
+            walletId,
+            _currentSyncStatus,
+            _currentNodeStatus,
+          ),
+        );
+      },
       child: Container(
         color: Colors.transparent,
         child: Row(
           children: [
-            SvgPicture.asset(
-              Assets.svg.network,
-              width: 24,
-              height: 24,
-              color:
-                  Theme.of(context).extension<StackColors>()!.accentColorGreen,
-            ),
+            _buildNetworkIcon(_currentSyncStatus, context),
             const SizedBox(
               width: 6,
             ),
-            Text(
-              "Synchronised",
-              style: STextStyles.desktopMenuItemSelected(context),
-            )
+            _buildText(_currentSyncStatus, context),
           ],
         ),
       ),

From a92e4e24c0a121c9ccf0014549478283d1250cec Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 13:01:05 -0600
Subject: [PATCH 052/426] desktop in wallet exchange button

---
 .../wallet_view/desktop_wallet_view.dart      | 100 ++++++++++++++++--
 1 file changed, 94 insertions(+), 6 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 2bcb9eeb4..76650e2c0 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -4,6 +4,8 @@ import 'package:event_bus/event_bus.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
+import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
 import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart';
@@ -14,10 +16,12 @@ import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
 import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_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/exchange/change_now/change_now_exchange.dart';
 import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -27,6 +31,7 @@ import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:tuple/tuple.dart';
 
 /// [eventBus] should only be set during testing
@@ -91,6 +96,73 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
     }
   }
 
+  void _onExchangePressed(BuildContext context) async {
+    final managerProvider =
+        ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
+    unawaited(_cnLoadingService.loadAll(ref));
+
+    final coin = ref.read(managerProvider).coin;
+
+    if (coin == Coin.epicCash) {
+      await showDialog<void>(
+        context: context,
+        builder: (_) => const StackOkDialog(
+          title: "Exchange not available for Epic Cash",
+        ),
+      );
+    } else if (coin.name.endsWith("TestNet")) {
+      await showDialog<void>(
+        context: context,
+        builder: (_) => const StackOkDialog(
+          title: "Exchange not available for test net coins",
+        ),
+      );
+    } else {
+      ref.read(currentExchangeNameStateProvider.state).state =
+          ChangeNowExchange.exchangeName;
+      final walletId = ref.read(managerProvider).walletId;
+      ref.read(prefsChangeNotifierProvider).exchangeRateType =
+          ExchangeRateType.estimated;
+
+      ref.read(exchangeFormStateProvider).exchange = ref.read(exchangeProvider);
+      ref.read(exchangeFormStateProvider).exchangeType =
+          ExchangeRateType.estimated;
+
+      final currencies = ref
+          .read(availableChangeNowCurrenciesProvider)
+          .currencies
+          .where((element) =>
+              element.ticker.toLowerCase() == coin.ticker.toLowerCase());
+
+      if (currencies.isNotEmpty) {
+        ref.read(exchangeFormStateProvider).setCurrencies(
+              currencies.first,
+              ref
+                  .read(availableChangeNowCurrenciesProvider)
+                  .currencies
+                  .firstWhere(
+                    (element) =>
+                        element.ticker.toLowerCase() !=
+                        coin.ticker.toLowerCase(),
+                  ),
+            );
+      }
+
+      if (mounted) {
+        unawaited(
+          Navigator.of(context).pushNamed(
+            WalletInitiatedExchangeView.routeName,
+            arguments: Tuple3(
+              walletId,
+              coin,
+              _loadCNData,
+            ),
+          ),
+        );
+      }
+    }
+  }
+
   @override
   void initState() {
     walletId = widget.walletId;
@@ -207,17 +279,33 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                   const Spacer(),
                   SecondaryButton(
                     width: 180,
-                    height: 56,
+                    desktopMed: true,
                     onPressed: () {
-                      // todo: go to wallet initiated exchange
+                      _onExchangePressed(context);
                     },
                     label: "Exchange",
                     icon: Container(
-                      color: Colors.red,
-                      width: 20,
-                      height: 20,
+                      width: 24,
+                      height: 24,
+                      decoration: BoxDecoration(
+                        borderRadius: BorderRadius.circular(24),
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .buttonBackPrimary
+                            .withOpacity(0.2),
+                      ),
+                      child: Center(
+                        child: SvgPicture.asset(
+                          Assets.svg.arrowRotate2,
+                          width: 14,
+                          height: 14,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .buttonTextSecondary,
+                        ),
+                      ),
                     ),
-                  )
+                  ),
                 ],
               ),
             ),

From 934cdcc917b032af961e78d49012f3f784221244 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 13:26:55 -0600
Subject: [PATCH 053/426] WIP: desktop transactions list

---
 .../sub_widgets/transactions_list.dart        | 167 ++++++++++--------
 .../wallet_view/desktop_wallet_view.dart      |  28 ++-
 lib/widgets/trade_card.dart                   |   3 +-
 lib/widgets/transaction_card.dart             |  32 +++-
 4 files changed, 140 insertions(+), 90 deletions(-)

diff --git a/lib/pages/wallet_view/sub_widgets/transactions_list.dart b/lib/pages/wallet_view/sub_widgets/transactions_list.dart
index 2246882ab..d23d3082f 100644
--- a/lib/pages/wallet_view/sub_widgets/transactions_list.dart
+++ b/lib/pages/wallet_view/sub_widgets/transactions_list.dart
@@ -10,6 +10,7 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/trade_card.dart';
 import 'package:stackwallet/widgets/transaction_card.dart';
@@ -67,6 +68,65 @@ class _TransactionsListState extends ConsumerState<TransactionsList> {
     );
   }
 
+  Widget itemBuilder(
+      BuildContext context, Transaction tx, BorderRadius? radius) {
+    final matchingTrades = ref
+        .read(tradesServiceProvider)
+        .trades
+        .where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid);
+    if (tx.txType == "Sent" && matchingTrades.isNotEmpty) {
+      final trade = matchingTrades.first;
+      return Container(
+        decoration: BoxDecoration(
+          color: Theme.of(context).extension<StackColors>()!.popupBG,
+          borderRadius: radius,
+        ),
+        child: Column(
+          mainAxisSize: MainAxisSize.min,
+          children: [
+            TransactionCard(
+              // this may mess with combined firo transactions
+              key: Key(tx.toString()), //
+              transaction: tx,
+              walletId: widget.walletId,
+            ),
+            TradeCard(
+              // this may mess with combined firo transactions
+              key: Key(tx.toString() + trade.uuid), //
+              trade: trade,
+              onTap: () {
+                unawaited(
+                  Navigator.of(context).pushNamed(
+                    TradeDetailsView.routeName,
+                    arguments: Tuple4(
+                      trade.tradeId,
+                      tx,
+                      widget.walletId,
+                      ref.read(managerProvider).walletName,
+                    ),
+                  ),
+                );
+              },
+            )
+          ],
+        ),
+      );
+    } else {
+      return Container(
+        decoration: BoxDecoration(
+          color: Theme.of(context).extension<StackColors>()!.popupBG,
+          borderRadius: radius,
+        ),
+        child: TransactionCard(
+          // this may mess with combined firo transactions
+          key: Key(tx.toString()), //
+          transaction: tx,
+          walletId: widget.walletId,
+        ),
+      );
+    }
+  }
+
   @override
   void initState() {
     managerProvider = widget.managerProvider;
@@ -119,77 +179,42 @@ class _TransactionsListState extends ConsumerState<TransactionsList> {
                 unawaited(ref.read(managerProvider).refresh());
               }
             },
-            child: ListView.builder(
-              itemCount: list.length,
-              itemBuilder: (context, index) {
-                BorderRadius? radius;
-                if (index == list.length - 1) {
-                  radius = _borderRadiusLast;
-                } else if (index == 0) {
-                  radius = _borderRadiusFirst;
-                }
-                final tx = list[index];
-
-                final matchingTrades = ref
-                    .read(tradesServiceProvider)
-                    .trades
-                    .where((e) =>
-                        e.payInTxid == tx.txid || e.payOutTxid == tx.txid);
-                if (tx.txType == "Sent" && matchingTrades.isNotEmpty) {
-                  final trade = matchingTrades.first;
-                  return Container(
-                    decoration: BoxDecoration(
-                      color:
-                          Theme.of(context).extension<StackColors>()!.popupBG,
-                      borderRadius: radius,
-                    ),
-                    child: Column(
-                      mainAxisSize: MainAxisSize.min,
-                      children: [
-                        TransactionCard(
-                          // this may mess with combined firo transactions
-                          key: Key(tx.toString()), //
-                          transaction: tx,
-                          walletId: widget.walletId,
-                        ),
-                        TradeCard(
-                          // this may mess with combined firo transactions
-                          key: Key(tx.toString() + trade.uuid), //
-                          trade: trade,
-                          onTap: () {
-                            unawaited(
-                              Navigator.of(context).pushNamed(
-                                TradeDetailsView.routeName,
-                                arguments: Tuple4(
-                                  trade.tradeId,
-                                  tx,
-                                  widget.walletId,
-                                  ref.read(managerProvider).walletName,
-                                ),
-                              ),
-                            );
-                          },
-                        )
-                      ],
-                    ),
-                  );
-                } else {
-                  return Container(
-                    decoration: BoxDecoration(
-                      color:
-                          Theme.of(context).extension<StackColors>()!.popupBG,
-                      borderRadius: radius,
-                    ),
-                    child: TransactionCard(
-                      // this may mess with combined firo transactions
-                      key: Key(tx.toString()), //
-                      transaction: tx,
-                      walletId: widget.walletId,
-                    ),
-                  );
-                }
-              },
-            ),
+            child: Util.isDesktop
+                ? ListView.separated(
+                    itemBuilder: (context, index) {
+                      BorderRadius? radius;
+                      if (index == list.length - 1) {
+                        radius = _borderRadiusLast;
+                      } else if (index == 0) {
+                        radius = _borderRadiusFirst;
+                      }
+                      final tx = list[index];
+                      return itemBuilder(context, tx, radius);
+                    },
+                    separatorBuilder: (context, index) {
+                      return Container(
+                        width: double.infinity,
+                        height: 2,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .background,
+                      );
+                    },
+                    itemCount: list.length,
+                  )
+                : ListView.builder(
+                    itemCount: list.length,
+                    itemBuilder: (context, index) {
+                      BorderRadius? radius;
+                      if (index == list.length - 1) {
+                        radius = _borderRadiusLast;
+                      } else if (index == 0) {
+                        radius = _borderRadiusFirst;
+                      }
+                      final tx = list[index];
+                      return itemBuilder(context, tx, radius);
+                    },
+                  ),
           );
         }
       },
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 76650e2c0..baa91b3f8 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -7,6 +7,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
 import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
 import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
+import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart';
@@ -324,8 +325,10 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                   const SizedBox(
                     width: 16,
                   ),
-                  const Expanded(
-                    child: RecentDesktopTransactions(),
+                  Expanded(
+                    child: RecentDesktopTransactions(
+                      walletId: walletId,
+                    ),
                   ),
                 ],
               ),
@@ -543,15 +546,21 @@ class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
   }
 }
 
-class RecentDesktopTransactions extends StatefulWidget {
-  const RecentDesktopTransactions({Key? key}) : super(key: key);
+class RecentDesktopTransactions extends ConsumerStatefulWidget {
+  const RecentDesktopTransactions({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
 
   @override
-  State<RecentDesktopTransactions> createState() =>
+  ConsumerState<RecentDesktopTransactions> createState() =>
       _RecentDesktopTransactionsState();
 }
 
-class _RecentDesktopTransactionsState extends State<RecentDesktopTransactions> {
+class _RecentDesktopTransactionsState
+    extends ConsumerState<RecentDesktopTransactions> {
   @override
   Widget build(BuildContext context) {
     return Column(
@@ -579,9 +588,10 @@ class _RecentDesktopTransactionsState extends State<RecentDesktopTransactions> {
           height: 16,
         ),
         Expanded(
-          child: RoundedWhiteContainer(
-            padding: const EdgeInsets.all(0),
-            child: Container(),
+          child: TransactionsList(
+            managerProvider: ref.watch(walletsChangeNotifierProvider
+                .select((value) => value.getManagerProvider(widget.walletId))),
+            walletId: widget.walletId,
           ),
         ),
       ],
diff --git a/lib/widgets/trade_card.dart b/lib/widgets/trade_card.dart
index ba07b9576..0ac8e9346 100644
--- a/lib/widgets/trade_card.dart
+++ b/lib/widgets/trade_card.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/models/exchange/response_objects/trade.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class TradeCard extends ConsumerWidget {
@@ -84,7 +85,7 @@ class TradeCard extends ConsumerWidget {
                         style: STextStyles.itemSubtitle12(context),
                       ),
                       Text(
-                        "${Decimal.tryParse(trade.payInAmount) ?? "..."} ${trade.payInCurrency.toUpperCase()}",
+                        "${Util.isDesktop ? "-" : ""}${Decimal.tryParse(trade.payInAmount) ?? "..."} ${trade.payInCurrency.toUpperCase()}",
                         style: STextStyles.itemSubtitle12(context),
                       ),
                     ],
diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart
index cb737ae08..de0447684 100644
--- a/lib/widgets/transaction_card.dart
+++ b/lib/widgets/transaction_card.dart
@@ -13,6 +13,7 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
 import 'package:tuple/tuple.dart';
 
 class TransactionCard extends ConsumerStatefulWidget {
@@ -100,6 +101,17 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
             .select((value) => value.getPrice(coin)))
         .item1;
 
+    late final String prefix;
+    if (Util.isDesktop) {
+      if (_transaction.txType == "Sent") {
+        prefix = "-";
+      } else if (_transaction.txType == "Received") {
+        prefix = "+";
+      }
+    } else {
+      prefix = "";
+    }
+
     return Material(
       color: Theme.of(context).extension<StackColors>()!.popupBG,
       elevation: 0,
@@ -126,14 +138,16 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
               ));
               return;
             }
-            unawaited(Navigator.of(context).pushNamed(
-              TransactionDetailsView.routeName,
-              arguments: Tuple3(
-                _transaction,
-                coin,
-                walletId,
+            unawaited(
+              Navigator.of(context).pushNamed(
+                TransactionDetailsView.routeName,
+                arguments: Tuple3(
+                  _transaction,
+                  coin,
+                  walletId,
+                ),
               ),
-            ));
+            );
           },
           child: Padding(
             padding: const EdgeInsets.all(8),
@@ -176,7 +190,7 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
                                           ? (_transaction.amount ~/ 1000)
                                           : _transaction.amount;
                                   return Text(
-                                    "${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}",
+                                    "$prefix${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}",
                                     style:
                                         STextStyles.itemSubtitle12_600(context),
                                   );
@@ -223,7 +237,7 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
                                     }
 
                                     return Text(
-                                      "${Format.localizedStringAsFixed(
+                                      "$prefix${Format.localizedStringAsFixed(
                                         value: Format.satoshisToAmount(value) *
                                             price,
                                         locale: locale,

From be81625d2b5ecf1d7c2c8d93681c49538a7dc74c Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 14:23:55 -0600
Subject: [PATCH 054/426] WIP: desktop transactions filter

---
 .../all_transactions_view.dart                | 297 +++++++++++-------
 .../wallet_view/desktop_wallet_view.dart      |   6 +-
 2 files changed, 196 insertions(+), 107 deletions(-)

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 4194a7307..e3d7bf0b6 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -12,7 +12,11 @@ import 'package:stackwallet/utilities/assets.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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -21,8 +25,6 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
 import 'package:stackwallet/widgets/transaction_card.dart';
 import 'package:tuple/tuple.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class AllTransactionsView extends ConsumerStatefulWidget {
   const AllTransactionsView({
     Key? key,
@@ -166,123 +168,206 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: 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(
-          "Transactions",
-          style: STextStyles.navBarTitle(context),
-        ),
-        actions: [
-          Padding(
-            padding: const EdgeInsets.only(
-              top: 10,
-              bottom: 10,
-              right: 20,
-            ),
-            child: AspectRatio(
-              aspectRatio: 1,
-              child: AppBarIconButton(
-                key: const Key("transactionSearchFilterViewButton"),
-                size: 36,
-                shadows: const [],
-                color: Theme.of(context).extension<StackColors>()!.background,
-                icon: SvgPicture.asset(
-                  Assets.svg.filter,
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .accentColorDark,
-                  width: 20,
-                  height: 20,
-                ),
-                onPressed: () {
-                  Navigator.of(context).pushNamed(
-                    TransactionSearchFilterView.routeName,
-                    arguments: ref
-                        .read(walletsChangeNotifierProvider)
-                        .getManager(walletId)
-                        .coin,
-                  );
+    final isDesktop = Util.isDesktop;
+
+    return MasterScaffold(
+      background: Theme.of(context).extension<StackColors>()!.background,
+      isDesktop: isDesktop,
+      appBar: isDesktop
+          ? DesktopAppBar(
+              isCompactHeight: true,
+              background: Theme.of(context).extension<StackColors>()!.popupBG,
+              leading: Row(
+                children: [
+                  const SizedBox(
+                    width: 32,
+                  ),
+                  AppBarIconButton(
+                    size: 32,
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .textFieldDefaultBG,
+                    shadows: const [],
+                    icon: SvgPicture.asset(
+                      Assets.svg.arrowLeft,
+                      width: 18,
+                      height: 18,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .topNavIconPrimary,
+                    ),
+                    onPressed: Navigator.of(context).pop,
+                  ),
+                  const SizedBox(
+                    width: 12,
+                  ),
+                  Text(
+                    "Transactions",
+                    style: STextStyles.desktopH3(context),
+                  ),
+                ],
+              ),
+            )
+          : 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(
+                "Transactions",
+                style: STextStyles.navBarTitle(context),
+              ),
+              actions: [
+                Padding(
+                  padding: const EdgeInsets.only(
+                    top: 10,
+                    bottom: 10,
+                    right: 20,
+                  ),
+                  child: AspectRatio(
+                    aspectRatio: 1,
+                    child: AppBarIconButton(
+                      key: const Key("transactionSearchFilterViewButton"),
+                      size: 36,
+                      shadows: const [],
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .background,
+                      icon: SvgPicture.asset(
+                        Assets.svg.filter,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark,
+                        width: 20,
+                        height: 20,
+                      ),
+                      onPressed: () {
+                        Navigator.of(context).pushNamed(
+                          TransactionSearchFilterView.routeName,
+                          arguments: ref
+                              .read(walletsChangeNotifierProvider)
+                              .getManager(walletId)
+                              .coin,
+                        );
+                      },
+                    ),
+                  ),
+                ),
+              ],
             ),
-          ),
-        ],
-      ),
       body: Padding(
-        padding: const EdgeInsets.only(
-          left: 12,
-          top: 12,
-          right: 12,
+        padding: EdgeInsets.only(
+          left: isDesktop ? 20 : 12,
+          top: isDesktop ? 20 : 12,
+          right: isDesktop ? 20 : 12,
         ),
         child: Column(
           children: [
             Padding(
               padding: const EdgeInsets.all(4),
-              child: ClipRRect(
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius,
-                ),
-                child: TextField(
-                  autocorrect: Util.isDesktop ? false : true,
-                  enableSuggestions: Util.isDesktop ? false : true,
-                  controller: _searchController,
-                  focusNode: searchFieldFocusNode,
-                  onChanged: (value) {
-                    setState(() {
-                      _searchString = value;
-                    });
-                  },
-                  style: STextStyles.field(context),
-                  decoration: standardInputDecoration(
-                    "Search",
-                    searchFieldFocusNode,
-                    context,
-                  ).copyWith(
-                    prefixIcon: Padding(
-                      padding: const EdgeInsets.symmetric(
-                        horizontal: 10,
-                        vertical: 16,
+              child: Row(
+                children: [
+                  SizedBox(
+                    width: isDesktop ? 570 : null,
+                    child: ClipRRect(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
                       ),
-                      child: SvgPicture.asset(
-                        Assets.svg.search,
-                        width: 16,
-                        height: 16,
+                      child: TextField(
+                        autocorrect: !isDesktop,
+                        enableSuggestions: !isDesktop,
+                        controller: _searchController,
+                        focusNode: searchFieldFocusNode,
+                        onChanged: (value) {
+                          setState(() {
+                            _searchString = value;
+                          });
+                        },
+                        style: isDesktop
+                            ? STextStyles.desktopTextExtraSmall(context)
+                                .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textFieldActiveText,
+                                height: 1.8,
+                              )
+                            : STextStyles.field(context),
+                        decoration: standardInputDecoration(
+                          "Search",
+                          searchFieldFocusNode,
+                          context,
+                          desktopMed: true,
+                        ).copyWith(
+                          prefixIcon: Padding(
+                            padding: EdgeInsets.symmetric(
+                              horizontal: isDesktop ? 12 : 10,
+                              vertical: isDesktop ? 18 : 16,
+                            ),
+                            child: SvgPicture.asset(
+                              Assets.svg.search,
+                              width: isDesktop ? 20 : 16,
+                              height: isDesktop ? 20 : 16,
+                            ),
+                          ),
+                          suffixIcon: _searchController.text.isNotEmpty
+                              ? Padding(
+                                  padding: const EdgeInsets.only(right: 0),
+                                  child: UnconstrainedBox(
+                                    child: Row(
+                                      children: [
+                                        TextFieldIconButton(
+                                          child: const XIcon(),
+                                          onTap: () async {
+                                            setState(() {
+                                              _searchController.text = "";
+                                            });
+                                          },
+                                        ),
+                                      ],
+                                    ),
+                                  ),
+                                )
+                              : null,
+                        ),
                       ),
                     ),
-                    suffixIcon: _searchController.text.isNotEmpty
-                        ? Padding(
-                            padding: const EdgeInsets.only(right: 0),
-                            child: UnconstrainedBox(
-                              child: Row(
-                                children: [
-                                  TextFieldIconButton(
-                                    child: const XIcon(),
-                                    onTap: () async {
-                                      setState(() {
-                                        _searchController.text = "";
-                                      });
-                                    },
-                                  ),
-                                ],
-                              ),
-                            ),
-                          )
-                        : null,
                   ),
-                ),
+                  const SizedBox(
+                    width: 20,
+                  ),
+                  SecondaryButton(
+                    desktopMed: true,
+                    width: 200,
+                    label: "Filter",
+                    icon: SvgPicture.asset(
+                      Assets.svg.filter,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                      width: 20,
+                      height: 20,
+                    ),
+                    onPressed: () {
+                      Navigator.of(context).pushNamed(
+                        TransactionSearchFilterView.routeName,
+                        arguments: ref
+                            .read(walletsChangeNotifierProvider)
+                            .getManager(walletId)
+                            .coin,
+                      );
+                    },
+                  ),
+                ],
               ),
             ),
             const SizedBox(
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index baa91b3f8..9d0d9ed64 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -8,6 +8,7 @@ import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.
 import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
 import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
 import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart';
+import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart';
@@ -579,7 +580,10 @@ class _RecentDesktopTransactionsState
             BlueTextButton(
               text: "See all",
               onTap: () {
-                // todo: show all txns
+                Navigator.of(context).pushNamed(
+                  AllTransactionsView.routeName,
+                  arguments: widget.walletId,
+                );
               },
             ),
           ],

From ec7840419fa727f45fb98d0b63dfb4d5fc70b59d Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 15:23:31 -0600
Subject: [PATCH 055/426] desktop dialog mod to allow setting max size

---
 lib/widgets/desktop/desktop_dialog.dart | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/lib/widgets/desktop/desktop_dialog.dart b/lib/widgets/desktop/desktop_dialog.dart
index 5ada3a545..d11124ba6 100644
--- a/lib/widgets/desktop/desktop_dialog.dart
+++ b/lib/widgets/desktop/desktop_dialog.dart
@@ -2,9 +2,16 @@ import 'package:flutter/material.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
 class DesktopDialog extends StatelessWidget {
-  const DesktopDialog({Key? key, this.child}) : super(key: key);
+  const DesktopDialog({
+    Key? key,
+    this.child,
+    this.maxWidth = 641,
+    this.maxHeight = 474,
+  }) : super(key: key);
 
   final Widget? child;
+  final double maxWidth;
+  final double maxHeight;
 
   @override
   Widget build(BuildContext context) {
@@ -13,9 +20,9 @@ class DesktopDialog extends StatelessWidget {
       crossAxisAlignment: CrossAxisAlignment.center,
       children: [
         ConstrainedBox(
-          constraints: const BoxConstraints(
-            maxWidth: 641,
-            maxHeight: 474,
+          constraints: BoxConstraints(
+            maxWidth: maxWidth,
+            maxHeight: maxHeight,
           ),
           child: Material(
             borderRadius: BorderRadius.circular(

From cc0770b2a27fd9e1250c05652f6bf792ecf68464 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 27 Oct 2022 16:04:13 -0600
Subject: [PATCH 056/426] desktop tx search filter + various bugfixes

---
 .../all_transactions_view.dart                |   60 +-
 .../transaction_search_filter_view.dart       | 1228 ++++++++++-------
 .../wallet_view/desktop_wallet_view.dart      |    1 +
 lib/utilities/text_styles.dart                |   19 +
 4 files changed, 772 insertions(+), 536 deletions(-)

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 e3d7bf0b6..7122f5379 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -306,7 +306,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
                           "Search",
                           searchFieldFocusNode,
                           context,
-                          desktopMed: true,
+                          desktopMed: isDesktop,
                         ).copyWith(
                           prefixIcon: Padding(
                             padding: EdgeInsets.symmetric(
@@ -330,6 +330,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
                                           onTap: () async {
                                             setState(() {
                                               _searchController.text = "";
+                                              _searchString = "";
                                             });
                                           },
                                         ),
@@ -342,31 +343,45 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
                       ),
                     ),
                   ),
-                  const SizedBox(
-                    width: 20,
-                  ),
-                  SecondaryButton(
-                    desktopMed: true,
-                    width: 200,
-                    label: "Filter",
-                    icon: SvgPicture.asset(
-                      Assets.svg.filter,
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .accentColorDark,
+                  if (isDesktop)
+                    const SizedBox(
                       width: 20,
-                      height: 20,
                     ),
-                    onPressed: () {
-                      Navigator.of(context).pushNamed(
-                        TransactionSearchFilterView.routeName,
-                        arguments: ref
+                  if (isDesktop)
+                    SecondaryButton(
+                      desktopMed: isDesktop,
+                      width: 200,
+                      label: "Filter",
+                      icon: SvgPicture.asset(
+                        Assets.svg.filter,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark,
+                        width: 20,
+                        height: 20,
+                      ),
+                      onPressed: () {
+                        final coin = ref
                             .read(walletsChangeNotifierProvider)
                             .getManager(walletId)
-                            .coin,
-                      );
-                    },
-                  ),
+                            .coin;
+                        if (isDesktop) {
+                          showDialog<void>(
+                            context: context,
+                            builder: (context) {
+                              return TransactionSearchFilterView(
+                                coin: coin,
+                              );
+                            },
+                          );
+                        } else {
+                          Navigator.of(context).pushNamed(
+                            TransactionSearchFilterView.routeName,
+                            arguments: coin,
+                          );
+                        }
+                      },
+                    ),
                 ],
               ),
             ),
@@ -402,6 +417,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
 
                         final monthlyList = groupTransactionsByMonth(searched);
                         return ListView.builder(
+                          primary: isDesktop ? false : null,
                           itemCount: monthlyList.length,
                           itemBuilder: (_, index) {
                             final month = monthlyList[index];
diff --git a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
index f9932c672..7d18d4428 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
@@ -16,6 +16,10 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
@@ -43,6 +47,7 @@ class _TransactionSearchViewState
 
   bool _isActiveReceivedCheckbox = false;
   bool _isActiveSentCheckbox = false;
+  bool _isActiveTradeCheckbox = false;
 
   String _fromDateString = "";
   String _toDateString = "";
@@ -63,6 +68,9 @@ class _TransactionSearchViewState
       _selectedFromDate = filterState.from;
       _keywordTextEditingController.text = filterState.keyword;
 
+      _fromDateString = Format.formatDate(_selectedFromDate);
+      _toDateString = Format.formatDate(_selectedToDate);
+
       // TODO: Fix XMR (modify Format.funcs to take optional Coin parameter)
       // final amt = Format.satoshisToAmount(widget.coin == Coin.monero ? )
       String amount = "";
@@ -166,104 +174,113 @@ class _TransactionSearchViewState
   Widget _buildDateRangePicker() {
     const middleSeparatorPadding = 2.0;
     const middleSeparatorWidth = 12.0;
-    final width = (MediaQuery.of(context).size.width -
-            (middleSeparatorWidth +
-                (2 * middleSeparatorPadding) +
-                (2 * Constants.size.standardPadding))) /
-        2;
+    final isDesktop = Util.isDesktop;
+
+    final width = isDesktop
+        ? null
+        : (MediaQuery.of(context).size.width -
+                (middleSeparatorWidth +
+                    (2 * middleSeparatorPadding) +
+                    (2 * Constants.size.standardPadding))) /
+            2;
 
     return Row(
       mainAxisAlignment: MainAxisAlignment.spaceBetween,
       children: [
-        GestureDetector(
-          key: const Key("transactionSearchViewFromDatePickerKey"),
-          onTap: () async {
-            final color =
-                Theme.of(context).extension<StackColors>()!.accentColorDark;
-            final height = MediaQuery.of(context).size.height;
-            // check and hide keyboard
-            if (FocusScope.of(context).hasFocus) {
-              FocusScope.of(context).unfocus();
-              await Future<void>.delayed(const Duration(milliseconds: 125));
-            }
-
-            final date = await showRoundedDatePicker(
-              // This doesn't change statusbar color...
-              // background: CFColors.starryNight.withOpacity(0.8),
-              context: context,
-              initialDate: DateTime.now(),
-              height: height * 0.5,
-              theme: ThemeData(
-                primarySwatch: Util.createMaterialColor(
-                  color,
-                ),
-              ),
-              //TODO pick a better initial date
-              // 2007 chosen as that is just before bitcoin launched
-              firstDate: DateTime(2007),
-              lastDate: DateTime.now(),
-              borderRadius: Constants.size.circularBorderRadius * 2,
-
-              textPositiveButton: "SELECT",
-
-              styleDatePicker: _buildDatePickerStyle(),
-              styleYearPicker: _buildYearPickerStyle(),
-            );
-            if (date != null) {
-              _selectedFromDate = date;
-
-              // flag to adjust date so from date is always before to date
-              final flag = !_selectedFromDate.isBefore(_selectedToDate);
-              if (flag) {
-                _selectedToDate = DateTime.fromMillisecondsSinceEpoch(
-                    _selectedFromDate.millisecondsSinceEpoch);
+        Expanded(
+          child: GestureDetector(
+            key: const Key("transactionSearchViewFromDatePickerKey"),
+            onTap: () async {
+              final color =
+                  Theme.of(context).extension<StackColors>()!.accentColorDark;
+              final height = MediaQuery.of(context).size.height;
+              // check and hide keyboard
+              if (FocusScope.of(context).hasFocus) {
+                FocusScope.of(context).unfocus();
+                await Future<void>.delayed(const Duration(milliseconds: 125));
               }
 
-              setState(() {
+              final date = await showRoundedDatePicker(
+                // This doesn't change statusbar color...
+                // background: CFColors.starryNight.withOpacity(0.8),
+                context: context,
+                initialDate: DateTime.now(),
+                height: height * 0.5,
+                theme: ThemeData(
+                  primarySwatch: Util.createMaterialColor(
+                    color,
+                  ),
+                ),
+                //TODO pick a better initial date
+                // 2007 chosen as that is just before bitcoin launched
+                firstDate: DateTime(2007),
+                lastDate: DateTime.now(),
+                borderRadius: Constants.size.circularBorderRadius * 2,
+
+                textPositiveButton: "SELECT",
+
+                styleDatePicker: _buildDatePickerStyle(),
+                styleYearPicker: _buildYearPickerStyle(),
+              );
+              if (date != null) {
+                _selectedFromDate = date;
+
+                // flag to adjust date so from date is always before to date
+                final flag = !_selectedFromDate.isBefore(_selectedToDate);
                 if (flag) {
-                  _toDateString = Format.formatDate(_selectedToDate);
+                  _selectedToDate = DateTime.fromMillisecondsSinceEpoch(
+                      _selectedFromDate.millisecondsSinceEpoch);
                 }
-                _fromDateString = Format.formatDate(_selectedFromDate);
-              });
-            }
-          },
-          child: Container(
-            width: width,
-            decoration: BoxDecoration(
-              color: Theme.of(context)
-                  .extension<StackColors>()!
-                  .textFieldDefaultBG,
-              borderRadius:
-                  BorderRadius.circular(Constants.size.circularBorderRadius),
-              border: Border.all(
+
+                setState(() {
+                  if (flag) {
+                    _toDateString = Format.formatDate(_selectedToDate);
+                  }
+                  _fromDateString = Format.formatDate(_selectedFromDate);
+                });
+              }
+            },
+            child: Container(
+              width: width,
+              decoration: BoxDecoration(
                 color: Theme.of(context)
                     .extension<StackColors>()!
                     .textFieldDefaultBG,
-                width: 1,
+                borderRadius:
+                    BorderRadius.circular(Constants.size.circularBorderRadius),
+                border: Border.all(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldDefaultBG,
+                  width: 1,
+                ),
               ),
-            ),
-            child: Padding(
-              padding: const EdgeInsets.all(12),
-              child: Row(
-                children: [
-                  SvgPicture.asset(
-                    Assets.svg.calendar,
-                    height: 20,
-                    width: 20,
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .textSubtitle2,
-                  ),
-                  const SizedBox(
-                    width: 10,
-                  ),
-                  Align(
-                    alignment: Alignment.centerLeft,
-                    child: FittedBox(
-                      child: _dateFromText,
+              child: Padding(
+                padding: EdgeInsets.symmetric(
+                  horizontal: 12,
+                  vertical: isDesktop ? 17 : 12,
+                ),
+                child: Row(
+                  children: [
+                    SvgPicture.asset(
+                      Assets.svg.calendar,
+                      height: 20,
+                      width: 20,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textSubtitle2,
                     ),
-                  )
-                ],
+                    const SizedBox(
+                      width: 10,
+                    ),
+                    Align(
+                      alignment: Alignment.centerLeft,
+                      child: FittedBox(
+                        child: _dateFromText,
+                      ),
+                    )
+                  ],
+                ),
               ),
             ),
           ),
@@ -277,470 +294,653 @@ class _TransactionSearchViewState
             // color: CFColors.smoke,
           ),
         ),
-        GestureDetector(
-          key: const Key("transactionSearchViewToDatePickerKey"),
-          onTap: () async {
-            final color =
-                Theme.of(context).extension<StackColors>()!.accentColorDark;
-            final height = MediaQuery.of(context).size.height;
-            // check and hide keyboard
-            if (FocusScope.of(context).hasFocus) {
-              FocusScope.of(context).unfocus();
-              await Future<void>.delayed(const Duration(milliseconds: 125));
-            }
-
-            final date = await showRoundedDatePicker(
-              // This doesn't change statusbar color...
-              // background: CFColors.starryNight.withOpacity(0.8),
-              context: context,
-              height: height * 0.5,
-              theme: ThemeData(
-                primarySwatch: Util.createMaterialColor(
-                  color,
-                ),
-              ),
-              //TODO pick a better initial date
-              // 2007 chosen as that is just before bitcoin launched
-              initialDate: DateTime.now(),
-              firstDate: DateTime(2007),
-              lastDate: DateTime.now(),
-              borderRadius: Constants.size.circularBorderRadius * 2,
-
-              textPositiveButton: "SELECT",
-
-              styleDatePicker: _buildDatePickerStyle(),
-              styleYearPicker: _buildYearPickerStyle(),
-            );
-            if (date != null) {
-              _selectedToDate = date;
-
-              // flag to adjust date so from date is always before to date
-              final flag = !_selectedToDate.isAfter(_selectedFromDate);
-              if (flag) {
-                _selectedFromDate = DateTime.fromMillisecondsSinceEpoch(
-                    _selectedToDate.millisecondsSinceEpoch);
+        Expanded(
+          child: GestureDetector(
+            key: const Key("transactionSearchViewToDatePickerKey"),
+            onTap: () async {
+              final color =
+                  Theme.of(context).extension<StackColors>()!.accentColorDark;
+              final height = MediaQuery.of(context).size.height;
+              // check and hide keyboard
+              if (FocusScope.of(context).hasFocus) {
+                FocusScope.of(context).unfocus();
+                await Future<void>.delayed(const Duration(milliseconds: 125));
               }
 
-              setState(() {
+              final date = await showRoundedDatePicker(
+                // This doesn't change statusbar color...
+                // background: CFColors.starryNight.withOpacity(0.8),
+                context: context,
+                height: height * 0.5,
+                theme: ThemeData(
+                  primarySwatch: Util.createMaterialColor(
+                    color,
+                  ),
+                ),
+                //TODO pick a better initial date
+                // 2007 chosen as that is just before bitcoin launched
+                initialDate: DateTime.now(),
+                firstDate: DateTime(2007),
+                lastDate: DateTime.now(),
+                borderRadius: Constants.size.circularBorderRadius * 2,
+
+                textPositiveButton: "SELECT",
+
+                styleDatePicker: _buildDatePickerStyle(),
+                styleYearPicker: _buildYearPickerStyle(),
+              );
+              if (date != null) {
+                _selectedToDate = date;
+
+                // flag to adjust date so from date is always before to date
+                final flag = !_selectedToDate.isAfter(_selectedFromDate);
                 if (flag) {
-                  _fromDateString = Format.formatDate(_selectedFromDate);
+                  _selectedFromDate = DateTime.fromMillisecondsSinceEpoch(
+                      _selectedToDate.millisecondsSinceEpoch);
                 }
-                _toDateString = Format.formatDate(_selectedToDate);
-              });
-            }
-          },
-          child: Container(
-            width: width,
-            decoration: BoxDecoration(
-              color: Theme.of(context)
-                  .extension<StackColors>()!
-                  .textFieldDefaultBG,
-              borderRadius:
-                  BorderRadius.circular(Constants.size.circularBorderRadius),
-              border: Border.all(
+
+                setState(() {
+                  if (flag) {
+                    _fromDateString = Format.formatDate(_selectedFromDate);
+                  }
+                  _toDateString = Format.formatDate(_selectedToDate);
+                });
+              }
+            },
+            child: Container(
+              width: width,
+              decoration: BoxDecoration(
                 color: Theme.of(context)
                     .extension<StackColors>()!
                     .textFieldDefaultBG,
-                width: 1,
+                borderRadius:
+                    BorderRadius.circular(Constants.size.circularBorderRadius),
+                border: Border.all(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldDefaultBG,
+                  width: 1,
+                ),
               ),
-            ),
-            child: Padding(
-              padding: const EdgeInsets.all(12),
-              child: Row(
-                children: [
-                  SvgPicture.asset(
-                    Assets.svg.calendar,
-                    height: 20,
-                    width: 20,
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .textSubtitle2,
-                  ),
-                  const SizedBox(
-                    width: 10,
-                  ),
-                  Align(
-                    alignment: Alignment.centerLeft,
-                    child: FittedBox(
-                      child: _dateToText,
+              child: Padding(
+                padding: EdgeInsets.symmetric(
+                  horizontal: 12,
+                  vertical: isDesktop ? 17 : 12,
+                ),
+                child: Row(
+                  children: [
+                    SvgPicture.asset(
+                      Assets.svg.calendar,
+                      height: 20,
+                      width: 20,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textSubtitle2,
                     ),
-                  )
-                ],
+                    const SizedBox(
+                      width: 10,
+                    ),
+                    Align(
+                      alignment: Alignment.centerLeft,
+                      child: FittedBox(
+                        child: _dateToText,
+                      ),
+                    )
+                  ],
+                ),
               ),
             ),
           ),
         ),
+        if (isDesktop)
+          const SizedBox(
+            width: 24,
+          ),
       ],
     );
   }
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
+    if (Util.isDesktop) {
+      return DesktopDialog(
+        maxWidth: 576,
+        maxHeight: double.infinity,
+        child: Padding(
+          padding: const EdgeInsets.only(
+            left: 32,
+            bottom: 32,
+          ),
+          child: _buildContent(context),
+        ),
+      );
+    } else {
+      return Scaffold(
         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();
-            }
-          },
+        appBar: 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(
+            "Transactions filter",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Transactions filter",
-          style: STextStyles.navBarTitle(context),
+        body: Padding(
+          padding: EdgeInsets.symmetric(
+            horizontal: Constants.size.standardPadding,
+          ),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(minHeight: constraints.maxHeight),
+                  child: IntrinsicHeight(
+                    child: _buildContent(context),
+                  ),
+                ),
+              );
+            },
+          ),
         ),
-      ),
-      body: Padding(
-        padding: EdgeInsets.symmetric(
-          horizontal: Constants.size.standardPadding,
+      );
+    }
+  }
+
+  Widget _buildContent(BuildContext context) {
+    final isDesktop = Util.isDesktop;
+
+    return Column(
+      children: [
+        if (isDesktop)
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Text(
+                "Transaction filter",
+                style: STextStyles.desktopH3(context),
+                textAlign: TextAlign.center,
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+        SizedBox(
+          height: isDesktop ? 14 : 10,
         ),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(minHeight: constraints.maxHeight),
-                child: IntrinsicHeight(
-                  child: Column(
-                    children: [
-                      const SizedBox(
-                        height: 10,
-                      ),
-                      Align(
-                        alignment: Alignment.centerLeft,
-                        child: FittedBox(
-                          child: Text(
-                            "Transactions",
-                            style: STextStyles.smallMed12(context),
-                          ),
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      RoundedWhiteContainer(
-                        child: Column(
-                          crossAxisAlignment: CrossAxisAlignment.start,
-                          children: [
-                            Row(
-                              children: [
-                                GestureDetector(
-                                  onTap: () {
-                                    setState(() {
-                                      _isActiveSentCheckbox =
-                                          !_isActiveSentCheckbox;
-                                    });
-                                  },
-                                  child: Container(
-                                    color: Colors.transparent,
-                                    child: Row(
-                                      children: [
-                                        SizedBox(
-                                          height: 20,
-                                          width: 20,
-                                          child: Checkbox(
-                                            key: const Key(
-                                                "transactionSearchViewSentCheckboxKey"),
-                                            materialTapTargetSize:
-                                                MaterialTapTargetSize
-                                                    .shrinkWrap,
-                                            value: _isActiveSentCheckbox,
-                                            onChanged: (newValue) {
-                                              setState(() {
-                                                _isActiveSentCheckbox =
-                                                    newValue!;
-                                              });
-                                            },
-                                          ),
-                                        ),
-                                        const SizedBox(
-                                          width: 14,
-                                        ),
-                                        Align(
-                                          alignment: Alignment.centerLeft,
-                                          child: FittedBox(
-                                            child: Text(
-                                              "Sent",
-                                              style: STextStyles.itemSubtitle12(
-                                                  context),
-                                            ),
-                                          ),
-                                        )
-                                      ],
-                                    ),
-                                  ),
-                                ),
-                              ],
-                            ),
-                            const SizedBox(
-                              height: 10,
-                            ),
-                            Row(
-                              children: [
-                                GestureDetector(
-                                  onTap: () {
-                                    setState(() {
-                                      _isActiveReceivedCheckbox =
-                                          !_isActiveReceivedCheckbox;
-                                    });
-                                  },
-                                  child: Container(
-                                    color: Colors.transparent,
-                                    child: Row(
-                                      children: [
-                                        SizedBox(
-                                          height: 20,
-                                          width: 20,
-                                          child: Checkbox(
-                                            key: const Key(
-                                                "transactionSearchViewReceivedCheckboxKey"),
-                                            materialTapTargetSize:
-                                                MaterialTapTargetSize
-                                                    .shrinkWrap,
-                                            value: _isActiveReceivedCheckbox,
-                                            onChanged: (newValue) {
-                                              setState(() {
-                                                _isActiveReceivedCheckbox =
-                                                    newValue!;
-                                              });
-                                            },
-                                          ),
-                                        ),
-                                        const SizedBox(
-                                          width: 14,
-                                        ),
-                                        Align(
-                                          alignment: Alignment.centerLeft,
-                                          child: FittedBox(
-                                            child: Text(
-                                              "Received",
-                                              style: STextStyles.itemSubtitle12(
-                                                  context),
-                                            ),
-                                          ),
-                                        )
-                                      ],
-                                    ),
-                                  ),
-                                ),
-                              ],
-                            ),
-                          ],
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 24,
-                      ),
-                      Align(
-                        alignment: Alignment.centerLeft,
-                        child: FittedBox(
-                          child: Text(
-                            "Date",
-                            style: STextStyles.smallMed12(context),
-                          ),
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 8,
-                      ),
-                      _buildDateRangePicker(),
-                      const SizedBox(
-                        height: 24,
-                      ),
-                      Align(
-                        alignment: Alignment.centerLeft,
-                        child: FittedBox(
-                          child: Text(
-                            "Amount",
-                            style: STextStyles.smallMed12(context),
-                          ),
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 8,
-                      ),
-                      ClipRRect(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
-                        ),
-                        child: TextField(
-                          autocorrect: Util.isDesktop ? false : true,
-                          enableSuggestions: Util.isDesktop ? false : true,
-                          key: const Key("transactionSearchViewAmountFieldKey"),
-                          controller: _amountTextEditingController,
-                          focusNode: amountTextFieldFocusNode,
-                          onChanged: (_) => setState(() {}),
-                          keyboardType: const TextInputType.numberWithOptions(
-                            signed: false,
-                            decimal: true,
-                          ),
-                          inputFormatters: [
-                            // regex to validate a crypto amount with 8 decimal places
-                            TextInputFormatter.withFunction((oldValue,
-                                    newValue) =>
-                                RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
-                                        .hasMatch(newValue.text)
-                                    ? newValue
-                                    : oldValue),
-                          ],
-                          style: STextStyles.field(context),
-                          decoration: standardInputDecoration(
-                            "Enter ${widget.coin.ticker} amount...",
-                            keywordTextFieldFocusNode,
-                            context,
-                          ).copyWith(
-                            suffixIcon: _amountTextEditingController
-                                    .text.isNotEmpty
-                                ? Padding(
-                                    padding: const EdgeInsets.only(right: 0),
-                                    child: UnconstrainedBox(
-                                      child: Row(
-                                        children: [
-                                          TextFieldIconButton(
-                                            child: const XIcon(),
-                                            onTap: () async {
-                                              setState(() {
-                                                _amountTextEditingController
-                                                    .text = "";
-                                              });
-                                            },
-                                          ),
-                                        ],
-                                      ),
-                                    ),
-                                  )
-                                : null,
-                          ),
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 24,
-                      ),
-                      Align(
-                        alignment: Alignment.centerLeft,
-                        child: FittedBox(
-                          child: Text(
-                            "Keyword",
-                            style: STextStyles.smallMed12(context),
-                          ),
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 8,
-                      ),
-                      ClipRRect(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
-                        ),
-                        child: TextField(
-                          autocorrect: Util.isDesktop ? false : true,
-                          enableSuggestions: Util.isDesktop ? false : true,
-                          key:
-                              const Key("transactionSearchViewKeywordFieldKey"),
-                          controller: _keywordTextEditingController,
-                          focusNode: keywordTextFieldFocusNode,
-                          style: STextStyles.field(context),
-                          onChanged: (_) => setState(() {}),
-                          decoration: standardInputDecoration(
-                            "Type keyword...",
-                            keywordTextFieldFocusNode,
-                            context,
-                          ).copyWith(
-                            suffixIcon: _keywordTextEditingController
-                                    .text.isNotEmpty
-                                ? Padding(
-                                    padding: const EdgeInsets.only(right: 0),
-                                    child: UnconstrainedBox(
-                                      child: Row(
-                                        children: [
-                                          TextFieldIconButton(
-                                            child: const XIcon(),
-                                            onTap: () async {
-                                              setState(() {
-                                                _keywordTextEditingController
-                                                    .text = "";
-                                              });
-                                            },
-                                          ),
-                                        ],
-                                      ),
-                                    ),
-                                  )
-                                : null,
-                          ),
-                        ),
-                      ),
-                      const Spacer(),
-                      const SizedBox(
-                        height: 20,
-                      ),
-                      Row(
+        if (!isDesktop)
+          Align(
+            alignment: Alignment.centerLeft,
+            child: FittedBox(
+              child: Text(
+                "Transactions",
+                style: STextStyles.smallMed12(context),
+              ),
+            ),
+          ),
+        if (!isDesktop)
+          const SizedBox(
+            height: 12,
+          ),
+        RoundedWhiteContainer(
+          padding: EdgeInsets.all(isDesktop ? 0 : 12),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Row(
+                children: [
+                  GestureDetector(
+                    onTap: () {
+                      setState(() {
+                        _isActiveSentCheckbox = !_isActiveSentCheckbox;
+                      });
+                    },
+                    child: Container(
+                      color: Colors.transparent,
+                      child: Row(
                         children: [
-                          Expanded(
-                            child: SizedBox(
-                              height: 48,
-                              child: TextButton(
-                                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();
-                                  }
-                                },
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getSecondaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Cancel",
-                                  style: STextStyles.button(context).copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .accentColorDark),
-                                ),
-                              ),
+                          SizedBox(
+                            height: 20,
+                            width: 20,
+                            child: Checkbox(
+                              key: const Key(
+                                  "transactionSearchViewSentCheckboxKey"),
+                              materialTapTargetSize:
+                                  MaterialTapTargetSize.shrinkWrap,
+                              value: _isActiveSentCheckbox,
+                              onChanged: (newValue) {
+                                setState(() {
+                                  _isActiveSentCheckbox = newValue!;
+                                });
+                              },
                             ),
                           ),
                           const SizedBox(
-                            width: 16,
+                            width: 14,
                           ),
-                          Expanded(
-                            child: SizedBox(
-                              height: 48,
-                              child: TextButton(
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getPrimaryEnabledButtonColor(context),
-                                onPressed: () async {
-                                  _onApplyPressed();
-                                },
-                                child: Text(
-                                  "Save",
-                                  style: STextStyles.button(context),
-                                ),
+                          Align(
+                            alignment: Alignment.centerLeft,
+                            child: FittedBox(
+                              child: Column(
+                                children: [
+                                  Text(
+                                    "Sent",
+                                    style: isDesktop
+                                        ? STextStyles.desktopTextSmall(context)
+                                        : STextStyles.itemSubtitle12(context),
+                                  ),
+                                  if (isDesktop)
+                                    const SizedBox(
+                                      height: 4,
+                                    ),
+                                ],
                               ),
                             ),
-                          ),
+                          )
                         ],
                       ),
-                      const SizedBox(
-                        height: 20,
-                      ),
-                    ],
+                    ),
                   ),
-                ),
+                ],
               ),
-            );
-          },
+              SizedBox(
+                height: isDesktop ? 4 : 10,
+              ),
+              Row(
+                children: [
+                  GestureDetector(
+                    onTap: () {
+                      setState(() {
+                        _isActiveReceivedCheckbox = !_isActiveReceivedCheckbox;
+                      });
+                    },
+                    child: Container(
+                      color: Colors.transparent,
+                      child: Row(
+                        children: [
+                          SizedBox(
+                            height: 20,
+                            width: 20,
+                            child: Checkbox(
+                              key: const Key(
+                                  "transactionSearchViewReceivedCheckboxKey"),
+                              materialTapTargetSize:
+                                  MaterialTapTargetSize.shrinkWrap,
+                              value: _isActiveReceivedCheckbox,
+                              onChanged: (newValue) {
+                                setState(() {
+                                  _isActiveReceivedCheckbox = newValue!;
+                                });
+                              },
+                            ),
+                          ),
+                          const SizedBox(
+                            width: 14,
+                          ),
+                          Align(
+                            alignment: Alignment.centerLeft,
+                            child: FittedBox(
+                              child: Column(
+                                children: [
+                                  Text(
+                                    "Received",
+                                    style: isDesktop
+                                        ? STextStyles.desktopTextSmall(context)
+                                        : STextStyles.itemSubtitle12(context),
+                                  ),
+                                  if (isDesktop)
+                                    const SizedBox(
+                                      height: 4,
+                                    ),
+                                ],
+                              ),
+                            ),
+                          )
+                        ],
+                      ),
+                    ),
+                  ),
+                ],
+              ),
+              SizedBox(
+                height: isDesktop ? 4 : 10,
+              ),
+              Row(
+                children: [
+                  GestureDetector(
+                    onTap: () {
+                      setState(() {
+                        _isActiveTradeCheckbox = !_isActiveTradeCheckbox;
+                      });
+                    },
+                    child: Container(
+                      color: Colors.transparent,
+                      child: Row(
+                        children: [
+                          SizedBox(
+                            height: 20,
+                            width: 20,
+                            child: Checkbox(
+                              key: const Key(
+                                  "transactionSearchViewSentCheckboxKey"),
+                              materialTapTargetSize:
+                                  MaterialTapTargetSize.shrinkWrap,
+                              value: _isActiveTradeCheckbox,
+                              onChanged: (newValue) {
+                                setState(() {
+                                  _isActiveTradeCheckbox = newValue!;
+                                });
+                              },
+                            ),
+                          ),
+                          const SizedBox(
+                            width: 14,
+                          ),
+                          Align(
+                            alignment: Alignment.centerLeft,
+                            child: FittedBox(
+                              child: Column(
+                                children: [
+                                  Text(
+                                    "Trades",
+                                    style: isDesktop
+                                        ? STextStyles.desktopTextSmall(context)
+                                        : STextStyles.itemSubtitle12(context),
+                                  ),
+                                  if (isDesktop)
+                                    const SizedBox(
+                                      height: 4,
+                                    ),
+                                ],
+                              ),
+                            ),
+                          )
+                        ],
+                      ),
+                    ),
+                  ),
+                ],
+              ),
+            ],
+          ),
         ),
-      ),
+        SizedBox(
+          height: isDesktop ? 32 : 24,
+        ),
+        Align(
+          alignment: Alignment.centerLeft,
+          child: FittedBox(
+            child: Text(
+              "Date",
+              style: isDesktop
+                  ? STextStyles.labelExtraExtraSmall(context)
+                  : STextStyles.smallMed12(context),
+            ),
+          ),
+        ),
+        SizedBox(
+          height: isDesktop ? 10 : 8,
+        ),
+        _buildDateRangePicker(),
+        SizedBox(
+          height: isDesktop ? 32 : 24,
+        ),
+        Align(
+          alignment: Alignment.centerLeft,
+          child: FittedBox(
+            child: Text(
+              "Amount",
+              style: isDesktop
+                  ? STextStyles.labelExtraExtraSmall(context)
+                  : STextStyles.smallMed12(context),
+            ),
+          ),
+        ),
+        SizedBox(
+          height: isDesktop ? 10 : 8,
+        ),
+        Padding(
+          padding: EdgeInsets.only(right: isDesktop ? 32 : 0),
+          child: ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
+              key: const Key("transactionSearchViewAmountFieldKey"),
+              controller: _amountTextEditingController,
+              focusNode: amountTextFieldFocusNode,
+              onChanged: (_) => setState(() {}),
+              keyboardType: const TextInputType.numberWithOptions(
+                signed: false,
+                decimal: true,
+              ),
+              inputFormatters: [
+                // regex to validate a crypto amount with 8 decimal places
+                TextInputFormatter.withFunction((oldValue, newValue) =>
+                    RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
+                            .hasMatch(newValue.text)
+                        ? newValue
+                        : oldValue),
+              ],
+              style: isDesktop
+                  ? STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color:
+                          Theme.of(context).extension<StackColors>()!.textDark,
+                      height: 1.8,
+                    )
+                  : STextStyles.field(context),
+              decoration: standardInputDecoration(
+                "Enter ${widget.coin.ticker} amount...",
+                keywordTextFieldFocusNode,
+                context,
+                desktopMed: isDesktop,
+              ).copyWith(
+                contentPadding: isDesktop
+                    ? const EdgeInsets.symmetric(
+                        vertical: 10,
+                        horizontal: 16,
+                      )
+                    : null,
+                suffixIcon: _amountTextEditingController.text.isNotEmpty
+                    ? Padding(
+                        padding: const EdgeInsets.only(right: 0),
+                        child: UnconstrainedBox(
+                          child: Row(
+                            children: [
+                              TextFieldIconButton(
+                                child: const XIcon(),
+                                onTap: () async {
+                                  setState(() {
+                                    _amountTextEditingController.text = "";
+                                  });
+                                },
+                              ),
+                            ],
+                          ),
+                        ),
+                      )
+                    : null,
+              ),
+            ),
+          ),
+        ),
+        SizedBox(
+          height: isDesktop ? 32 : 24,
+        ),
+        Align(
+          alignment: Alignment.centerLeft,
+          child: FittedBox(
+            child: Text(
+              "Keyword",
+              style: isDesktop
+                  ? STextStyles.labelExtraExtraSmall(context)
+                  : STextStyles.smallMed12(context),
+            ),
+          ),
+        ),
+        SizedBox(
+          height: isDesktop ? 10 : 8,
+        ),
+        Padding(
+          padding: EdgeInsets.only(right: isDesktop ? 32 : 0),
+          child: ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
+              key: const Key("transactionSearchViewKeywordFieldKey"),
+              controller: _keywordTextEditingController,
+              focusNode: keywordTextFieldFocusNode,
+              style: isDesktop
+                  ? STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color:
+                          Theme.of(context).extension<StackColors>()!.textDark,
+                      height: 1.8,
+                    )
+                  : STextStyles.field(context),
+              onChanged: (_) => setState(() {}),
+              decoration: standardInputDecoration(
+                "Type keyword...",
+                keywordTextFieldFocusNode,
+                context,
+                desktopMed: isDesktop,
+              ).copyWith(
+                contentPadding: isDesktop
+                    ? const EdgeInsets.symmetric(
+                        vertical: 10,
+                        horizontal: 16,
+                      )
+                    : null,
+                suffixIcon: _keywordTextEditingController.text.isNotEmpty
+                    ? Padding(
+                        padding: const EdgeInsets.only(right: 0),
+                        child: UnconstrainedBox(
+                          child: Row(
+                            children: [
+                              TextFieldIconButton(
+                                child: const XIcon(),
+                                onTap: () async {
+                                  setState(() {
+                                    _keywordTextEditingController.text = "";
+                                  });
+                                },
+                              ),
+                            ],
+                          ),
+                        ),
+                      )
+                    : null,
+              ),
+            ),
+          ),
+        ),
+        if (!isDesktop) const Spacer(),
+        SizedBox(
+          height: isDesktop ? 32 : 20,
+        ),
+        Row(
+          children: [
+            Expanded(
+              child: SecondaryButton(
+                label: "Cancel",
+                desktopMed: isDesktop,
+                onPressed: () async {
+                  if (!isDesktop) {
+                    if (FocusScope.of(context).hasFocus) {
+                      FocusScope.of(context).unfocus();
+                      await Future<void>.delayed(
+                        const Duration(
+                          milliseconds: 75,
+                        ),
+                      );
+                    }
+                  }
+                  if (mounted) {
+                    Navigator.of(context).pop();
+                  }
+                },
+              ),
+            ),
+            // Expanded(
+            //   child: SizedBox(
+            //     height: 48,
+            //     child: TextButton(
+            //       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();
+            //         }
+            //       },
+            //       style: Theme.of(context)
+            //           .extension<StackColors>()!
+            //           .getSecondaryEnabledButtonColor(context),
+            //       child: Text(
+            //         "Cancel",
+            //         style: STextStyles.button(context).copyWith(
+            //             color: Theme.of(context)
+            //                 .extension<StackColors>()!
+            //                 .accentColorDark),
+            //       ),
+            //     ),
+            //   ),
+            // ),
+            const SizedBox(
+              width: 16,
+            ),
+            Expanded(
+              child: PrimaryButton(
+                desktopMed: isDesktop,
+                onPressed: () async {
+                  await _onApplyPressed();
+                },
+                label: "Save",
+              ),
+            ),
+            // Expanded(
+            //   child: SizedBox(
+            //     height: 48,
+            //     child: TextButton(
+            //       style: Theme.of(context)
+            //           .extension<StackColors>()!
+            //           .getPrimaryEnabledButtonColor(context),
+            //       onPressed: () async {
+            //         await _onApplyPressed();
+            //       },
+            //       child: Text(
+            //         "Save",
+            //         style: STextStyles.button(context),
+            //       ),
+            //     ),
+            //   ),
+            // ),
+            if (isDesktop)
+              const SizedBox(
+                width: 32,
+              ),
+          ],
+        ),
+        if (!isDesktop)
+          const SizedBox(
+            height: 20,
+          ),
+      ],
     );
   }
 
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 9d0d9ed64..35b63174c 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -359,6 +359,7 @@ class _MyWalletState extends State<MyWallet> {
   @override
   Widget build(BuildContext context) {
     return ListView(
+      primary: false,
       children: [
         Text(
           "My wallet",
diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart
index 82e2ad349..b583dba98 100644
--- a/lib/utilities/text_styles.dart
+++ b/lib/utilities/text_styles.dart
@@ -228,6 +228,25 @@ class STextStyles {
     }
   }
 
+  static TextStyle labelExtraExtraSmall(BuildContext context) {
+    switch (_theme(context).themeType) {
+      case ThemeType.light:
+        return GoogleFonts.inter(
+          color: _theme(context).textFieldActiveSearchIconRight,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+          height: 14 / 14,
+        );
+      case ThemeType.dark:
+        return GoogleFonts.inter(
+          color: _theme(context).textFieldActiveSearchIconRight,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+          height: 14 / 14,
+        );
+    }
+  }
+
   static TextStyle label700(BuildContext context) {
     switch (_theme(context).themeType) {
       case ThemeType.light:

From 4c4df1b618f03584c1101e3e7816d4d4fea262a4 Mon Sep 17 00:00:00 2001
From: Marco <marco@cypherstack.com>
Date: Thu, 27 Oct 2022 17:24:14 -0600
Subject: [PATCH 057/426] before changes for litecoin

---
 .../coins/litecoin/litecoin_wallet.dart       | 3796 +++++++++++++++++
 1 file changed, 3796 insertions(+)
 create mode 100644 lib/services/coins/litecoin/litecoin_wallet.dart

diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart
new file mode 100644
index 000000000..da3bdfed0
--- /dev/null
+++ b/lib/services/coins/litecoin/litecoin_wallet.dart
@@ -0,0 +1,3796 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:bech32/bech32.dart';
+import 'package:bip32/bip32.dart' as bip32;
+import 'package:bip39/bip39.dart' as bip39;
+import 'package:bitcoindart/bitcoindart.dart';
+import 'package:bs58check/bs58check.dart' as bs58check;
+import 'package:crypto/crypto.dart';
+import 'package:decimal/decimal.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:http/http.dart';
+import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
+import 'package:stackwallet/electrumx_rpc/electrumx.dart';
+import 'package:stackwallet/hive/db.dart';
+import 'package:stackwallet/models/models.dart' as models;
+import 'package:stackwallet/models/paymint/fee_object_model.dart';
+import 'package:stackwallet/models/paymint/transactions_model.dart';
+import 'package:stackwallet/models/paymint/utxo_model.dart';
+import 'package:stackwallet/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/node_service.dart';
+import 'package:stackwallet/services/notifications_api.dart';
+import 'package:stackwallet/services/price.dart';
+import 'package:stackwallet/services/transaction_notification_tracker.dart';
+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/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/prefs.dart';
+import 'package:tuple/tuple.dart';
+import 'package:uuid/uuid.dart';
+
+const int MINIMUM_CONFIRMATIONS = 1;
+const int DUST_LIMIT = 294;
+
+const String GENESIS_HASH_MAINNET =
+    "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f";
+const String GENESIS_HASH_TESTNET =
+    "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943";
+
+enum DerivePathType { bip44, bip49, bip84 }
+
+bip32.BIP32 getBip32Node(
+  int chain,
+  int index,
+  String mnemonic,
+  NetworkType network,
+  DerivePathType derivePathType,
+) {
+  final root = getBip32Root(mnemonic, network);
+
+  final node = getBip32NodeFromRoot(chain, index, root, derivePathType);
+  return node;
+}
+
+/// wrapper for compute()
+bip32.BIP32 getBip32NodeWrapper(
+  Tuple5<int, int, String, NetworkType, DerivePathType> args,
+) {
+  return getBip32Node(
+    args.item1,
+    args.item2,
+    args.item3,
+    args.item4,
+    args.item5,
+  );
+}
+
+bip32.BIP32 getBip32NodeFromRoot(
+  int chain,
+  int index,
+  bip32.BIP32 root,
+  DerivePathType derivePathType,
+) {
+  String coinType;
+  switch (root.network.wif) {
+    case 0x80: // btc mainnet wif
+      coinType = "0"; // btc mainnet
+      break;
+    case 0xef: // btc testnet wif
+      coinType = "1"; // btc testnet
+      break;
+    default:
+      throw Exception("Invalid Bitcoin network type used!");
+  }
+  switch (derivePathType) {
+    case DerivePathType.bip44:
+      return root.derivePath("m/44'/$coinType'/0'/$chain/$index");
+    case DerivePathType.bip49:
+      return root.derivePath("m/49'/$coinType'/0'/$chain/$index");
+    case DerivePathType.bip84:
+      return root.derivePath("m/84'/$coinType'/0'/$chain/$index");
+    default:
+      throw Exception("DerivePathType must not be null.");
+  }
+}
+
+/// wrapper for compute()
+bip32.BIP32 getBip32NodeFromRootWrapper(
+  Tuple4<int, int, bip32.BIP32, DerivePathType> args,
+) {
+  return getBip32NodeFromRoot(
+    args.item1,
+    args.item2,
+    args.item3,
+    args.item4,
+  );
+}
+
+bip32.BIP32 getBip32Root(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;
+}
+
+/// wrapper for compute()
+bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) {
+  return getBip32Root(args.item1, args.item2);
+}
+
+class BitcoinWallet extends CoinServiceAPI {
+  static const integrationTestFlag =
+      bool.fromEnvironment("IS_INTEGRATION_TEST");
+
+  final _prefs = Prefs.instance;
+
+  Timer? timer;
+  late Coin _coin;
+
+  late final TransactionNotificationTracker txTracker;
+
+  NetworkType get _network {
+    switch (coin) {
+      case Coin.bitcoin:
+        return bitcoin;
+      case Coin.bitcoinTestNet:
+        return testnet;
+      default:
+        throw Exception("Invalid network type!");
+    }
+  }
+
+  List<UtxoObject> outputsList = [];
+
+  @override
+  set isFavorite(bool markFavorite) {
+    DB.instance.put<dynamic>(
+        boxName: walletId, key: "isFavorite", value: markFavorite);
+  }
+
+  @override
+  bool get isFavorite {
+    try {
+      return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
+          as bool;
+    } catch (e, s) {
+      Logging.instance
+          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  @override
+  Coin get coin => _coin;
+
+  @override
+  Future<List<String>> get allOwnAddresses =>
+      _allOwnAddresses ??= _fetchAllOwnAddresses();
+  Future<List<String>>? _allOwnAddresses;
+
+  Future<UtxoData>? _utxoData;
+  Future<UtxoData> get utxoData => _utxoData ??= _fetchUtxoData();
+
+  @override
+  Future<List<UtxoObject>> get unspentOutputs async =>
+      (await utxoData).unspentOutputArray;
+
+  @override
+  Future<Decimal> get availableBalance async {
+    final data = await utxoData;
+    return Format.satoshisToAmount(
+        data.satoshiBalance - data.satoshiBalanceUnconfirmed);
+  }
+
+  @override
+  Future<Decimal> get pendingBalance async {
+    final data = await utxoData;
+    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
+  }
+
+  @override
+  Future<Decimal> get balanceMinusMaxFee async =>
+      (await availableBalance) -
+      (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
+          .toDecimal();
+
+  @override
+  Future<Decimal> get totalBalance async {
+    if (!isActive) {
+      final totalBalance = DB.instance
+          .get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
+      if (totalBalance == null) {
+        final data = await utxoData;
+        return Format.satoshisToAmount(data.satoshiBalance);
+      } else {
+        return Format.satoshisToAmount(totalBalance);
+      }
+    }
+    final data = await utxoData;
+    return Format.satoshisToAmount(data.satoshiBalance);
+  }
+
+  @override
+  Future<String> get currentReceivingAddress => _currentReceivingAddress ??=
+      _getCurrentAddressForChain(0, DerivePathType.bip84);
+  Future<String>? _currentReceivingAddress;
+
+  Future<String> get currentLegacyReceivingAddress =>
+      _currentReceivingAddressP2PKH ??=
+          _getCurrentAddressForChain(0, DerivePathType.bip44);
+  Future<String>? _currentReceivingAddressP2PKH;
+
+  Future<String> get currentReceivingAddressP2SH =>
+      _currentReceivingAddressP2SH ??=
+          _getCurrentAddressForChain(0, DerivePathType.bip49);
+  Future<String>? _currentReceivingAddressP2SH;
+
+  @override
+  Future<void> exit() async {
+    _hasCalledExit = true;
+    timer?.cancel();
+    timer = null;
+    stopNetworkAlivePinging();
+  }
+
+  bool _hasCalledExit = false;
+
+  @override
+  bool get hasCalledExit => _hasCalledExit;
+
+  @override
+  Future<FeeObject> get fees => _feeObject ??= _getFees();
+  Future<FeeObject>? _feeObject;
+
+  @override
+  Future<int> get maxFee async {
+    final fee = (await fees).fast as String;
+    final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin);
+    return satsFee.floor().toBigInt().toInt();
+  }
+
+  @override
+  Future<List<String>> get mnemonic => _getMnemonicList();
+
+  Future<int> get chainHeight async {
+    try {
+      final result = await _electrumXClient.getBlockHeadTip();
+      return result["height"] as int;
+    } catch (e, s) {
+      Logging.instance.log("Exception caught in chainHeight: $e\n$s",
+          level: LogLevel.Error);
+      return -1;
+    }
+  }
+
+  int get storedChainHeight {
+    final storedHeight = DB.instance
+        .get<dynamic>(boxName: walletId, key: "storedChainHeight") as int?;
+    return storedHeight ?? 0;
+  }
+
+  Future<void> updateStoredChainHeight({required int newHeight}) async {
+    await DB.instance.put<dynamic>(
+        boxName: walletId, key: "storedChainHeight", value: newHeight);
+  }
+
+  DerivePathType addressType({required String address}) {
+    Uint8List? decodeBase58;
+    Segwit? decodeBech32;
+    try {
+      decodeBase58 = bs58check.decode(address);
+    } catch (err) {
+      // Base58check decode fail
+    }
+    if (decodeBase58 != null) {
+      if (decodeBase58[0] == _network.pubKeyHash) {
+        // P2PKH
+        return DerivePathType.bip44;
+      }
+      if (decodeBase58[0] == _network.scriptHash) {
+        // P2SH
+        return DerivePathType.bip49;
+      }
+      throw ArgumentError('Invalid version or Network mismatch');
+    } else {
+      try {
+        decodeBech32 = segwit.decode(address);
+      } catch (err) {
+        // Bech32 decode fail
+      }
+      if (_network.bech32 != decodeBech32!.hrp) {
+        throw ArgumentError('Invalid prefix or Network mismatch');
+      }
+      if (decodeBech32.version != 0) {
+        throw ArgumentError('Invalid address version');
+      }
+      // P2WPKH
+      return DerivePathType.bip84;
+    }
+  }
+
+  bool longMutex = false;
+
+  @override
+  Future<void> recoverFromMnemonic({
+    required String mnemonic,
+    required int maxUnusedAddressGap,
+    required int maxNumberOfIndexesToCheck,
+    required int height,
+  }) async {
+    longMutex = true;
+    final start = DateTime.now();
+    try {
+      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.bitcoin:
+            if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
+              throw Exception("genesis hash does not match main net!");
+            }
+            break;
+          case Coin.bitcoinTestNet:
+            if (features['genesis_hash'] != GENESIS_HASH_TESTNET) {
+              throw Exception("genesis hash does not match test net!");
+            }
+            break;
+          default:
+            throw Exception(
+                "Attempted to generate a BitcoinWallet using a non bitcoin coin type: ${coin.name}");
+        }
+        // if (_networkType == BasicNetworkType.main) {
+        //   if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
+        //     throw Exception("genesis hash does not match main net!");
+        //   }
+        // } else if (_networkType == BasicNetworkType.test) {
+        //   if (features['genesis_hash'] != GENESIS_HASH_TESTNET) {
+        //     throw Exception("genesis hash does not match test net!");
+        //   }
+        // }
+      }
+      // check to make sure we aren't overwriting a mnemonic
+      // this should never fail
+      if ((await _secureStore.read(key: '${_walletId}_mnemonic')) != null) {
+        longMutex = false;
+        throw Exception("Attempted to overwrite mnemonic on restore!");
+      }
+      await _secureStore.write(
+          key: '${_walletId}_mnemonic', value: mnemonic.trim());
+      await _recoverWalletFromBIP32SeedPhrase(
+        mnemonic: mnemonic.trim(),
+        maxUnusedAddressGap: maxUnusedAddressGap,
+        maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck,
+      );
+    } catch (e, s) {
+      Logging.instance.log(
+          "Exception rethrown from recoverFromMnemonic(): $e\n$s",
+          level: LogLevel.Error);
+      longMutex = false;
+      rethrow;
+    }
+    longMutex = false;
+
+    final end = DateTime.now();
+    Logging.instance.log(
+        "$walletName recovery time: ${end.difference(start).inMilliseconds} millis",
+        level: LogLevel.Info);
+  }
+
+  Future<Map<String, dynamic>> _checkGaps(
+      int maxNumberOfIndexesToCheck,
+      int maxUnusedAddressGap,
+      int txCountBatchSize,
+      bip32.BIP32 root,
+      DerivePathType type,
+      int account) async {
+    List<String> addressArray = [];
+    int returningIndex = -1;
+    Map<String, Map<String, String>> derivations = {};
+    int gapCounter = 0;
+    for (int index = 0;
+        index < maxNumberOfIndexesToCheck && gapCounter < maxUnusedAddressGap;
+        index += txCountBatchSize) {
+      List<String> iterationsAddressArray = [];
+      Logging.instance.log(
+          "index: $index, \t GapCounter $account ${type.name}: $gapCounter",
+          level: LogLevel.Info);
+
+      final _id = "k_$index";
+      Map<String, String> txCountCallArgs = {};
+      final Map<String, dynamic> receivingNodes = {};
+
+      for (int j = 0; j < txCountBatchSize; j++) {
+        final node = await compute(
+          getBip32NodeFromRootWrapper,
+          Tuple4(
+            account,
+            index + j,
+            root,
+            type,
+          ),
+        );
+        String? address;
+        switch (type) {
+          case DerivePathType.bip44:
+            address = P2PKH(
+                    data: PaymentData(pubkey: node.publicKey),
+                    network: _network)
+                .data
+                .address!;
+            break;
+          case DerivePathType.bip49:
+            address = P2SH(
+                    data: PaymentData(
+                        redeem: P2WPKH(
+                                data: PaymentData(pubkey: node.publicKey),
+                                network: _network)
+                            .data),
+                    network: _network)
+                .data
+                .address!;
+            break;
+          case DerivePathType.bip84:
+            address = P2WPKH(
+                    network: _network,
+                    data: PaymentData(pubkey: node.publicKey))
+                .data
+                .address!;
+            break;
+          default:
+            throw Exception("No Path type $type exists");
+        }
+        receivingNodes.addAll({
+          "${_id}_$j": {
+            "node": node,
+            "address": address,
+          }
+        });
+        txCountCallArgs.addAll({
+          "${_id}_$j": address,
+        });
+      }
+
+      // get address tx counts
+      final counts = await _getBatchTxCount(addresses: txCountCallArgs);
+
+      // check and add appropriate addresses
+      for (int k = 0; k < txCountBatchSize; k++) {
+        int count = counts["${_id}_$k"]!;
+        if (count > 0) {
+          final node = receivingNodes["${_id}_$k"];
+          // add address to array
+          addressArray.add(node["address"] as String);
+          iterationsAddressArray.add(node["address"] as String);
+          // set current index
+          returningIndex = index + k;
+          // reset counter
+          gapCounter = 0;
+          // add info to derivations
+          derivations[node["address"] as String] = {
+            "pubKey": Format.uint8listToString(
+                (node["node"] as bip32.BIP32).publicKey),
+            "wif": (node["node"] as bip32.BIP32).toWIF(),
+          };
+        }
+
+        // increase counter when no tx history found
+        if (count == 0) {
+          gapCounter++;
+        }
+      }
+      // cache all the transactions while waiting for the current function to finish.
+      unawaited(getTransactionCacheEarly(iterationsAddressArray));
+    }
+    return {
+      "addressArray": addressArray,
+      "index": returningIndex,
+      "derivations": derivations
+    };
+  }
+
+  Future<void> getTransactionCacheEarly(List<String> allAddresses) async {
+    try {
+      final List<Map<String, dynamic>> allTxHashes =
+          await _fetchHistory(allAddresses);
+      for (final txHash in allTxHashes) {
+        try {
+          unawaited(cachedElectrumXClient.getTransaction(
+            txHash: txHash["tx_hash"] as String,
+            verbose: true,
+            coin: coin,
+          ));
+        } catch (e) {
+          continue;
+        }
+      }
+    } catch (e) {
+      //
+    }
+  }
+
+  Future<void> _recoverWalletFromBIP32SeedPhrase({
+    required String mnemonic,
+    int maxUnusedAddressGap = 20,
+    int maxNumberOfIndexesToCheck = 1000,
+  }) async {
+    longMutex = true;
+
+    Map<String, Map<String, String>> p2pkhReceiveDerivations = {};
+    Map<String, Map<String, String>> p2shReceiveDerivations = {};
+    Map<String, Map<String, String>> p2wpkhReceiveDerivations = {};
+    Map<String, Map<String, String>> p2pkhChangeDerivations = {};
+    Map<String, Map<String, String>> p2shChangeDerivations = {};
+    Map<String, Map<String, String>> p2wpkhChangeDerivations = {};
+
+    final root = await compute(getBip32RootWrapper, Tuple2(mnemonic, _network));
+
+    List<String> p2pkhReceiveAddressArray = [];
+    List<String> p2shReceiveAddressArray = [];
+    List<String> p2wpkhReceiveAddressArray = [];
+    int p2pkhReceiveIndex = -1;
+    int p2shReceiveIndex = -1;
+    int p2wpkhReceiveIndex = -1;
+
+    List<String> p2pkhChangeAddressArray = [];
+    List<String> p2shChangeAddressArray = [];
+    List<String> p2wpkhChangeAddressArray = [];
+    int p2pkhChangeIndex = -1;
+    int p2shChangeIndex = -1;
+    int p2wpkhChangeIndex = -1;
+
+    // actual size is 36 due to p2pkh, p2sh, and p2wpkh so 12x3
+    const txCountBatchSize = 12;
+
+    try {
+      // receiving addresses
+      Logging.instance
+          .log("checking receiving addresses...", level: LogLevel.Info);
+      final resultReceive44 = _checkGaps(maxNumberOfIndexesToCheck,
+          maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip44, 0);
+
+      final resultReceive49 = _checkGaps(maxNumberOfIndexesToCheck,
+          maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 0);
+
+      final resultReceive84 = _checkGaps(maxNumberOfIndexesToCheck,
+          maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip84, 0);
+
+      Logging.instance
+          .log("checking change addresses...", level: LogLevel.Info);
+      // change addresses
+      final resultChange44 = _checkGaps(maxNumberOfIndexesToCheck,
+          maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip44, 1);
+
+      final resultChange49 = _checkGaps(maxNumberOfIndexesToCheck,
+          maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 1);
+
+      final resultChange84 = _checkGaps(maxNumberOfIndexesToCheck,
+          maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip84, 1);
+
+      await Future.wait([
+        resultReceive44,
+        resultReceive49,
+        resultReceive84,
+        resultChange44,
+        resultChange49,
+        resultChange84
+      ]);
+
+      p2pkhReceiveAddressArray =
+          (await resultReceive44)['addressArray'] as List<String>;
+      p2pkhReceiveIndex = (await resultReceive44)['index'] as int;
+      p2pkhReceiveDerivations = (await resultReceive44)['derivations']
+          as Map<String, Map<String, String>>;
+
+      p2shReceiveAddressArray =
+          (await resultReceive49)['addressArray'] as List<String>;
+      p2shReceiveIndex = (await resultReceive49)['index'] as int;
+      p2shReceiveDerivations = (await resultReceive49)['derivations']
+          as Map<String, Map<String, String>>;
+
+      p2wpkhReceiveAddressArray =
+          (await resultReceive84)['addressArray'] as List<String>;
+      p2wpkhReceiveIndex = (await resultReceive84)['index'] as int;
+      p2wpkhReceiveDerivations = (await resultReceive84)['derivations']
+          as Map<String, Map<String, String>>;
+
+      p2pkhChangeAddressArray =
+          (await resultChange44)['addressArray'] as List<String>;
+      p2pkhChangeIndex = (await resultChange44)['index'] as int;
+      p2pkhChangeDerivations = (await resultChange44)['derivations']
+          as Map<String, Map<String, String>>;
+
+      p2shChangeAddressArray =
+          (await resultChange49)['addressArray'] as List<String>;
+      p2shChangeIndex = (await resultChange49)['index'] as int;
+      p2shChangeDerivations = (await resultChange49)['derivations']
+          as Map<String, Map<String, String>>;
+
+      p2wpkhChangeAddressArray =
+          (await resultChange84)['addressArray'] as List<String>;
+      p2wpkhChangeIndex = (await resultChange84)['index'] as int;
+      p2wpkhChangeDerivations = (await resultChange84)['derivations']
+          as Map<String, Map<String, String>>;
+
+      // save the derivations (if any)
+      if (p2pkhReceiveDerivations.isNotEmpty) {
+        await addDerivations(
+            chain: 0,
+            derivePathType: DerivePathType.bip44,
+            derivationsToAdd: p2pkhReceiveDerivations);
+      }
+      if (p2shReceiveDerivations.isNotEmpty) {
+        await addDerivations(
+            chain: 0,
+            derivePathType: DerivePathType.bip49,
+            derivationsToAdd: p2shReceiveDerivations);
+      }
+      if (p2wpkhReceiveDerivations.isNotEmpty) {
+        await addDerivations(
+            chain: 0,
+            derivePathType: DerivePathType.bip84,
+            derivationsToAdd: p2wpkhReceiveDerivations);
+      }
+      if (p2pkhChangeDerivations.isNotEmpty) {
+        await addDerivations(
+            chain: 1,
+            derivePathType: DerivePathType.bip44,
+            derivationsToAdd: p2pkhChangeDerivations);
+      }
+      if (p2shChangeDerivations.isNotEmpty) {
+        await addDerivations(
+            chain: 1,
+            derivePathType: DerivePathType.bip49,
+            derivationsToAdd: p2shChangeDerivations);
+      }
+      if (p2wpkhChangeDerivations.isNotEmpty) {
+        await addDerivations(
+            chain: 1,
+            derivePathType: DerivePathType.bip84,
+            derivationsToAdd: p2wpkhChangeDerivations);
+      }
+
+      // 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) {
+        final address =
+            await _generateAddressForChain(0, 0, DerivePathType.bip44);
+        p2pkhReceiveAddressArray.add(address);
+        p2pkhReceiveIndex = 0;
+      }
+      if (p2shReceiveIndex == -1) {
+        final address =
+            await _generateAddressForChain(0, 0, DerivePathType.bip49);
+        p2shReceiveAddressArray.add(address);
+        p2shReceiveIndex = 0;
+      }
+      if (p2wpkhReceiveIndex == -1) {
+        final address =
+            await _generateAddressForChain(0, 0, DerivePathType.bip84);
+        p2wpkhReceiveAddressArray.add(address);
+        p2wpkhReceiveIndex = 0;
+      }
+
+      // If restoring a wallet that never sent any funds with change, then set changeArray
+      // manually. If we didn't do this, it'd store an empty array.
+      if (p2pkhChangeIndex == -1) {
+        final address =
+            await _generateAddressForChain(1, 0, DerivePathType.bip44);
+        p2pkhChangeAddressArray.add(address);
+        p2pkhChangeIndex = 0;
+      }
+      if (p2shChangeIndex == -1) {
+        final address =
+            await _generateAddressForChain(1, 0, DerivePathType.bip49);
+        p2shChangeAddressArray.add(address);
+        p2shChangeIndex = 0;
+      }
+      if (p2wpkhChangeIndex == -1) {
+        final address =
+            await _generateAddressForChain(1, 0, DerivePathType.bip84);
+        p2wpkhChangeAddressArray.add(address);
+        p2wpkhChangeIndex = 0;
+      }
+
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'receivingAddressesP2WPKH',
+          value: p2wpkhReceiveAddressArray);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'changeAddressesP2WPKH',
+          value: p2wpkhChangeAddressArray);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'receivingAddressesP2PKH',
+          value: p2pkhReceiveAddressArray);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'changeAddressesP2PKH',
+          value: p2pkhChangeAddressArray);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'receivingAddressesP2SH',
+          value: p2shReceiveAddressArray);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'changeAddressesP2SH',
+          value: p2shChangeAddressArray);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'receivingIndexP2WPKH',
+          value: p2wpkhReceiveIndex);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'changeIndexP2WPKH',
+          value: p2wpkhChangeIndex);
+      await DB.instance.put<dynamic>(
+          boxName: walletId, key: 'changeIndexP2PKH', value: p2pkhChangeIndex);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'receivingIndexP2PKH',
+          value: p2pkhReceiveIndex);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'receivingIndexP2SH',
+          value: p2shReceiveIndex);
+      await DB.instance.put<dynamic>(
+          boxName: walletId, key: 'changeIndexP2SH', value: p2shChangeIndex);
+      await DB.instance
+          .put<dynamic>(boxName: walletId, key: "id", value: _walletId);
+      await DB.instance
+          .put<dynamic>(boxName: walletId, key: "isFavorite", value: false);
+
+      longMutex = false;
+    } catch (e, s) {
+      Logging.instance.log(
+          "Exception rethrown from _recoverWalletFromBIP32SeedPhrase(): $e\n$s",
+          level: LogLevel.Error);
+
+      longMutex = false;
+      rethrow;
+    }
+  }
+
+  Future<bool> refreshIfThereIsNewData() async {
+    if (longMutex) return false;
+    if (_hasCalledExit) return false;
+    Logging.instance.log("refreshIfThereIsNewData", level: LogLevel.Info);
+
+    try {
+      bool needsRefresh = false;
+      Set<String> txnsToCheck = {};
+
+      for (final String txid in txTracker.pendings) {
+        if (!txTracker.wasNotifiedConfirmed(txid)) {
+          txnsToCheck.add(txid);
+        }
+      }
+
+      for (String txid in txnsToCheck) {
+        final txn = await electrumXClient.getTransaction(txHash: txid);
+        int confirmations = txn["confirmations"] as int? ?? 0;
+        bool isUnconfirmed = confirmations < MINIMUM_CONFIRMATIONS;
+        if (!isUnconfirmed) {
+          // unconfirmedTxs = {};
+          needsRefresh = true;
+          break;
+        }
+      }
+      if (!needsRefresh) {
+        var allOwnAddresses = await _fetchAllOwnAddresses();
+        List<Map<String, dynamic>> allTxs =
+            await _fetchHistory(allOwnAddresses);
+        final txData = await transactionData;
+        for (Map<String, dynamic> transaction in allTxs) {
+          if (txData.findTransaction(transaction['tx_hash'] as String) ==
+              null) {
+            Logging.instance.log(
+                " txid not found in address history already ${transaction['tx_hash']}",
+                level: LogLevel.Info);
+            needsRefresh = true;
+            break;
+          }
+        }
+      }
+      return needsRefresh;
+    } catch (e, s) {
+      Logging.instance.log(
+          "Exception caught in refreshIfThereIsNewData: $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  Future<void> getAllTxsToWatch(
+    TransactionData txData,
+  ) async {
+    if (_hasCalledExit) return;
+    List<models.Transaction> unconfirmedTxnsToNotifyPending = [];
+    List<models.Transaction> unconfirmedTxnsToNotifyConfirmed = [];
+
+    for (final chunk in txData.txChunks) {
+      for (final tx in chunk.transactions) {
+        if (tx.confirmedStatus) {
+          // get all transactions that were notified as pending but not as confirmed
+          if (txTracker.wasNotifiedPending(tx.txid) &&
+              !txTracker.wasNotifiedConfirmed(tx.txid)) {
+            unconfirmedTxnsToNotifyConfirmed.add(tx);
+          }
+        } else {
+          // get all transactions that were not notified as pending yet
+          if (!txTracker.wasNotifiedPending(tx.txid)) {
+            unconfirmedTxnsToNotifyPending.add(tx);
+          }
+        }
+      }
+    }
+
+    // notify on unconfirmed transactions
+    for (final tx in unconfirmedTxnsToNotifyPending) {
+      if (tx.txType == "Received") {
+        unawaited(NotificationApi.showNotification(
+          title: "Incoming transaction",
+          body: walletName,
+          walletId: walletId,
+          iconAssetName: Assets.svg.iconFor(coin: coin),
+          date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
+          shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS,
+          coinName: coin.name,
+          txid: tx.txid,
+          confirmations: tx.confirmations,
+          requiredConfirmations: MINIMUM_CONFIRMATIONS,
+        ));
+        await txTracker.addNotifiedPending(tx.txid);
+      } else if (tx.txType == "Sent") {
+        unawaited(NotificationApi.showNotification(
+          title: "Sending transaction",
+          body: walletName,
+          walletId: walletId,
+          iconAssetName: Assets.svg.iconFor(coin: coin),
+          date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
+          shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS,
+          coinName: coin.name,
+          txid: tx.txid,
+          confirmations: tx.confirmations,
+          requiredConfirmations: MINIMUM_CONFIRMATIONS,
+        ));
+        await txTracker.addNotifiedPending(tx.txid);
+      }
+    }
+
+    // notify on confirmed
+    for (final tx in unconfirmedTxnsToNotifyConfirmed) {
+      if (tx.txType == "Received") {
+        unawaited(NotificationApi.showNotification(
+          title: "Incoming transaction confirmed",
+          body: walletName,
+          walletId: walletId,
+          iconAssetName: Assets.svg.iconFor(coin: coin),
+          date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
+          shouldWatchForUpdates: false,
+          coinName: coin.name,
+        ));
+        await txTracker.addNotifiedConfirmed(tx.txid);
+      } else if (tx.txType == "Sent") {
+        unawaited(NotificationApi.showNotification(
+          title: "Outgoing transaction confirmed",
+          body: walletName,
+          walletId: walletId,
+          iconAssetName: Assets.svg.iconFor(coin: coin),
+          date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
+          shouldWatchForUpdates: false,
+          coinName: coin.name,
+        ));
+        await txTracker.addNotifiedConfirmed(tx.txid);
+      }
+    }
+  }
+
+  bool _shouldAutoSync = false;
+
+  @override
+  bool get shouldAutoSync => _shouldAutoSync;
+
+  @override
+  set shouldAutoSync(bool shouldAutoSync) {
+    if (_shouldAutoSync != shouldAutoSync) {
+      _shouldAutoSync = shouldAutoSync;
+      if (!shouldAutoSync) {
+        timer?.cancel();
+        timer = null;
+        stopNetworkAlivePinging();
+      } else {
+        startNetworkAlivePinging();
+        refresh();
+      }
+    }
+  }
+
+  @override
+  bool get isRefreshing => refreshMutex;
+
+  bool refreshMutex = false;
+
+  //TODO Show percentages properly/more consistently
+  /// Refreshes display data for the wallet
+  @override
+  Future<void> refresh() async {
+    if (refreshMutex) {
+      Logging.instance.log("$walletId $walletName refreshMutex denied",
+          level: LogLevel.Info);
+      return;
+    } else {
+      refreshMutex = true;
+    }
+
+    try {
+      GlobalEventBus.instance.fire(
+        WalletSyncStatusChangedEvent(
+          WalletSyncStatus.syncing,
+          walletId,
+          coin,
+        ),
+      );
+
+      GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.0, walletId));
+
+      GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.1, walletId));
+
+      final currentHeight = await chainHeight;
+      const storedHeight = 1; //await storedChainHeight;
+
+      Logging.instance
+          .log("chain height: $currentHeight", level: LogLevel.Info);
+      Logging.instance
+          .log("cached height: $storedHeight", level: LogLevel.Info);
+
+      if (currentHeight != storedHeight) {
+        if (currentHeight != -1) {
+          // -1 failed to fetch current height
+          unawaited(updateStoredChainHeight(newHeight: currentHeight));
+        }
+
+        GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.2, walletId));
+        final changeAddressForTransactions =
+            _checkChangeAddressForTransactions(DerivePathType.bip84);
+
+        GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId));
+        final currentReceivingAddressesForTransactions =
+            _checkCurrentReceivingAddressesForTransactions();
+
+        final newTxData = _fetchTransactionData();
+        GlobalEventBus.instance
+            .fire(RefreshPercentChangedEvent(0.50, walletId));
+
+        final newUtxoData = _fetchUtxoData();
+        final feeObj = _getFees();
+        GlobalEventBus.instance
+            .fire(RefreshPercentChangedEvent(0.60, walletId));
+
+        _transactionData = Future(() => newTxData);
+
+        GlobalEventBus.instance
+            .fire(RefreshPercentChangedEvent(0.70, walletId));
+        _feeObject = Future(() => feeObj);
+        _utxoData = Future(() => newUtxoData);
+        GlobalEventBus.instance
+            .fire(RefreshPercentChangedEvent(0.80, walletId));
+
+        final allTxsToWatch = getAllTxsToWatch(await newTxData);
+        await Future.wait([
+          newTxData,
+          changeAddressForTransactions,
+          currentReceivingAddressesForTransactions,
+          newUtxoData,
+          feeObj,
+          allTxsToWatch,
+        ]);
+        GlobalEventBus.instance
+            .fire(RefreshPercentChangedEvent(0.90, walletId));
+      }
+
+      refreshMutex = false;
+      GlobalEventBus.instance.fire(RefreshPercentChangedEvent(1.0, walletId));
+      GlobalEventBus.instance.fire(
+        WalletSyncStatusChangedEvent(
+          WalletSyncStatus.synced,
+          walletId,
+          coin,
+        ),
+      );
+
+      if (shouldAutoSync) {
+        timer ??= Timer.periodic(const Duration(seconds: 30), (timer) async {
+          Logging.instance.log(
+              "Periodic refresh check for $walletId $walletName in object instance: $hashCode",
+              level: LogLevel.Info);
+          // chain height check currently broken
+          // if ((await chainHeight) != (await storedChainHeight)) {
+          if (await refreshIfThereIsNewData()) {
+            await refresh();
+            GlobalEventBus.instance.fire(UpdatedInBackgroundEvent(
+                "New data found in $walletId $walletName in background!",
+                walletId));
+          }
+          // }
+        });
+      }
+    } catch (error, strace) {
+      refreshMutex = false;
+      GlobalEventBus.instance.fire(
+        NodeConnectionStatusChangedEvent(
+          NodeConnectionStatus.disconnected,
+          walletId,
+          coin,
+        ),
+      );
+      GlobalEventBus.instance.fire(
+        WalletSyncStatusChangedEvent(
+          WalletSyncStatus.unableToSync,
+          walletId,
+          coin,
+        ),
+      );
+      Logging.instance.log(
+          "Caught exception in refreshWalletData(): $error\n$strace",
+          level: LogLevel.Error);
+    }
+  }
+
+  @override
+  Future<Map<String, dynamic>> prepareSend({
+    required String address,
+    required int satoshiAmount,
+    Map<String, dynamic>? args,
+  }) async {
+    try {
+      final feeRateType = args?["feeRate"];
+      final feeRateAmount = args?["feeRateAmount"];
+      if (feeRateType is FeeRateType || feeRateAmount is int) {
+        late final int rate;
+        if (feeRateType is FeeRateType) {
+          int fee = 0;
+          final feeObject = await fees;
+          switch (feeRateType) {
+            case FeeRateType.fast:
+              fee = feeObject.fast;
+              break;
+            case FeeRateType.average:
+              fee = feeObject.medium;
+              break;
+            case FeeRateType.slow:
+              fee = feeObject.slow;
+              break;
+          }
+          rate = fee;
+        } else {
+          rate = feeRateAmount as int;
+        }
+
+        // check for send all
+        bool isSendAll = false;
+        final balance = Format.decimalAmountToSatoshis(await availableBalance);
+        if (satoshiAmount == balance) {
+          isSendAll = true;
+        }
+
+        final txData =
+            await coinSelection(satoshiAmount, rate, address, isSendAll);
+
+        Logging.instance.log("prepare send: $txData", level: LogLevel.Info);
+        try {
+          if (txData is int) {
+            switch (txData) {
+              case 1:
+                throw Exception("Insufficient balance!");
+              case 2:
+                throw Exception(
+                    "Insufficient funds to pay for transaction fee!");
+              default:
+                throw Exception("Transaction failed with error code $txData");
+            }
+          } else {
+            final hex = txData["hex"];
+
+            if (hex is String) {
+              final fee = txData["fee"] as int;
+              final vSize = txData["vSize"] as int;
+
+              Logging.instance
+                  .log("prepared txHex: $hex", level: LogLevel.Info);
+              Logging.instance.log("prepared fee: $fee", level: LogLevel.Info);
+              Logging.instance
+                  .log("prepared vSize: $vSize", level: LogLevel.Info);
+
+              // fee should never be less than vSize sanity check
+              if (fee < vSize) {
+                throw Exception(
+                    "Error in fee calculation: Transaction fee cannot be less than vSize");
+              }
+
+              return txData as Map<String, dynamic>;
+            } else {
+              throw Exception("prepared hex is not a String!!!");
+            }
+          }
+        } catch (e, s) {
+          Logging.instance.log("Exception rethrown from prepareSend(): $e\n$s",
+              level: LogLevel.Error);
+          rethrow;
+        }
+      } else {
+        throw ArgumentError("Invalid fee rate argument provided!");
+      }
+    } catch (e, s) {
+      Logging.instance.log("Exception rethrown from prepareSend(): $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  @override
+  Future<String> confirmSend({required Map<String, dynamic> txData}) async {
+    try {
+      Logging.instance.log("confirmSend txData: $txData", level: LogLevel.Info);
+
+      final hex = txData["hex"] as String;
+
+      final txHash = await _electrumXClient.broadcastTransaction(rawTx: hex);
+      Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info);
+
+      return txHash;
+    } catch (e, s) {
+      Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  @override
+  Future<String> send({
+    required String toAddress,
+    required int amount,
+    Map<String, String> args = const {},
+  }) async {
+    try {
+      final txData = await prepareSend(
+          address: toAddress, satoshiAmount: amount, args: args);
+      final txHash = await confirmSend(txData: txData);
+      return txHash;
+    } catch (e, s) {
+      Logging.instance
+          .log("Exception rethrown from send(): $e\n$s", level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  @override
+  Future<bool> testNetworkConnection() async {
+    try {
+      final result = await _electrumXClient.ping();
+      return result;
+    } catch (_) {
+      return false;
+    }
+  }
+
+  Timer? _networkAliveTimer;
+
+  void startNetworkAlivePinging() {
+    // call once on start right away
+    _periodicPingCheck();
+
+    // then periodically check
+    _networkAliveTimer = Timer.periodic(
+      Constants.networkAliveTimerDuration,
+      (_) async {
+        _periodicPingCheck();
+      },
+    );
+  }
+
+  void _periodicPingCheck() async {
+    bool hasNetwork = await testNetworkConnection();
+    _isConnected = hasNetwork;
+    if (_isConnected != hasNetwork) {
+      NodeConnectionStatus status = hasNetwork
+          ? NodeConnectionStatus.connected
+          : NodeConnectionStatus.disconnected;
+      GlobalEventBus.instance
+          .fire(NodeConnectionStatusChangedEvent(status, walletId, coin));
+    }
+  }
+
+  void stopNetworkAlivePinging() {
+    _networkAliveTimer?.cancel();
+    _networkAliveTimer = null;
+  }
+
+  bool _isConnected = false;
+
+  @override
+  bool get isConnected => _isConnected;
+
+  @override
+  Future<void> initializeNew() async {
+    Logging.instance
+        .log("Generating new ${coin.prettyName} wallet.", level: LogLevel.Info);
+
+    if ((DB.instance.get<dynamic>(boxName: walletId, key: "id")) != null) {
+      throw Exception(
+          "Attempted to initialize a new wallet using an existing wallet ID!");
+    }
+
+    await _prefs.init();
+    try {
+      await _generateNewWallet();
+    } catch (e, s) {
+      Logging.instance.log("Exception rethrown from initializeNew(): $e\n$s",
+          level: LogLevel.Fatal);
+      rethrow;
+    }
+    await Future.wait([
+      DB.instance.put<dynamic>(boxName: walletId, key: "id", value: walletId),
+      DB.instance
+          .put<dynamic>(boxName: walletId, key: "isFavorite", value: false),
+    ]);
+  }
+
+  @override
+  Future<void> initializeExisting() async {
+    Logging.instance.log("Opening existing ${coin.prettyName} wallet.",
+        level: LogLevel.Info);
+
+    if ((DB.instance.get<dynamic>(boxName: walletId, key: "id")) == null) {
+      throw Exception(
+          "Attempted to initialize an existing wallet using an unknown wallet ID!");
+    }
+    await _prefs.init();
+    final data =
+        DB.instance.get<dynamic>(boxName: walletId, key: "latest_tx_model")
+            as TransactionData?;
+    if (data != null) {
+      _transactionData = Future(() => data);
+    }
+  }
+
+  @override
+  Future<TransactionData> get transactionData =>
+      _transactionData ??= _fetchTransactionData();
+  Future<TransactionData>? _transactionData;
+
+  @override
+  bool validateAddress(String address) {
+    return Address.validateAddress(address, _network);
+  }
+
+  @override
+  String get walletId => _walletId;
+  late String _walletId;
+
+  @override
+  String get walletName => _walletName;
+  late String _walletName;
+
+  // setter for updating on rename
+  @override
+  set walletName(String newName) => _walletName = newName;
+
+  late ElectrumX _electrumXClient;
+
+  ElectrumX get electrumXClient => _electrumXClient;
+
+  late CachedElectrumX _cachedElectrumXClient;
+
+  CachedElectrumX get cachedElectrumXClient => _cachedElectrumXClient;
+
+  late FlutterSecureStorageInterface _secureStore;
+
+  late PriceAPI _priceAPI;
+
+  BitcoinWallet({
+    required String walletId,
+    required String walletName,
+    required Coin coin,
+    required ElectrumX client,
+    required CachedElectrumX cachedClient,
+    required TransactionNotificationTracker tracker,
+    PriceAPI? priceAPI,
+    FlutterSecureStorageInterface? secureStore,
+  }) {
+    txTracker = tracker;
+    _walletId = walletId;
+    _walletName = walletName;
+    _coin = coin;
+    _electrumXClient = client;
+    _cachedElectrumXClient = cachedClient;
+
+    _priceAPI = priceAPI ?? PriceAPI(Client());
+    _secureStore =
+        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+  }
+
+  @override
+  Future<void> updateNode(bool shouldRefresh) async {
+    final failovers = NodeService()
+        .failoverNodesFor(coin: coin)
+        .map((e) => ElectrumXNode(
+              address: e.host,
+              port: e.port,
+              name: e.name,
+              id: e.id,
+              useSSL: e.useSSL,
+            ))
+        .toList();
+    final newNode = await getCurrentNode();
+    _cachedElectrumXClient = CachedElectrumX.from(
+      node: newNode,
+      prefs: _prefs,
+      failovers: failovers,
+    );
+    _electrumXClient = ElectrumX.from(
+      node: newNode,
+      prefs: _prefs,
+      failovers: failovers,
+    );
+
+    if (shouldRefresh) {
+      unawaited(refresh());
+    }
+  }
+
+  Future<List<String>> _getMnemonicList() async {
+    final mnemonicString =
+        await _secureStore.read(key: '${_walletId}_mnemonic');
+    if (mnemonicString == null) {
+      return [];
+    }
+    final List<String> data = mnemonicString.split(' ');
+    return data;
+  }
+
+  Future<ElectrumXNode> getCurrentNode() async {
+    final node = NodeService().getPrimaryNodeFor(coin: coin) ??
+        DefaultNodes.getNodeFor(coin);
+
+    return ElectrumXNode(
+      address: node.host,
+      port: node.port,
+      name: node.name,
+      useSSL: node.useSSL,
+      id: node.id,
+    );
+  }
+
+  Future<List<String>> _fetchAllOwnAddresses() async {
+    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;
+  }
+
+  Future<FeeObject> _getFees() async {
+    try {
+      //TODO adjust numbers for different speeds?
+      const int f = 1, m = 5, s = 20;
+
+      final fast = await electrumXClient.estimateFee(blocks: f);
+      final medium = await electrumXClient.estimateFee(blocks: m);
+      final slow = await electrumXClient.estimateFee(blocks: s);
+
+      final feeObject = FeeObject(
+        numberOfBlocksFast: f,
+        numberOfBlocksAverage: m,
+        numberOfBlocksSlow: s,
+        fast: Format.decimalAmountToSatoshis(fast),
+        medium: Format.decimalAmountToSatoshis(medium),
+        slow: Format.decimalAmountToSatoshis(slow),
+      );
+
+      Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
+      return feeObject;
+    } catch (e) {
+      Logging.instance
+          .log("Exception rethrown from _getFees(): $e", level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  Future<void> _generateNewWallet() async {
+    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.bitcoin:
+          if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
+            throw Exception("genesis hash does not match main net!");
+          }
+          break;
+        case Coin.bitcoinTestNet:
+          if (features['genesis_hash'] != GENESIS_HASH_TESTNET) {
+            throw Exception("genesis hash does not match test net!");
+          }
+          break;
+        default:
+          throw Exception(
+              "Attempted to generate a BitcoinWallet using a non bitcoin coin type: ${coin.name}");
+      }
+    }
+
+    // this should never fail
+    if ((await _secureStore.read(key: '${_walletId}_mnemonic')) != null) {
+      throw Exception(
+          "Attempted to overwrite mnemonic on generate new wallet!");
+    }
+    await _secureStore.write(
+        key: '${_walletId}_mnemonic',
+        value: bip39.generateMnemonic(strength: 256));
+
+    // Set relevant indexes
+    await DB.instance
+        .put<dynamic>(boxName: walletId, key: "receivingIndexP2WPKH", value: 0);
+    await DB.instance
+        .put<dynamic>(boxName: walletId, key: "changeIndexP2WPKH", value: 0);
+    await DB.instance
+        .put<dynamic>(boxName: walletId, key: "receivingIndexP2PKH", value: 0);
+    await DB.instance
+        .put<dynamic>(boxName: walletId, key: "changeIndexP2PKH", value: 0);
+    await DB.instance
+        .put<dynamic>(boxName: walletId, key: "receivingIndexP2SH", value: 0);
+    await DB.instance
+        .put<dynamic>(boxName: walletId, key: "changeIndexP2SH", value: 0);
+    await DB.instance.put<dynamic>(
+      boxName: walletId,
+      key: 'blocked_tx_hashes',
+      value: ["0xdefault"],
+    ); // A list of transaction hashes to represent frozen utxos in wallet
+    // initialize address book entries
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'addressBookEntries',
+        value: <String, String>{});
+
+    // Generate and add addresses to relevant arrays
+    await Future.wait([
+      // P2WPKH
+      _generateAddressForChain(0, 0, DerivePathType.bip84).then(
+        (initialReceivingAddressP2WPKH) {
+          _addToAddressesArrayForChain(
+              initialReceivingAddressP2WPKH, 0, DerivePathType.bip84);
+          _currentReceivingAddress =
+              Future(() => initialReceivingAddressP2WPKH);
+        },
+      ),
+      _generateAddressForChain(1, 0, DerivePathType.bip84).then(
+        (initialChangeAddressP2WPKH) => _addToAddressesArrayForChain(
+          initialChangeAddressP2WPKH,
+          1,
+          DerivePathType.bip84,
+        ),
+      ),
+
+      // P2PKH
+      _generateAddressForChain(0, 0, DerivePathType.bip44).then(
+        (initialReceivingAddressP2PKH) {
+          _addToAddressesArrayForChain(
+              initialReceivingAddressP2PKH, 0, DerivePathType.bip44);
+          _currentReceivingAddressP2PKH =
+              Future(() => initialReceivingAddressP2PKH);
+        },
+      ),
+      _generateAddressForChain(1, 0, DerivePathType.bip44).then(
+        (initialChangeAddressP2PKH) => _addToAddressesArrayForChain(
+          initialChangeAddressP2PKH,
+          1,
+          DerivePathType.bip44,
+        ),
+      ),
+
+      // P2SH
+      _generateAddressForChain(0, 0, DerivePathType.bip49).then(
+        (initialReceivingAddressP2SH) {
+          _addToAddressesArrayForChain(
+              initialReceivingAddressP2SH, 0, DerivePathType.bip49);
+          _currentReceivingAddressP2SH =
+              Future(() => initialReceivingAddressP2SH);
+        },
+      ),
+      _generateAddressForChain(1, 0, DerivePathType.bip49).then(
+        (initialChangeAddressP2SH) => _addToAddressesArrayForChain(
+          initialChangeAddressP2SH,
+          1,
+          DerivePathType.bip49,
+        ),
+      ),
+    ]);
+
+    // // P2PKH
+    // _generateAddressForChain(0, 0, DerivePathType.bip44).then(
+    //   (initialReceivingAddressP2PKH) {
+    //     _addToAddressesArrayForChain(
+    //         initialReceivingAddressP2PKH, 0, DerivePathType.bip44);
+    //     this._currentReceivingAddressP2PKH =
+    //         Future(() => initialReceivingAddressP2PKH);
+    //   },
+    // );
+    // _generateAddressForChain(1, 0, DerivePathType.bip44)
+    //     .then((initialChangeAddressP2PKH) => _addToAddressesArrayForChain(
+    //           initialChangeAddressP2PKH,
+    //           1,
+    //           DerivePathType.bip44,
+    //         ));
+    //
+    // // P2SH
+    // _generateAddressForChain(0, 0, DerivePathType.bip49).then(
+    //   (initialReceivingAddressP2SH) {
+    //     _addToAddressesArrayForChain(
+    //         initialReceivingAddressP2SH, 0, DerivePathType.bip49);
+    //     this._currentReceivingAddressP2SH =
+    //         Future(() => initialReceivingAddressP2SH);
+    //   },
+    // );
+    // _generateAddressForChain(1, 0, DerivePathType.bip49)
+    //     .then((initialChangeAddressP2SH) => _addToAddressesArrayForChain(
+    //           initialChangeAddressP2SH,
+    //           1,
+    //           DerivePathType.bip49,
+    //         ));
+
+    Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info);
+  }
+
+  /// Generates a new internal or external chain address for the wallet using a BIP84, BIP44, or BIP49 derivation path.
+  /// [chain] - Use 0 for receiving (external), 1 for change (internal). Should not be any other value!
+  /// [index] - This can be any integer >= 0
+  Future<String> _generateAddressForChain(
+    int chain,
+    int index,
+    DerivePathType derivePathType,
+  ) async {
+    final mnemonic = await _secureStore.read(key: '${_walletId}_mnemonic');
+    final node = await compute(
+      getBip32NodeWrapper,
+      Tuple5(
+        chain,
+        index,
+        mnemonic!,
+        _network,
+        derivePathType,
+      ),
+    );
+    final data = PaymentData(pubkey: node.publicKey);
+    String address;
+
+    switch (derivePathType) {
+      case DerivePathType.bip44:
+        address = P2PKH(data: data, network: _network).data.address!;
+        break;
+      case DerivePathType.bip49:
+        address = P2SH(
+                data: PaymentData(
+                    redeem: P2WPKH(data: data, network: _network).data),
+                network: _network)
+            .data
+            .address!;
+        break;
+      case DerivePathType.bip84:
+        address = P2WPKH(network: _network, data: data).data.address!;
+        break;
+    }
+
+    // add generated address & info to derivations
+    await addDerivation(
+      chain: chain,
+      address: address,
+      pubKey: Format.uint8listToString(node.publicKey),
+      wif: node.toWIF(),
+      derivePathType: derivePathType,
+    );
+
+    return address;
+  }
+
+  /// Increases the index for either the internal or external chain, depending on [chain].
+  /// [chain] - Use 0 for receiving (external), 1 for change (internal). Should not be any other value!
+  Future<void> _incrementAddressIndexForChain(
+      int chain, DerivePathType derivePathType) async {
+    // Here we assume chain == 1 if it isn't 0
+    String indexKey = chain == 0 ? "receivingIndex" : "changeIndex";
+    switch (derivePathType) {
+      case DerivePathType.bip44:
+        indexKey += "P2PKH";
+        break;
+      case DerivePathType.bip49:
+        indexKey += "P2SH";
+        break;
+      case DerivePathType.bip84:
+        indexKey += "P2WPKH";
+        break;
+    }
+
+    final newIndex =
+        (DB.instance.get<dynamic>(boxName: walletId, key: indexKey)) + 1;
+    await DB.instance
+        .put<dynamic>(boxName: walletId, key: indexKey, value: newIndex);
+  }
+
+  /// Adds [address] to the relevant chain's address array, which is determined by [chain].
+  /// [address] - Expects a standard native segwit address
+  /// [chain] - Use 0 for receiving (external), 1 for change (internal). Should not be any other value!
+  Future<void> _addToAddressesArrayForChain(
+      String address, int chain, DerivePathType derivePathType) async {
+    String chainArray = '';
+    if (chain == 0) {
+      chainArray = 'receivingAddresses';
+    } else {
+      chainArray = 'changeAddresses';
+    }
+    switch (derivePathType) {
+      case DerivePathType.bip44:
+        chainArray += "P2PKH";
+        break;
+      case DerivePathType.bip49:
+        chainArray += "P2SH";
+        break;
+      case DerivePathType.bip84:
+        chainArray += "P2WPKH";
+        break;
+    }
+
+    final addressArray =
+        DB.instance.get<dynamic>(boxName: walletId, key: chainArray);
+    if (addressArray == null) {
+      Logging.instance.log(
+          'Attempting to add the following to $chainArray array for chain $chain:${[
+            address
+          ]}',
+          level: LogLevel.Info);
+      await DB.instance
+          .put<dynamic>(boxName: walletId, key: chainArray, value: [address]);
+    } else {
+      // Make a deep copy of the existing list
+      final List<String> newArray = [];
+      addressArray
+          .forEach((dynamic _address) => newArray.add(_address as String));
+      newArray.add(address); // Add the address passed into the method
+      await DB.instance
+          .put<dynamic>(boxName: walletId, key: chainArray, value: newArray);
+    }
+  }
+
+  /// Returns the latest receiving/change (external/internal) address for the wallet depending on [chain]
+  /// and
+  /// [chain] - Use 0 for receiving (external), 1 for change (internal). Should not be any other value!
+  Future<String> _getCurrentAddressForChain(
+      int chain, DerivePathType derivePathType) async {
+    // Here, we assume that chain == 1 if it isn't 0
+    String arrayKey = chain == 0 ? "receivingAddresses" : "changeAddresses";
+    switch (derivePathType) {
+      case DerivePathType.bip44:
+        arrayKey += "P2PKH";
+        break;
+      case DerivePathType.bip49:
+        arrayKey += "P2SH";
+        break;
+      case DerivePathType.bip84:
+        arrayKey += "P2WPKH";
+        break;
+    }
+    final internalChainArray =
+        DB.instance.get<dynamic>(boxName: walletId, key: arrayKey);
+    return internalChainArray.last as String;
+  }
+
+  String _buildDerivationStorageKey({
+    required int chain,
+    required DerivePathType derivePathType,
+  }) {
+    String key;
+    String chainId = chain == 0 ? "receive" : "change";
+    switch (derivePathType) {
+      case DerivePathType.bip44:
+        key = "${walletId}_${chainId}DerivationsP2PKH";
+        break;
+      case DerivePathType.bip49:
+        key = "${walletId}_${chainId}DerivationsP2SH";
+        break;
+      case DerivePathType.bip84:
+        key = "${walletId}_${chainId}DerivationsP2WPKH";
+        break;
+    }
+    return key;
+  }
+
+  Future<Map<String, dynamic>> _fetchDerivations({
+    required int chain,
+    required DerivePathType derivePathType,
+  }) async {
+    // build lookup key
+    final key = _buildDerivationStorageKey(
+        chain: chain, derivePathType: derivePathType);
+
+    // fetch current derivations
+    final derivationsString = await _secureStore.read(key: key);
+    return Map<String, dynamic>.from(
+        jsonDecode(derivationsString ?? "{}") as Map);
+  }
+
+  /// Add a single derivation to the local secure storage for [chain] and
+  /// [derivePathType] where [chain] must either be 1 for change or 0 for receive.
+  /// This will overwrite a previous entry where the address of the new derivation
+  /// matches a derivation currently stored.
+  Future<void> addDerivation({
+    required int chain,
+    required String address,
+    required String pubKey,
+    required String wif,
+    required DerivePathType derivePathType,
+  }) async {
+    // build lookup key
+    final key = _buildDerivationStorageKey(
+        chain: chain, derivePathType: derivePathType);
+
+    // fetch current derivations
+    final derivationsString = await _secureStore.read(key: key);
+    final derivations =
+        Map<String, dynamic>.from(jsonDecode(derivationsString ?? "{}") as Map);
+
+    // add derivation
+    derivations[address] = {
+      "pubKey": pubKey,
+      "wif": wif,
+    };
+
+    // save derivations
+    final newReceiveDerivationsString = jsonEncode(derivations);
+    await _secureStore.write(key: key, value: newReceiveDerivationsString);
+  }
+
+  /// Add multiple derivations to the local secure storage for [chain] and
+  /// [derivePathType] where [chain] must either be 1 for change or 0 for receive.
+  /// This will overwrite any previous entries where the address of the new derivation
+  /// matches a derivation currently stored.
+  /// The [derivationsToAdd] must be in the format of:
+  /// {
+  ///   addressA : {
+  ///     "pubKey": <the pubKey string>,
+  ///     "wif": <the wif string>,
+  ///   },
+  ///   addressB : {
+  ///     "pubKey": <the pubKey string>,
+  ///     "wif": <the wif string>,
+  ///   },
+  /// }
+  Future<void> addDerivations({
+    required int chain,
+    required DerivePathType derivePathType,
+    required Map<String, dynamic> derivationsToAdd,
+  }) async {
+    // build lookup key
+    final key = _buildDerivationStorageKey(
+        chain: chain, derivePathType: derivePathType);
+
+    // fetch current derivations
+    final derivationsString = await _secureStore.read(key: key);
+    final derivations =
+        Map<String, dynamic>.from(jsonDecode(derivationsString ?? "{}") as Map);
+
+    // add derivation
+    derivations.addAll(derivationsToAdd);
+
+    // save derivations
+    final newReceiveDerivationsString = jsonEncode(derivations);
+    await _secureStore.write(key: key, value: newReceiveDerivationsString);
+  }
+
+  Future<UtxoData> _fetchUtxoData() async {
+    final List<String> allAddresses = await _fetchAllOwnAddresses();
+
+    try {
+      final fetchedUtxoList = <List<Map<String, dynamic>>>[];
+
+      final Map<int, Map<String, List<dynamic>>> batches = {};
+      const batchSizeMax = 100;
+      int batchNumber = 0;
+      for (int i = 0; i < allAddresses.length; i++) {
+        if (batches[batchNumber] == null) {
+          batches[batchNumber] = {};
+        }
+        final scripthash = _convertToScriptHash(allAddresses[i], _network);
+        batches[batchNumber]!.addAll({
+          scripthash: [scripthash]
+        });
+        if (i % batchSizeMax == batchSizeMax - 1) {
+          batchNumber++;
+        }
+      }
+
+      for (int i = 0; i < batches.length; i++) {
+        final response =
+            await _electrumXClient.getBatchUTXOs(args: batches[i]!);
+        for (final entry in response.entries) {
+          if (entry.value.isNotEmpty) {
+            fetchedUtxoList.add(entry.value);
+          }
+        }
+      }
+      final priceData =
+          await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
+      Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
+      final List<Map<String, dynamic>> outputArray = [];
+      int satoshiBalance = 0;
+      int satoshiBalancePending = 0;
+
+      for (int i = 0; i < fetchedUtxoList.length; i++) {
+        for (int j = 0; j < fetchedUtxoList[i].length; j++) {
+          int value = fetchedUtxoList[i][j]["value"] as int;
+          satoshiBalance += value;
+
+          final txn = await cachedElectrumXClient.getTransaction(
+            txHash: fetchedUtxoList[i][j]["tx_hash"] as String,
+            verbose: true,
+            coin: coin,
+          );
+
+          final Map<String, dynamic> utxo = {};
+          final int confirmations = txn["confirmations"] as int? ?? 0;
+          final bool confirmed = confirmations >= MINIMUM_CONFIRMATIONS;
+          if (!confirmed) {
+            satoshiBalancePending += value;
+          }
+
+          utxo["txid"] = txn["txid"];
+          utxo["vout"] = fetchedUtxoList[i][j]["tx_pos"];
+          utxo["value"] = value;
+
+          utxo["status"] = <String, dynamic>{};
+          utxo["status"]["confirmed"] = confirmed;
+          utxo["status"]["confirmations"] = confirmations;
+          utxo["status"]["block_height"] = fetchedUtxoList[i][j]["height"];
+          utxo["status"]["block_hash"] = txn["blockhash"];
+          utxo["status"]["block_time"] = txn["blocktime"];
+
+          final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
+                  Decimal.fromInt(Constants.satsPerCoin))
+              .toDecimal(scaleOnInfinitePrecision: 2);
+          utxo["rawWorth"] = fiatValue;
+          utxo["fiatWorth"] = fiatValue.toString();
+          outputArray.add(utxo);
+        }
+      }
+
+      Decimal currencyBalanceRaw =
+          ((Decimal.fromInt(satoshiBalance) * currentPrice) /
+                  Decimal.fromInt(Constants.satsPerCoin))
+              .toDecimal(scaleOnInfinitePrecision: 2);
+
+      final Map<String, dynamic> result = {
+        "total_user_currency": currencyBalanceRaw.toString(),
+        "total_sats": satoshiBalance,
+        "total_btc": (Decimal.fromInt(satoshiBalance) /
+                Decimal.fromInt(Constants.satsPerCoin))
+            .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
+            .toString(),
+        "outputArray": outputArray,
+        "unconfirmed": satoshiBalancePending,
+      };
+
+      final dataModel = UtxoData.fromJson(result);
+
+      final List<UtxoObject> allOutputs = dataModel.unspentOutputArray;
+      Logging.instance
+          .log('Outputs fetched: $allOutputs', level: LogLevel.Info);
+      await _sortOutputs(allOutputs);
+      await DB.instance.put<dynamic>(
+          boxName: walletId, key: 'latest_utxo_model', value: dataModel);
+      await DB.instance.put<dynamic>(
+          boxName: walletId,
+          key: 'totalBalance',
+          value: dataModel.satoshiBalance);
+      return dataModel;
+    } catch (e, s) {
+      Logging.instance
+          .log("Output fetch unsuccessful: $e\n$s", level: LogLevel.Error);
+      final latestTxModel =
+          DB.instance.get<dynamic>(boxName: walletId, key: 'latest_utxo_model')
+              as models.UtxoData?;
+
+      if (latestTxModel == null) {
+        final emptyModel = {
+          "total_user_currency": "0.00",
+          "total_sats": 0,
+          "total_btc": "0",
+          "outputArray": <dynamic>[]
+        };
+        return UtxoData.fromJson(emptyModel);
+      } else {
+        Logging.instance
+            .log("Old output model located", level: LogLevel.Warning);
+        return latestTxModel;
+      }
+    }
+  }
+
+  /// Takes in a list of UtxoObjects and adds a name (dependent on object index within list)
+  /// and checks for the txid associated with the utxo being blocked and marks it accordingly.
+  /// Now also checks for output labeling.
+  Future<void> _sortOutputs(List<UtxoObject> utxos) async {
+    final blockedHashArray =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'blocked_tx_hashes')
+            as List<dynamic>?;
+    final List<String> lst = [];
+    if (blockedHashArray != null) {
+      for (var hash in blockedHashArray) {
+        lst.add(hash as String);
+      }
+    }
+    final labels =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'labels') as Map? ??
+            {};
+
+    outputsList = [];
+
+    for (var i = 0; i < utxos.length; i++) {
+      if (labels[utxos[i].txid] != null) {
+        utxos[i].txName = labels[utxos[i].txid] as String? ?? "";
+      } else {
+        utxos[i].txName = 'Output #$i';
+      }
+
+      if (utxos[i].status.confirmed == false) {
+        outputsList.add(utxos[i]);
+      } else {
+        if (lst.contains(utxos[i].txid)) {
+          utxos[i].blocked = true;
+          outputsList.add(utxos[i]);
+        } else if (!lst.contains(utxos[i].txid)) {
+          outputsList.add(utxos[i]);
+        }
+      }
+    }
+  }
+
+  Future<int> getTxCount({required String address}) async {
+    String? scripthash;
+    try {
+      scripthash = _convertToScriptHash(address, _network);
+      final transactions =
+          await electrumXClient.getHistory(scripthash: scripthash);
+      return transactions.length;
+    } catch (e) {
+      Logging.instance.log(
+          "Exception rethrown in _getTxCount(address: $address, scripthash: $scripthash): $e",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  Future<Map<String, int>> _getBatchTxCount({
+    required Map<String, String> addresses,
+  }) async {
+    try {
+      final Map<String, List<dynamic>> args = {};
+      for (final entry in addresses.entries) {
+        args[entry.key] = [_convertToScriptHash(entry.value, _network)];
+      }
+      final response = await electrumXClient.getBatchHistory(args: args);
+
+      final Map<String, int> result = {};
+      for (final entry in response.entries) {
+        result[entry.key] = entry.value.length;
+      }
+      return result;
+    } catch (e, s) {
+      Logging.instance.log(
+          "Exception rethrown in _getBatchTxCount(address: $addresses: $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  Future<void> _checkReceivingAddressForTransactions(
+      DerivePathType derivePathType) async {
+    try {
+      final String currentExternalAddr =
+          await _getCurrentAddressForChain(0, derivePathType);
+      final int txCount = await getTxCount(address: currentExternalAddr);
+      Logging.instance.log(
+          'Number of txs for current receiving address $currentExternalAddr: $txCount',
+          level: LogLevel.Info);
+
+      if (txCount >= 1) {
+        // First increment the receiving index
+        await _incrementAddressIndexForChain(0, derivePathType);
+
+        // Check the new receiving index
+        String indexKey = "receivingIndex";
+        switch (derivePathType) {
+          case DerivePathType.bip44:
+            indexKey += "P2PKH";
+            break;
+          case DerivePathType.bip49:
+            indexKey += "P2SH";
+            break;
+          case DerivePathType.bip84:
+            indexKey += "P2WPKH";
+            break;
+        }
+        final newReceivingIndex =
+            DB.instance.get<dynamic>(boxName: walletId, key: indexKey) as int;
+
+        // Use new index to derive a new receiving address
+        final newReceivingAddress = await _generateAddressForChain(
+            0, newReceivingIndex, derivePathType);
+
+        // Add that new receiving address to the array of receiving addresses
+        await _addToAddressesArrayForChain(
+            newReceivingAddress, 0, derivePathType);
+
+        // Set the new receiving address that the service
+
+        switch (derivePathType) {
+          case DerivePathType.bip44:
+            _currentReceivingAddressP2PKH = Future(() => newReceivingAddress);
+            break;
+          case DerivePathType.bip49:
+            _currentReceivingAddressP2SH = Future(() => newReceivingAddress);
+            break;
+          case DerivePathType.bip84:
+            _currentReceivingAddress = Future(() => newReceivingAddress);
+            break;
+        }
+      }
+    } catch (e, s) {
+      Logging.instance.log(
+          "Exception rethrown from _checkReceivingAddressForTransactions($derivePathType): $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  Future<void> _checkChangeAddressForTransactions(
+      DerivePathType derivePathType) async {
+    try {
+      final String currentExternalAddr =
+          await _getCurrentAddressForChain(1, derivePathType);
+      final int txCount = await getTxCount(address: currentExternalAddr);
+      Logging.instance.log(
+          'Number of txs for current change address $currentExternalAddr: $txCount',
+          level: LogLevel.Info);
+
+      if (txCount >= 1) {
+        // First increment the change index
+        await _incrementAddressIndexForChain(1, derivePathType);
+
+        // Check the new change index
+        String indexKey = "changeIndex";
+        switch (derivePathType) {
+          case DerivePathType.bip44:
+            indexKey += "P2PKH";
+            break;
+          case DerivePathType.bip49:
+            indexKey += "P2SH";
+            break;
+          case DerivePathType.bip84:
+            indexKey += "P2WPKH";
+            break;
+        }
+        final newChangeIndex =
+            DB.instance.get<dynamic>(boxName: walletId, key: indexKey) as int;
+
+        // Use new index to derive a new change address
+        final newChangeAddress =
+            await _generateAddressForChain(1, newChangeIndex, derivePathType);
+
+        // Add that new receiving address to the array of change addresses
+        await _addToAddressesArrayForChain(newChangeAddress, 1, derivePathType);
+      }
+    } on SocketException catch (se, s) {
+      Logging.instance.log(
+          "SocketException caught in _checkReceivingAddressForTransactions($derivePathType): $se\n$s",
+          level: LogLevel.Error);
+      return;
+    } catch (e, s) {
+      Logging.instance.log(
+          "Exception rethrown from _checkReceivingAddressForTransactions($derivePathType): $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  Future<void> _checkCurrentReceivingAddressesForTransactions() async {
+    try {
+      for (final type in DerivePathType.values) {
+        await _checkReceivingAddressForTransactions(type);
+      }
+    } catch (e, s) {
+      Logging.instance.log(
+          "Exception rethrown from _checkCurrentReceivingAddressesForTransactions(): $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  /// public wrapper because dart can't test private...
+  Future<void> checkCurrentReceivingAddressesForTransactions() async {
+    if (Platform.environment["FLUTTER_TEST"] == "true") {
+      try {
+        return _checkCurrentReceivingAddressesForTransactions();
+      } catch (_) {
+        rethrow;
+      }
+    }
+  }
+
+  Future<void> _checkCurrentChangeAddressesForTransactions() async {
+    try {
+      for (final type in DerivePathType.values) {
+        await _checkChangeAddressForTransactions(type);
+      }
+    } catch (e, s) {
+      Logging.instance.log(
+          "Exception rethrown from _checkCurrentChangeAddressesForTransactions(): $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  /// public wrapper because dart can't test private...
+  Future<void> checkCurrentChangeAddressesForTransactions() async {
+    if (Platform.environment["FLUTTER_TEST"] == "true") {
+      try {
+        return _checkCurrentChangeAddressesForTransactions();
+      } catch (_) {
+        rethrow;
+      }
+    }
+  }
+
+  /// attempts to convert a string to a valid scripthash
+  ///
+  /// Returns the scripthash or throws an exception on invalid bitcoin address
+  String _convertToScriptHash(String bitcoinAddress, NetworkType network) {
+    try {
+      final output = Address.addressToOutputScript(bitcoinAddress, network);
+      final hash = sha256.convert(output.toList(growable: false)).toString();
+
+      final chars = hash.split("");
+      final reversedPairs = <String>[];
+      var i = chars.length - 1;
+      while (i > 0) {
+        reversedPairs.add(chars[i - 1]);
+        reversedPairs.add(chars[i]);
+        i -= 2;
+      }
+      return reversedPairs.join("");
+    } catch (e) {
+      rethrow;
+    }
+  }
+
+  Future<List<Map<String, dynamic>>> _fetchHistory(
+      List<String> allAddresses) async {
+    try {
+      List<Map<String, dynamic>> allTxHashes = [];
+
+      final Map<int, Map<String, List<dynamic>>> batches = {};
+      final Map<String, String> requestIdToAddressMap = {};
+      const batchSizeMax = 100;
+      int batchNumber = 0;
+      for (int i = 0; i < allAddresses.length; i++) {
+        if (batches[batchNumber] == null) {
+          batches[batchNumber] = {};
+        }
+        final scripthash = _convertToScriptHash(allAddresses[i], _network);
+        final id = Logger.isTestEnv ? "$i" : const Uuid().v1();
+        requestIdToAddressMap[id] = allAddresses[i];
+        batches[batchNumber]!.addAll({
+          id: [scripthash]
+        });
+        if (i % batchSizeMax == batchSizeMax - 1) {
+          batchNumber++;
+        }
+      }
+
+      for (int i = 0; i < batches.length; i++) {
+        final response =
+            await _electrumXClient.getBatchHistory(args: batches[i]!);
+        for (final entry in response.entries) {
+          for (int j = 0; j < entry.value.length; j++) {
+            entry.value[j]["address"] = requestIdToAddressMap[entry.key];
+            if (!allTxHashes.contains(entry.value[j])) {
+              allTxHashes.add(entry.value[j]);
+            }
+          }
+        }
+      }
+
+      return allTxHashes;
+    } catch (e, s) {
+      Logging.instance.log("_fetchHistory: $e\n$s", level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  bool _duplicateTxCheck(
+      List<Map<String, dynamic>> allTransactions, String txid) {
+    for (int i = 0; i < allTransactions.length; i++) {
+      if (allTransactions[i]["txid"] == txid) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  Future<List<Map<String, dynamic>>> fastFetch(List<String> allTxHashes) async {
+    List<Map<String, dynamic>> allTransactions = [];
+
+    const futureLimit = 30;
+    List<Future<Map<String, dynamic>>> transactionFutures = [];
+    int currentFutureCount = 0;
+    for (final txHash in allTxHashes) {
+      Future<Map<String, dynamic>> transactionFuture =
+          cachedElectrumXClient.getTransaction(
+        txHash: txHash,
+        verbose: true,
+        coin: coin,
+      );
+      transactionFutures.add(transactionFuture);
+      currentFutureCount++;
+      if (currentFutureCount > futureLimit) {
+        currentFutureCount = 0;
+        await Future.wait(transactionFutures);
+        for (final fTx in transactionFutures) {
+          final tx = await fTx;
+
+          allTransactions.add(tx);
+        }
+      }
+    }
+    if (currentFutureCount != 0) {
+      currentFutureCount = 0;
+      await Future.wait(transactionFutures);
+      for (final fTx in transactionFutures) {
+        final tx = await fTx;
+
+        allTransactions.add(tx);
+      }
+    }
+    return allTransactions;
+  }
+
+  Future<TransactionData> _fetchTransactionData() async {
+    final List<String> allAddresses = await _fetchAllOwnAddresses();
+
+    final changeAddresses = DB.instance.get<dynamic>(
+        boxName: walletId, key: 'changeAddressesP2WPKH') as List<dynamic>;
+    final changeAddressesP2PKH =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2PKH')
+            as List<dynamic>;
+    final changeAddressesP2SH =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2SH')
+            as List<dynamic>;
+
+    for (var i = 0; i < changeAddressesP2PKH.length; i++) {
+      changeAddresses.add(changeAddressesP2PKH[i] as String);
+    }
+    for (var i = 0; i < changeAddressesP2SH.length; i++) {
+      changeAddresses.add(changeAddressesP2SH[i] as String);
+    }
+
+    final List<Map<String, dynamic>> allTxHashes =
+        await _fetchHistory(allAddresses);
+
+    final cachedTransactions =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
+            as TransactionData?;
+    int latestTxnBlockHeight =
+        DB.instance.get<dynamic>(boxName: walletId, key: "storedTxnDataHeight")
+                as int? ??
+            0;
+
+    final unconfirmedCachedTransactions =
+        cachedTransactions?.getAllTransactions() ?? {};
+    unconfirmedCachedTransactions
+        .removeWhere((key, value) => value.confirmedStatus);
+
+    if (cachedTransactions != null) {
+      for (final tx in allTxHashes.toList(growable: false)) {
+        final txHeight = tx["height"] as int;
+        if (txHeight > 0 &&
+            txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) {
+          if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) {
+            allTxHashes.remove(tx);
+          }
+        }
+      }
+    }
+
+    Set<String> hashes = {};
+    for (var element in allTxHashes) {
+      hashes.add(element['tx_hash'] as String);
+    }
+    await fastFetch(hashes.toList());
+    List<Map<String, dynamic>> allTransactions = [];
+
+    for (final txHash in allTxHashes) {
+      final tx = await cachedElectrumXClient.getTransaction(
+        txHash: txHash["tx_hash"] as String,
+        verbose: true,
+        coin: coin,
+      );
+
+      // Logging.instance.log("TRANSACTION: ${jsonEncode(tx)}");
+      // TODO fix this for sent to self transactions?
+      if (!_duplicateTxCheck(allTransactions, tx["txid"] as String)) {
+        tx["address"] = txHash["address"];
+        tx["height"] = txHash["height"];
+        allTransactions.add(tx);
+      }
+    }
+
+    Logging.instance.log("addAddresses: $allAddresses", level: LogLevel.Info);
+    Logging.instance.log("allTxHashes: $allTxHashes", level: LogLevel.Info);
+
+    Logging.instance.log("allTransactions length: ${allTransactions.length}",
+        level: LogLevel.Info);
+
+    final priceData =
+        await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency);
+    Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
+    final List<Map<String, dynamic>> midSortedArray = [];
+
+    Set<String> vHashes = {};
+    for (final txObject in allTransactions) {
+      for (int i = 0; i < (txObject["vin"] as List).length; i++) {
+        final input = txObject["vin"]![i] as Map;
+        final prevTxid = input["txid"] as String;
+        vHashes.add(prevTxid);
+      }
+    }
+    await fastFetch(vHashes.toList());
+
+    for (final txObject in allTransactions) {
+      List<String> sendersArray = [];
+      List<String> recipientsArray = [];
+
+      // Usually only has value when txType = 'Send'
+      int inputAmtSentFromWallet = 0;
+      // Usually has value regardless of txType due to change addresses
+      int outputAmtAddressedToWallet = 0;
+      int fee = 0;
+
+      Map<String, dynamic> midSortedTx = {};
+
+      for (int i = 0; i < (txObject["vin"] as List).length; i++) {
+        final input = txObject["vin"]![i] as Map;
+        final prevTxid = input["txid"] as String;
+        final prevOut = input["vout"] as int;
+
+        final tx = await _cachedElectrumXClient.getTransaction(
+          txHash: prevTxid,
+          coin: coin,
+        );
+
+        for (final out in tx["vout"] as List) {
+          if (prevOut == out["n"]) {
+            final address = out["scriptPubKey"]["address"] as String?;
+            if (address != null) {
+              sendersArray.add(address);
+            }
+          }
+        }
+      }
+
+      Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info);
+
+      for (final output in txObject["vout"] as List) {
+        final address = output["scriptPubKey"]["address"] as String?;
+        if (address != null) {
+          recipientsArray.add(address);
+        }
+      }
+
+      Logging.instance
+          .log("recipientsArray: $recipientsArray", level: LogLevel.Info);
+
+      final foundInSenders =
+          allAddresses.any((element) => sendersArray.contains(element));
+      Logging.instance
+          .log("foundInSenders: $foundInSenders", level: LogLevel.Info);
+
+      // If txType = Sent, then calculate inputAmtSentFromWallet
+      if (foundInSenders) {
+        int totalInput = 0;
+        for (int i = 0; i < (txObject["vin"] as List).length; i++) {
+          final input = txObject["vin"]![i] as Map;
+          final prevTxid = input["txid"] as String;
+          final prevOut = input["vout"] as int;
+          final tx = await _cachedElectrumXClient.getTransaction(
+            txHash: prevTxid,
+            coin: coin,
+          );
+
+          for (final out in tx["vout"] as List) {
+            if (prevOut == out["n"]) {
+              inputAmtSentFromWallet +=
+                  (Decimal.parse(out["value"]!.toString()) *
+                          Decimal.fromInt(Constants.satsPerCoin))
+                      .toBigInt()
+                      .toInt();
+            }
+          }
+        }
+        totalInput = inputAmtSentFromWallet;
+        int totalOutput = 0;
+
+        for (final output in txObject["vout"] as List) {
+          final String address = output["scriptPubKey"]!["address"] as String;
+          final value = output["value"]!;
+          final _value = (Decimal.parse(value.toString()) *
+                  Decimal.fromInt(Constants.satsPerCoin))
+              .toBigInt()
+              .toInt();
+          totalOutput += _value;
+          if (changeAddresses.contains(address)) {
+            inputAmtSentFromWallet -= _value;
+          } else {
+            // change address from 'sent from' to the 'sent to' address
+            txObject["address"] = address;
+          }
+        }
+        // calculate transaction fee
+        fee = totalInput - totalOutput;
+        // subtract fee from sent to calculate correct value of sent tx
+        inputAmtSentFromWallet -= fee;
+      } else {
+        // counters for fee calculation
+        int totalOut = 0;
+        int totalIn = 0;
+
+        // add up received tx value
+        for (final output in txObject["vout"] as List) {
+          final address = output["scriptPubKey"]["address"];
+          if (address != null) {
+            final value = (Decimal.parse(output["value"].toString()) *
+                    Decimal.fromInt(Constants.satsPerCoin))
+                .toBigInt()
+                .toInt();
+            totalOut += value;
+            if (allAddresses.contains(address)) {
+              outputAmtAddressedToWallet += value;
+            }
+          }
+        }
+
+        // calculate fee for received tx
+        for (int i = 0; i < (txObject["vin"] as List).length; i++) {
+          final input = txObject["vin"][i] as Map;
+          final prevTxid = input["txid"] as String;
+          final prevOut = input["vout"] as int;
+          final tx = await _cachedElectrumXClient.getTransaction(
+            txHash: prevTxid,
+            coin: coin,
+          );
+
+          for (final out in tx["vout"] as List) {
+            if (prevOut == out["n"]) {
+              totalIn += (Decimal.parse(out["value"].toString()) *
+                      Decimal.fromInt(Constants.satsPerCoin))
+                  .toBigInt()
+                  .toInt();
+            }
+          }
+        }
+        fee = totalIn - totalOut;
+      }
+
+      // create final tx map
+      midSortedTx["txid"] = txObject["txid"];
+      midSortedTx["confirmed_status"] = (txObject["confirmations"] != null) &&
+          (txObject["confirmations"] as int >= MINIMUM_CONFIRMATIONS);
+      midSortedTx["confirmations"] = txObject["confirmations"] ?? 0;
+      midSortedTx["timestamp"] = txObject["blocktime"] ??
+          (DateTime.now().millisecondsSinceEpoch ~/ 1000);
+
+      if (foundInSenders) {
+        midSortedTx["txType"] = "Sent";
+        midSortedTx["amount"] = inputAmtSentFromWallet;
+        final String worthNow =
+            ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
+                    Decimal.fromInt(Constants.satsPerCoin))
+                .toDecimal(scaleOnInfinitePrecision: 2)
+                .toStringAsFixed(2);
+        midSortedTx["worthNow"] = worthNow;
+        midSortedTx["worthAtBlockTimestamp"] = worthNow;
+      } else {
+        midSortedTx["txType"] = "Received";
+        midSortedTx["amount"] = outputAmtAddressedToWallet;
+        final worthNow =
+            ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
+                    Decimal.fromInt(Constants.satsPerCoin))
+                .toDecimal(scaleOnInfinitePrecision: 2)
+                .toStringAsFixed(2);
+        midSortedTx["worthNow"] = worthNow;
+      }
+      midSortedTx["aliens"] = <dynamic>[];
+      midSortedTx["fees"] = fee;
+      midSortedTx["address"] = txObject["address"];
+      midSortedTx["inputSize"] = txObject["vin"].length;
+      midSortedTx["outputSize"] = txObject["vout"].length;
+      midSortedTx["inputs"] = txObject["vin"];
+      midSortedTx["outputs"] = txObject["vout"];
+
+      final int height = txObject["height"] as int;
+      midSortedTx["height"] = height;
+
+      if (height >= latestTxnBlockHeight) {
+        latestTxnBlockHeight = height;
+      }
+
+      midSortedArray.add(midSortedTx);
+    }
+
+    // sort by date  ----  //TODO not sure if needed
+    // shouldn't be any issues with a null timestamp but I got one at some point?
+    midSortedArray
+        .sort((a, b) => (b["timestamp"] as int) - (a["timestamp"] as int));
+    // {
+    //   final aT = a["timestamp"];
+    //   final bT = b["timestamp"];
+    //
+    //   if (aT == null && bT == null) {
+    //     return 0;
+    //   } else if (aT == null) {
+    //     return -1;
+    //   } else if (bT == null) {
+    //     return 1;
+    //   } else {
+    //     return bT - aT;
+    //   }
+    // });
+
+    // buildDateTimeChunks
+    final Map<String, dynamic> result = {"dateTimeChunks": <dynamic>[]};
+    final dateArray = <dynamic>[];
+
+    for (int i = 0; i < midSortedArray.length; i++) {
+      final txObject = midSortedArray[i];
+      final date = extractDateFromTimestamp(txObject["timestamp"] as int);
+      final txTimeArray = [txObject["timestamp"], date];
+
+      if (dateArray.contains(txTimeArray[1])) {
+        result["dateTimeChunks"].forEach((dynamic chunk) {
+          if (extractDateFromTimestamp(chunk["timestamp"] as int) ==
+              txTimeArray[1]) {
+            if (chunk["transactions"] == null) {
+              chunk["transactions"] = <Map<String, dynamic>>[];
+            }
+            chunk["transactions"].add(txObject);
+          }
+        });
+      } else {
+        dateArray.add(txTimeArray[1]);
+        final chunk = {
+          "timestamp": txTimeArray[0],
+          "transactions": [txObject],
+        };
+        result["dateTimeChunks"].add(chunk);
+      }
+    }
+
+    final transactionsMap = cachedTransactions?.getAllTransactions() ?? {};
+    transactionsMap
+        .addAll(TransactionData.fromJson(result).getAllTransactions());
+
+    final txModel = TransactionData.fromMap(transactionsMap);
+
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'storedTxnDataHeight',
+        value: latestTxnBlockHeight);
+    await DB.instance.put<dynamic>(
+        boxName: walletId, key: 'latest_tx_model', value: txModel);
+
+    return txModel;
+  }
+
+  int estimateTxFee({required int vSize, required int feeRatePerKB}) {
+    return vSize * (feeRatePerKB / 1000).ceil();
+  }
+
+  /// The coinselection algorithm decides whether or not the user is eligible to make the transaction
+  /// with [satoshiAmountToSend] and [selectedTxFeeRate]. If so, it will call buildTrasaction() and return
+  /// a map containing the tx hex along with other important information. If not, then it will return
+  /// an integer (1 or 2)
+  dynamic coinSelection(
+    int satoshiAmountToSend,
+    int selectedTxFeeRate,
+    String _recipientAddress,
+    bool isSendAll, {
+    int additionalOutputs = 0,
+    List<UtxoObject>? utxos,
+  }) async {
+    Logging.instance
+        .log("Starting coinSelection ----------", level: LogLevel.Info);
+    final List<UtxoObject> availableOutputs = utxos ?? outputsList;
+    final List<UtxoObject> 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].blocked == false &&
+          availableOutputs[i].status.confirmed == true) {
+        spendableOutputs.add(availableOutputs[i]);
+        spendableSatoshiValue += availableOutputs[i].value;
+      }
+    }
+
+    // sort spendable by age (oldest first)
+    spendableOutputs.sort(
+        (a, b) => b.status.confirmations.compareTo(a.status.confirmations));
+
+    Logging.instance.log("spendableOutputs.length: ${spendableOutputs.length}",
+        level: LogLevel.Info);
+    Logging.instance
+        .log("spendableOutputs: $spendableOutputs", level: LogLevel.Info);
+    Logging.instance.log("spendableSatoshiValue: $spendableSatoshiValue",
+        level: LogLevel.Info);
+    Logging.instance
+        .log("satoshiAmountToSend: $satoshiAmountToSend", level: LogLevel.Info);
+    // If the amount the user is trying to send is smaller than the amount that they have spendable,
+    // then return 1, which indicates that they have an insufficient balance.
+    if (spendableSatoshiValue < satoshiAmountToSend) {
+      return 1;
+      // If the amount the user wants to send is exactly equal to the amount they can spend, then return
+      // 2, which indicates that they are not leaving enough over to pay the transaction fee
+    } else if (spendableSatoshiValue == satoshiAmountToSend && !isSendAll) {
+      return 2;
+    }
+    // If neither of these statements pass, we assume that the user has a spendable balance greater
+    // than the amount they're attempting to send. Note that this value still does not account for
+    // the added transaction fee, which may require an extra input and will need to be checked for
+    // later on.
+
+    // Possible situation right here
+    int satoshisBeingUsed = 0;
+    int inputsBeingConsumed = 0;
+    List<UtxoObject> utxoObjectsToUse = [];
+
+    for (var i = 0;
+        satoshisBeingUsed < satoshiAmountToSend && i < spendableOutputs.length;
+        i++) {
+      utxoObjectsToUse.add(spendableOutputs[i]);
+      satoshisBeingUsed += spendableOutputs[i].value;
+      inputsBeingConsumed += 1;
+    }
+    for (int i = 0;
+        i < additionalOutputs && inputsBeingConsumed < spendableOutputs.length;
+        i++) {
+      utxoObjectsToUse.add(spendableOutputs[inputsBeingConsumed]);
+      satoshisBeingUsed += spendableOutputs[inputsBeingConsumed].value;
+      inputsBeingConsumed += 1;
+    }
+
+    Logging.instance
+        .log("satoshisBeingUsed: $satoshisBeingUsed", level: LogLevel.Info);
+    Logging.instance
+        .log("inputsBeingConsumed: $inputsBeingConsumed", level: LogLevel.Info);
+    Logging.instance
+        .log('utxoObjectsToUse: $utxoObjectsToUse', level: LogLevel.Info);
+
+    // numberOfOutputs' length must always be equal to that of recipientsArray and recipientsAmtArray
+    List<String> recipientsArray = [_recipientAddress];
+    List<int> recipientsAmtArray = [satoshiAmountToSend];
+
+    // gather required signing data
+    final utxoSigningData = await fetchBuildTxData(utxoObjectsToUse);
+
+    if (isSendAll) {
+      Logging.instance
+          .log("Attempting to send all $coin", level: LogLevel.Info);
+
+      final int vSizeForOneOutput = (await buildTransaction(
+        utxosToUse: utxoObjectsToUse,
+        utxoSigningData: utxoSigningData,
+        recipients: [_recipientAddress],
+        satoshiAmounts: [satoshisBeingUsed - 1],
+      ))["vSize"] as int;
+      int feeForOneOutput = estimateTxFee(
+        vSize: vSizeForOneOutput,
+        feeRatePerKB: selectedTxFeeRate,
+      );
+
+      final int roughEstimate =
+          roughFeeEstimate(spendableOutputs.length, 1, selectedTxFeeRate);
+      if (feeForOneOutput < roughEstimate) {
+        feeForOneOutput = roughEstimate;
+      }
+
+      final int amount = satoshiAmountToSend - feeForOneOutput;
+      dynamic txn = await buildTransaction(
+        utxosToUse: utxoObjectsToUse,
+        utxoSigningData: utxoSigningData,
+        recipients: recipientsArray,
+        satoshiAmounts: [amount],
+      );
+      Map<String, dynamic> transactionObject = {
+        "hex": txn["hex"],
+        "recipient": recipientsArray[0],
+        "recipientAmt": amount,
+        "fee": feeForOneOutput,
+        "vSize": txn["vSize"],
+      };
+      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;
+
+    // Assume 1 output, only for recipient and no change
+    final feeForOneOutput = estimateTxFee(
+      vSize: vSizeForOneOutput,
+      feeRatePerKB: selectedTxFeeRate,
+    );
+    // Assume 2 outputs, one for recipient and one for change
+    final feeForTwoOutputs = estimateTxFee(
+      vSize: vSizeForTwoOutPuts,
+      feeRatePerKB: selectedTxFeeRate,
+    );
+
+    Logging.instance
+        .log("feeForTwoOutputs: $feeForTwoOutputs", level: LogLevel.Info);
+    Logging.instance
+        .log("feeForOneOutput: $feeForOneOutput", level: LogLevel.Info);
+
+    if (satoshisBeingUsed - satoshiAmountToSend > feeForOneOutput) {
+      if (satoshisBeingUsed - satoshiAmountToSend >
+          feeForOneOutput + DUST_LIMIT) {
+        // Here, we know that theoretically, we may be able to include another output(change) but we first need to
+        // factor in the value of this output in satoshis.
+        int changeOutputSize =
+            satoshisBeingUsed - satoshiAmountToSend - feeForTwoOutputs;
+        // We check to see if the user can pay for the new transaction with 2 outputs instead of one. If they can and
+        // the second output's size > DUST_LIMIT satoshis, we perform the mechanics required to properly generate and use a new
+        // change address.
+        if (changeOutputSize > DUST_LIMIT &&
+            satoshisBeingUsed - satoshiAmountToSend - changeOutputSize ==
+                feeForTwoOutputs) {
+          // generate new change address if current change address has been used
+          await _checkChangeAddressForTransactions(DerivePathType.bip84);
+          final String newChangeAddress =
+              await _getCurrentAddressForChain(1, DerivePathType.bip84);
+
+          int feeBeingPaid =
+              satoshisBeingUsed - satoshiAmountToSend - changeOutputSize;
+
+          recipientsArray.add(newChangeAddress);
+          recipientsAmtArray.add(changeOutputSize);
+          // At this point, we have the outputs we're going to use, the amounts to send along with which addresses
+          // we intend to send these amounts to. We have enough to send instructions to build the transaction.
+          Logging.instance.log('2 outputs in tx', level: LogLevel.Info);
+          Logging.instance
+              .log('Input size: $satoshisBeingUsed', level: LogLevel.Info);
+          Logging.instance.log('Recipient output size: $satoshiAmountToSend',
+              level: LogLevel.Info);
+          Logging.instance.log('Change Output Size: $changeOutputSize',
+              level: LogLevel.Info);
+          Logging.instance.log(
+              'Difference (fee being paid): $feeBeingPaid sats',
+              level: LogLevel.Info);
+          Logging.instance
+              .log('Estimated fee: $feeForTwoOutputs', level: LogLevel.Info);
+          dynamic txn = await buildTransaction(
+            utxosToUse: utxoObjectsToUse,
+            utxoSigningData: utxoSigningData,
+            recipients: recipientsArray,
+            satoshiAmounts: recipientsAmtArray,
+          );
+
+          // make sure minimum fee is accurate if that is being used
+          if (txn["vSize"] - feeBeingPaid == 1) {
+            int changeOutputSize =
+                satoshisBeingUsed - satoshiAmountToSend - (txn["vSize"] as int);
+            feeBeingPaid =
+                satoshisBeingUsed - satoshiAmountToSend - changeOutputSize;
+            recipientsAmtArray.removeLast();
+            recipientsAmtArray.add(changeOutputSize);
+            Logging.instance.log('Adjusted Input size: $satoshisBeingUsed',
+                level: LogLevel.Info);
+            Logging.instance.log(
+                'Adjusted Recipient output size: $satoshiAmountToSend',
+                level: LogLevel.Info);
+            Logging.instance.log(
+                'Adjusted Change Output Size: $changeOutputSize',
+                level: LogLevel.Info);
+            Logging.instance.log(
+                'Adjusted Difference (fee being paid): $feeBeingPaid sats',
+                level: LogLevel.Info);
+            Logging.instance.log('Adjusted Estimated fee: $feeForTwoOutputs',
+                level: LogLevel.Info);
+            txn = await buildTransaction(
+              utxosToUse: utxoObjectsToUse,
+              utxoSigningData: utxoSigningData,
+              recipients: recipientsArray,
+              satoshiAmounts: recipientsAmtArray,
+            );
+          }
+
+          Map<String, dynamic> transactionObject = {
+            "hex": txn["hex"],
+            "recipient": recipientsArray[0],
+            "recipientAmt": recipientsAmtArray[0],
+            "fee": feeBeingPaid,
+            "vSize": txn["vSize"],
+          };
+          return transactionObject;
+        } else {
+          // Something went wrong here. It either overshot or undershot the estimated fee amount or the changeOutputSize
+          // is smaller than or equal to DUST_LIMIT. Revert to single output transaction.
+          Logging.instance.log('1 output in tx', level: LogLevel.Info);
+          Logging.instance
+              .log('Input size: $satoshisBeingUsed', level: LogLevel.Info);
+          Logging.instance.log('Recipient output size: $satoshiAmountToSend',
+              level: LogLevel.Info);
+          Logging.instance.log(
+              'Difference (fee being paid): ${satoshisBeingUsed - satoshiAmountToSend} sats',
+              level: LogLevel.Info);
+          Logging.instance
+              .log('Estimated fee: $feeForOneOutput', level: LogLevel.Info);
+          dynamic txn = await buildTransaction(
+            utxosToUse: utxoObjectsToUse,
+            utxoSigningData: utxoSigningData,
+            recipients: recipientsArray,
+            satoshiAmounts: recipientsAmtArray,
+          );
+          Map<String, dynamic> transactionObject = {
+            "hex": txn["hex"],
+            "recipient": recipientsArray[0],
+            "recipientAmt": recipientsAmtArray[0],
+            "fee": satoshisBeingUsed - satoshiAmountToSend,
+            "vSize": txn["vSize"],
+          };
+          return transactionObject;
+        }
+      } else {
+        // No additional outputs needed since adding one would mean that it'd be smaller than DUST_LIMIT sats
+        // which makes it uneconomical to add to the transaction. Here, we pass data directly to instruct
+        // the wallet to begin crafting the transaction that the user requested.
+        Logging.instance.log('1 output in tx', level: LogLevel.Info);
+        Logging.instance
+            .log('Input size: $satoshisBeingUsed', level: LogLevel.Info);
+        Logging.instance.log('Recipient output size: $satoshiAmountToSend',
+            level: LogLevel.Info);
+        Logging.instance.log(
+            'Difference (fee being paid): ${satoshisBeingUsed - satoshiAmountToSend} sats',
+            level: LogLevel.Info);
+        Logging.instance
+            .log('Estimated fee: $feeForOneOutput', level: LogLevel.Info);
+        dynamic txn = await buildTransaction(
+          utxosToUse: utxoObjectsToUse,
+          utxoSigningData: utxoSigningData,
+          recipients: recipientsArray,
+          satoshiAmounts: recipientsAmtArray,
+        );
+        Map<String, dynamic> transactionObject = {
+          "hex": txn["hex"],
+          "recipient": recipientsArray[0],
+          "recipientAmt": recipientsAmtArray[0],
+          "fee": satoshisBeingUsed - satoshiAmountToSend,
+          "vSize": txn["vSize"],
+        };
+        return transactionObject;
+      }
+    } else if (satoshisBeingUsed - satoshiAmountToSend == feeForOneOutput) {
+      // In this scenario, no additional change output is needed since inputs - outputs equal exactly
+      // what we need to pay for fees. Here, we pass data directly to instruct the wallet to begin
+      // crafting the transaction that the user requested.
+      Logging.instance.log('1 output in tx', level: LogLevel.Info);
+      Logging.instance
+          .log('Input size: $satoshisBeingUsed', level: LogLevel.Info);
+      Logging.instance.log('Recipient output size: $satoshiAmountToSend',
+          level: LogLevel.Info);
+      Logging.instance.log(
+          'Fee being paid: ${satoshisBeingUsed - satoshiAmountToSend} sats',
+          level: LogLevel.Info);
+      Logging.instance
+          .log('Estimated fee: $feeForOneOutput', level: LogLevel.Info);
+      dynamic txn = await buildTransaction(
+        utxosToUse: utxoObjectsToUse,
+        utxoSigningData: utxoSigningData,
+        recipients: recipientsArray,
+        satoshiAmounts: recipientsAmtArray,
+      );
+      Map<String, dynamic> transactionObject = {
+        "hex": txn["hex"],
+        "recipient": recipientsArray[0],
+        "recipientAmt": recipientsAmtArray[0],
+        "fee": feeForOneOutput,
+        "vSize": txn["vSize"],
+      };
+      return transactionObject;
+    } else {
+      // Remember that returning 2 indicates that the user does not have a sufficient balance to
+      // pay for the transaction fee. Ideally, at this stage, we should check if the user has any
+      // additional outputs they're able to spend and then recalculate fees.
+      Logging.instance.log(
+          'Cannot pay tx fee - checking for more outputs and trying again',
+          level: LogLevel.Warning);
+      // try adding more outputs
+      if (spendableOutputs.length > inputsBeingConsumed) {
+        return coinSelection(satoshiAmountToSend, selectedTxFeeRate,
+            _recipientAddress, isSendAll,
+            additionalOutputs: additionalOutputs + 1, utxos: utxos);
+      }
+      return 2;
+    }
+  }
+
+  Future<Map<String, dynamic>> fetchBuildTxData(
+    List<UtxoObject> utxosToUse,
+  ) async {
+    // return data
+    Map<String, dynamic> results = {};
+    Map<String, List<String>> addressTxid = {};
+
+    // addresses to check
+    List<String> addressesP2PKH = [];
+    List<String> addressesP2SH = [];
+    List<String> addressesP2WPKH = [];
+
+    try {
+      // Populating the addresses to check
+      for (var i = 0; i < utxosToUse.length; i++) {
+        final txid = utxosToUse[i].txid;
+        final tx = await _cachedElectrumXClient.getTransaction(
+          txHash: txid,
+          coin: coin,
+        );
+
+        for (final output in tx["vout"] as List) {
+          final n = output["n"];
+          if (n != null && n == utxosToUse[i].vout) {
+            final address = output["scriptPubKey"]["address"] as String;
+            if (!addressTxid.containsKey(address)) {
+              addressTxid[address] = <String>[];
+            }
+            (addressTxid[address] as List).add(txid);
+            switch (addressType(address: address)) {
+              case DerivePathType.bip44:
+                addressesP2PKH.add(address);
+                break;
+              case DerivePathType.bip49:
+                addressesP2SH.add(address);
+                break;
+              case DerivePathType.bip84:
+                addressesP2WPKH.add(address);
+                break;
+            }
+          }
+        }
+      }
+
+      // p2pkh / bip44
+      final p2pkhLength = addressesP2PKH.length;
+      if (p2pkhLength > 0) {
+        final receiveDerivations = await _fetchDerivations(
+          chain: 0,
+          derivePathType: DerivePathType.bip44,
+        );
+        final changeDerivations = await _fetchDerivations(
+          chain: 1,
+          derivePathType: DerivePathType.bip44,
+        );
+        for (int i = 0; i < p2pkhLength; i++) {
+          // receives
+          final receiveDerivation = receiveDerivations[addressesP2PKH[i]];
+          // if a match exists it will not be null
+          if (receiveDerivation != null) {
+            final data = P2PKH(
+              data: PaymentData(
+                  pubkey: Format.stringToUint8List(
+                      receiveDerivation["pubKey"] as String)),
+              network: _network,
+            ).data;
+
+            for (String tx in addressTxid[addressesP2PKH[i]]!) {
+              results[tx] = {
+                "output": data.output,
+                "keyPair": ECPair.fromWIF(
+                  receiveDerivation["wif"] as String,
+                  network: _network,
+                ),
+              };
+            }
+          } else {
+            // if its not a receive, check change
+            final changeDerivation = changeDerivations[addressesP2PKH[i]];
+            // if a match exists it will not be null
+            if (changeDerivation != null) {
+              final data = P2PKH(
+                data: PaymentData(
+                    pubkey: Format.stringToUint8List(
+                        changeDerivation["pubKey"] as String)),
+                network: _network,
+              ).data;
+
+              for (String tx in addressTxid[addressesP2PKH[i]]!) {
+                results[tx] = {
+                  "output": data.output,
+                  "keyPair": ECPair.fromWIF(
+                    changeDerivation["wif"] as String,
+                    network: _network,
+                  ),
+                };
+              }
+            }
+          }
+        }
+      }
+
+      // p2sh / bip49
+      final p2shLength = addressesP2SH.length;
+      if (p2shLength > 0) {
+        final receiveDerivations = await _fetchDerivations(
+          chain: 0,
+          derivePathType: DerivePathType.bip49,
+        );
+        final changeDerivations = await _fetchDerivations(
+          chain: 1,
+          derivePathType: DerivePathType.bip49,
+        );
+        for (int i = 0; i < p2shLength; i++) {
+          // receives
+          final receiveDerivation = receiveDerivations[addressesP2SH[i]];
+          // if a match exists it will not be null
+          if (receiveDerivation != null) {
+            final p2wpkh = P2WPKH(
+                    data: PaymentData(
+                        pubkey: Format.stringToUint8List(
+                            receiveDerivation["pubKey"] as String)),
+                    network: _network)
+                .data;
+
+            final redeemScript = p2wpkh.output;
+
+            final data =
+                P2SH(data: PaymentData(redeem: p2wpkh), network: _network).data;
+
+            for (String tx in addressTxid[addressesP2SH[i]]!) {
+              results[tx] = {
+                "output": data.output,
+                "keyPair": ECPair.fromWIF(
+                  receiveDerivation["wif"] as String,
+                  network: _network,
+                ),
+                "redeemScript": redeemScript,
+              };
+            }
+          } else {
+            // if its not a receive, check change
+            final changeDerivation = changeDerivations[addressesP2SH[i]];
+            // if a match exists it will not be null
+            if (changeDerivation != null) {
+              final p2wpkh = P2WPKH(
+                      data: PaymentData(
+                          pubkey: Format.stringToUint8List(
+                              changeDerivation["pubKey"] as String)),
+                      network: _network)
+                  .data;
+
+              final redeemScript = p2wpkh.output;
+
+              final data =
+                  P2SH(data: PaymentData(redeem: p2wpkh), network: _network)
+                      .data;
+
+              for (String tx in addressTxid[addressesP2SH[i]]!) {
+                results[tx] = {
+                  "output": data.output,
+                  "keyPair": ECPair.fromWIF(
+                    changeDerivation["wif"] as String,
+                    network: _network,
+                  ),
+                  "redeemScript": redeemScript,
+                };
+              }
+            }
+          }
+        }
+      }
+
+      // p2wpkh / bip84
+      final p2wpkhLength = addressesP2WPKH.length;
+      if (p2wpkhLength > 0) {
+        final receiveDerivations = await _fetchDerivations(
+          chain: 0,
+          derivePathType: DerivePathType.bip84,
+        );
+        final changeDerivations = await _fetchDerivations(
+          chain: 1,
+          derivePathType: DerivePathType.bip84,
+        );
+
+        for (int i = 0; i < p2wpkhLength; i++) {
+          // receives
+          final receiveDerivation = receiveDerivations[addressesP2WPKH[i]];
+          // if a match exists it will not be null
+          if (receiveDerivation != null) {
+            final data = P2WPKH(
+              data: PaymentData(
+                  pubkey: Format.stringToUint8List(
+                      receiveDerivation["pubKey"] as String)),
+              network: _network,
+            ).data;
+
+            for (String tx in addressTxid[addressesP2WPKH[i]]!) {
+              results[tx] = {
+                "output": data.output,
+                "keyPair": ECPair.fromWIF(
+                  receiveDerivation["wif"] as String,
+                  network: _network,
+                ),
+              };
+            }
+          } else {
+            // if its not a receive, check change
+            final changeDerivation = changeDerivations[addressesP2WPKH[i]];
+            // if a match exists it will not be null
+            if (changeDerivation != null) {
+              final data = P2WPKH(
+                data: PaymentData(
+                    pubkey: Format.stringToUint8List(
+                        changeDerivation["pubKey"] as String)),
+                network: _network,
+              ).data;
+
+              for (String tx in addressTxid[addressesP2WPKH[i]]!) {
+                results[tx] = {
+                  "output": data.output,
+                  "keyPair": ECPair.fromWIF(
+                    changeDerivation["wif"] as String,
+                    network: _network,
+                  ),
+                };
+              }
+            }
+          }
+        }
+      }
+
+      return results;
+    } catch (e, s) {
+      Logging.instance
+          .log("fetchBuildTxData() threw: $e,\n$s", level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  /// Builds and signs a transaction
+  Future<Map<String, dynamic>> buildTransaction({
+    required List<UtxoObject> utxosToUse,
+    required Map<String, dynamic> utxoSigningData,
+    required List<String> recipients,
+    required List<int> satoshiAmounts,
+  }) async {
+    Logging.instance
+        .log("Starting buildTransaction ----------", level: LogLevel.Info);
+
+    final txb = TransactionBuilder(network: _network);
+    txb.setVersion(1);
+
+    // Add transaction inputs
+    for (var i = 0; i < utxosToUse.length; i++) {
+      final txid = utxosToUse[i].txid;
+      txb.addInput(txid, utxosToUse[i].vout, null,
+          utxoSigningData[txid]["output"] as Uint8List);
+    }
+
+    // Add transaction output
+    for (var i = 0; i < recipients.length; i++) {
+      txb.addOutput(recipients[i], satoshiAmounts[i]);
+    }
+
+    try {
+      // Sign the transaction accordingly
+      for (var i = 0; i < utxosToUse.length; i++) {
+        final txid = utxosToUse[i].txid;
+        txb.sign(
+          vin: i,
+          keyPair: utxoSigningData[txid]["keyPair"] as ECPair,
+          witnessValue: utxosToUse[i].value,
+          redeemScript: utxoSigningData[txid]["redeemScript"] as Uint8List?,
+        );
+      }
+    } catch (e, s) {
+      Logging.instance.log("Caught exception while signing transaction: $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+
+    final builtTx = txb.build();
+    final vSize = builtTx.virtualSize();
+
+    return {"hex": builtTx.toHex(), "vSize": vSize};
+  }
+
+  @override
+  Future<void> fullRescan(
+    int maxUnusedAddressGap,
+    int maxNumberOfIndexesToCheck,
+  ) async {
+    Logging.instance.log("Starting full rescan!", level: LogLevel.Info);
+    longMutex = true;
+    GlobalEventBus.instance.fire(
+      WalletSyncStatusChangedEvent(
+        WalletSyncStatus.syncing,
+        walletId,
+        coin,
+      ),
+    );
+
+    // clear cache
+    await _cachedElectrumXClient.clearSharedTransactionCache(coin: coin);
+
+    // back up data
+    await _rescanBackup();
+
+    try {
+      final mnemonic = await _secureStore.read(key: '${_walletId}_mnemonic');
+      await _recoverWalletFromBIP32SeedPhrase(
+        mnemonic: mnemonic!,
+        maxUnusedAddressGap: maxUnusedAddressGap,
+        maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck,
+      );
+
+      longMutex = false;
+      Logging.instance.log("Full rescan complete!", level: LogLevel.Info);
+      GlobalEventBus.instance.fire(
+        WalletSyncStatusChangedEvent(
+          WalletSyncStatus.synced,
+          walletId,
+          coin,
+        ),
+      );
+    } catch (e, s) {
+      GlobalEventBus.instance.fire(
+        WalletSyncStatusChangedEvent(
+          WalletSyncStatus.unableToSync,
+          walletId,
+          coin,
+        ),
+      );
+
+      // restore from backup
+      await _rescanRestore();
+
+      longMutex = false;
+      Logging.instance.log("Exception rethrown from fullRescan(): $e\n$s",
+          level: LogLevel.Error);
+      rethrow;
+    }
+  }
+
+  Future<void> _rescanRestore() async {
+    Logging.instance.log("starting rescan restore", level: LogLevel.Info);
+
+    // restore from backup
+    // p2pkh
+    final tempReceivingAddressesP2PKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'receivingAddressesP2PKH_BACKUP');
+    final tempChangeAddressesP2PKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'changeAddressesP2PKH_BACKUP');
+    final tempReceivingIndexP2PKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'receivingIndexP2PKH_BACKUP');
+    final tempChangeIndexP2PKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'changeIndexP2PKH_BACKUP');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingAddressesP2PKH',
+        value: tempReceivingAddressesP2PKH);
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeAddressesP2PKH',
+        value: tempChangeAddressesP2PKH);
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingIndexP2PKH',
+        value: tempReceivingIndexP2PKH);
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeIndexP2PKH',
+        value: tempChangeIndexP2PKH);
+    await DB.instance.delete<dynamic>(
+        key: 'receivingAddressesP2PKH_BACKUP', boxName: walletId);
+    await DB.instance
+        .delete<dynamic>(key: 'changeAddressesP2PKH_BACKUP', boxName: walletId);
+    await DB.instance
+        .delete<dynamic>(key: 'receivingIndexP2PKH_BACKUP', boxName: walletId);
+    await DB.instance
+        .delete<dynamic>(key: 'changeIndexP2PKH_BACKUP', boxName: walletId);
+
+    // p2Sh
+    final tempReceivingAddressesP2SH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'receivingAddressesP2SH_BACKUP');
+    final tempChangeAddressesP2SH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'changeAddressesP2SH_BACKUP');
+    final tempReceivingIndexP2SH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'receivingIndexP2SH_BACKUP');
+    final tempChangeIndexP2SH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'changeIndexP2SH_BACKUP');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingAddressesP2SH',
+        value: tempReceivingAddressesP2SH);
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeAddressesP2SH',
+        value: tempChangeAddressesP2SH);
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingIndexP2SH',
+        value: tempReceivingIndexP2SH);
+    await DB.instance.put<dynamic>(
+        boxName: walletId, key: 'changeIndexP2SH', value: tempChangeIndexP2SH);
+    await DB.instance.delete<dynamic>(
+        key: 'receivingAddressesP2SH_BACKUP', boxName: walletId);
+    await DB.instance
+        .delete<dynamic>(key: 'changeAddressesP2SH_BACKUP', boxName: walletId);
+    await DB.instance
+        .delete<dynamic>(key: 'receivingIndexP2SH_BACKUP', boxName: walletId);
+    await DB.instance
+        .delete<dynamic>(key: 'changeIndexP2SH_BACKUP', boxName: walletId);
+
+    // p2wpkh
+    final tempReceivingAddressesP2WPKH = DB.instance.get<dynamic>(
+        boxName: walletId, key: 'receivingAddressesP2WPKH_BACKUP');
+    final tempChangeAddressesP2WPKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'changeAddressesP2WPKH_BACKUP');
+    final tempReceivingIndexP2WPKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'receivingIndexP2WPKH_BACKUP');
+    final tempChangeIndexP2WPKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'changeIndexP2WPKH_BACKUP');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingAddressesP2WPKH',
+        value: tempReceivingAddressesP2WPKH);
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeAddressesP2WPKH',
+        value: tempChangeAddressesP2WPKH);
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingIndexP2WPKH',
+        value: tempReceivingIndexP2WPKH);
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeIndexP2WPKH',
+        value: tempChangeIndexP2WPKH);
+    await DB.instance.delete<dynamic>(
+        key: 'receivingAddressesP2WPKH_BACKUP', boxName: walletId);
+    await DB.instance.delete<dynamic>(
+        key: 'changeAddressesP2WPKH_BACKUP', boxName: walletId);
+    await DB.instance
+        .delete<dynamic>(key: 'receivingIndexP2WPKH_BACKUP', boxName: walletId);
+    await DB.instance
+        .delete<dynamic>(key: 'changeIndexP2WPKH_BACKUP', boxName: walletId);
+
+    // P2PKH derivations
+    final p2pkhReceiveDerivationsString = await _secureStore.read(
+        key: "${walletId}_receiveDerivationsP2PKH_BACKUP");
+    final p2pkhChangeDerivationsString = await _secureStore.read(
+        key: "${walletId}_changeDerivationsP2PKH_BACKUP");
+
+    await _secureStore.write(
+        key: "${walletId}_receiveDerivationsP2PKH",
+        value: p2pkhReceiveDerivationsString);
+    await _secureStore.write(
+        key: "${walletId}_changeDerivationsP2PKH",
+        value: p2pkhChangeDerivationsString);
+
+    await _secureStore.delete(
+        key: "${walletId}_receiveDerivationsP2PKH_BACKUP");
+    await _secureStore.delete(key: "${walletId}_changeDerivationsP2PKH_BACKUP");
+
+    // P2SH derivations
+    final p2shReceiveDerivationsString = await _secureStore.read(
+        key: "${walletId}_receiveDerivationsP2SH_BACKUP");
+    final p2shChangeDerivationsString = await _secureStore.read(
+        key: "${walletId}_changeDerivationsP2SH_BACKUP");
+
+    await _secureStore.write(
+        key: "${walletId}_receiveDerivationsP2SH",
+        value: p2shReceiveDerivationsString);
+    await _secureStore.write(
+        key: "${walletId}_changeDerivationsP2SH",
+        value: p2shChangeDerivationsString);
+
+    await _secureStore.delete(key: "${walletId}_receiveDerivationsP2SH_BACKUP");
+    await _secureStore.delete(key: "${walletId}_changeDerivationsP2SH_BACKUP");
+
+    // P2WPKH derivations
+    final p2wpkhReceiveDerivationsString = await _secureStore.read(
+        key: "${walletId}_receiveDerivationsP2WPKH_BACKUP");
+    final p2wpkhChangeDerivationsString = await _secureStore.read(
+        key: "${walletId}_changeDerivationsP2WPKH_BACKUP");
+
+    await _secureStore.write(
+        key: "${walletId}_receiveDerivationsP2WPKH",
+        value: p2wpkhReceiveDerivationsString);
+    await _secureStore.write(
+        key: "${walletId}_changeDerivationsP2WPKH",
+        value: p2wpkhChangeDerivationsString);
+
+    await _secureStore.delete(
+        key: "${walletId}_receiveDerivationsP2WPKH_BACKUP");
+    await _secureStore.delete(
+        key: "${walletId}_changeDerivationsP2WPKH_BACKUP");
+
+    // UTXOs
+    final utxoData = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'latest_utxo_model_BACKUP');
+    await DB.instance.put<dynamic>(
+        boxName: walletId, key: 'latest_utxo_model', value: utxoData);
+    await DB.instance
+        .delete<dynamic>(key: 'latest_utxo_model_BACKUP', boxName: walletId);
+
+    Logging.instance.log("rescan restore  complete", level: LogLevel.Info);
+  }
+
+  Future<void> _rescanBackup() async {
+    Logging.instance.log("starting rescan backup", level: LogLevel.Info);
+
+    // backup current and clear data
+    // p2pkh
+    final tempReceivingAddressesP2PKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'receivingAddressesP2PKH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingAddressesP2PKH_BACKUP',
+        value: tempReceivingAddressesP2PKH);
+    await DB.instance
+        .delete<dynamic>(key: 'receivingAddressesP2PKH', boxName: walletId);
+
+    final tempChangeAddressesP2PKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'changeAddressesP2PKH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeAddressesP2PKH_BACKUP',
+        value: tempChangeAddressesP2PKH);
+    await DB.instance
+        .delete<dynamic>(key: 'changeAddressesP2PKH', boxName: walletId);
+
+    final tempReceivingIndexP2PKH =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'receivingIndexP2PKH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingIndexP2PKH_BACKUP',
+        value: tempReceivingIndexP2PKH);
+    await DB.instance
+        .delete<dynamic>(key: 'receivingIndexP2PKH', boxName: walletId);
+
+    final tempChangeIndexP2PKH =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'changeIndexP2PKH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeIndexP2PKH_BACKUP',
+        value: tempChangeIndexP2PKH);
+    await DB.instance
+        .delete<dynamic>(key: 'changeIndexP2PKH', boxName: walletId);
+
+    // p2sh
+    final tempReceivingAddressesP2SH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'receivingAddressesP2SH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingAddressesP2SH_BACKUP',
+        value: tempReceivingAddressesP2SH);
+    await DB.instance
+        .delete<dynamic>(key: 'receivingAddressesP2SH', boxName: walletId);
+
+    final tempChangeAddressesP2SH =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2SH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeAddressesP2SH_BACKUP',
+        value: tempChangeAddressesP2SH);
+    await DB.instance
+        .delete<dynamic>(key: 'changeAddressesP2SH', boxName: walletId);
+
+    final tempReceivingIndexP2SH =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'receivingIndexP2SH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingIndexP2SH_BACKUP',
+        value: tempReceivingIndexP2SH);
+    await DB.instance
+        .delete<dynamic>(key: 'receivingIndexP2SH', boxName: walletId);
+
+    final tempChangeIndexP2SH =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'changeIndexP2SH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeIndexP2SH_BACKUP',
+        value: tempChangeIndexP2SH);
+    await DB.instance
+        .delete<dynamic>(key: 'changeIndexP2SH', boxName: walletId);
+
+    // p2wpkh
+    final tempReceivingAddressesP2WPKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'receivingAddressesP2WPKH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingAddressesP2WPKH_BACKUP',
+        value: tempReceivingAddressesP2WPKH);
+    await DB.instance
+        .delete<dynamic>(key: 'receivingAddressesP2WPKH', boxName: walletId);
+
+    final tempChangeAddressesP2WPKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'changeAddressesP2WPKH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeAddressesP2WPKH_BACKUP',
+        value: tempChangeAddressesP2WPKH);
+    await DB.instance
+        .delete<dynamic>(key: 'changeAddressesP2WPKH', boxName: walletId);
+
+    final tempReceivingIndexP2WPKH = DB.instance
+        .get<dynamic>(boxName: walletId, key: 'receivingIndexP2WPKH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'receivingIndexP2WPKH_BACKUP',
+        value: tempReceivingIndexP2WPKH);
+    await DB.instance
+        .delete<dynamic>(key: 'receivingIndexP2WPKH', boxName: walletId);
+
+    final tempChangeIndexP2WPKH =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'changeIndexP2WPKH');
+    await DB.instance.put<dynamic>(
+        boxName: walletId,
+        key: 'changeIndexP2WPKH_BACKUP',
+        value: tempChangeIndexP2WPKH);
+    await DB.instance
+        .delete<dynamic>(key: 'changeIndexP2WPKH', boxName: walletId);
+
+    // P2PKH derivations
+    final p2pkhReceiveDerivationsString =
+        await _secureStore.read(key: "${walletId}_receiveDerivationsP2PKH");
+    final p2pkhChangeDerivationsString =
+        await _secureStore.read(key: "${walletId}_changeDerivationsP2PKH");
+
+    await _secureStore.write(
+        key: "${walletId}_receiveDerivationsP2PKH_BACKUP",
+        value: p2pkhReceiveDerivationsString);
+    await _secureStore.write(
+        key: "${walletId}_changeDerivationsP2PKH_BACKUP",
+        value: p2pkhChangeDerivationsString);
+
+    await _secureStore.delete(key: "${walletId}_receiveDerivationsP2PKH");
+    await _secureStore.delete(key: "${walletId}_changeDerivationsP2PKH");
+
+    // P2SH derivations
+    final p2shReceiveDerivationsString =
+        await _secureStore.read(key: "${walletId}_receiveDerivationsP2SH");
+    final p2shChangeDerivationsString =
+        await _secureStore.read(key: "${walletId}_changeDerivationsP2SH");
+
+    await _secureStore.write(
+        key: "${walletId}_receiveDerivationsP2SH_BACKUP",
+        value: p2shReceiveDerivationsString);
+    await _secureStore.write(
+        key: "${walletId}_changeDerivationsP2SH_BACKUP",
+        value: p2shChangeDerivationsString);
+
+    await _secureStore.delete(key: "${walletId}_receiveDerivationsP2SH");
+    await _secureStore.delete(key: "${walletId}_changeDerivationsP2SH");
+
+    // P2WPKH derivations
+    final p2wpkhReceiveDerivationsString =
+        await _secureStore.read(key: "${walletId}_receiveDerivationsP2WPKH");
+    final p2wpkhChangeDerivationsString =
+        await _secureStore.read(key: "${walletId}_changeDerivationsP2WPKH");
+
+    await _secureStore.write(
+        key: "${walletId}_receiveDerivationsP2WPKH_BACKUP",
+        value: p2wpkhReceiveDerivationsString);
+    await _secureStore.write(
+        key: "${walletId}_changeDerivationsP2WPKH_BACKUP",
+        value: p2wpkhChangeDerivationsString);
+
+    await _secureStore.delete(key: "${walletId}_receiveDerivationsP2WPKH");
+    await _secureStore.delete(key: "${walletId}_changeDerivationsP2WPKH");
+
+    // UTXOs
+    final utxoData =
+        DB.instance.get<dynamic>(boxName: walletId, key: 'latest_utxo_model');
+    await DB.instance.put<dynamic>(
+        boxName: walletId, key: 'latest_utxo_model_BACKUP', value: utxoData);
+    await DB.instance
+        .delete<dynamic>(key: 'latest_utxo_model', boxName: walletId);
+
+    Logging.instance.log("rescan backup complete", level: LogLevel.Info);
+  }
+
+  bool isActive = false;
+
+  @override
+  void Function(bool)? get onIsActiveWalletChanged =>
+      (isActive) => this.isActive = isActive;
+
+  @override
+  Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
+    final available = Format.decimalAmountToSatoshis(await availableBalance);
+
+    if (available == satoshiAmount) {
+      return satoshiAmount - sweepAllEstimate(feeRate);
+    } else if (satoshiAmount <= 0 || satoshiAmount > available) {
+      return roughFeeEstimate(1, 2, feeRate);
+    }
+
+    int runningBalance = 0;
+    int inputCount = 0;
+    for (final output in outputsList) {
+      runningBalance += output.value;
+      inputCount++;
+      if (runningBalance > satoshiAmount) {
+        break;
+      }
+    }
+
+    final oneOutPutFee = roughFeeEstimate(inputCount, 1, feeRate);
+    final twoOutPutFee = roughFeeEstimate(inputCount, 2, feeRate);
+
+    if (runningBalance - satoshiAmount > oneOutPutFee) {
+      if (runningBalance - satoshiAmount > oneOutPutFee + DUST_LIMIT) {
+        final change = runningBalance - satoshiAmount - twoOutPutFee;
+        if (change > DUST_LIMIT &&
+            runningBalance - satoshiAmount - change == twoOutPutFee) {
+          return runningBalance - satoshiAmount - change;
+        } else {
+          return runningBalance - satoshiAmount;
+        }
+      } else {
+        return runningBalance - satoshiAmount;
+      }
+    } else if (runningBalance - satoshiAmount == oneOutPutFee) {
+      return oneOutPutFee;
+    } else {
+      return twoOutPutFee;
+    }
+  }
+
+  int roughFeeEstimate(int inputCount, int outputCount, int feeRatePerKB) {
+    return ((42 + (272 * inputCount) + (128 * outputCount)) / 4).ceil() *
+        (feeRatePerKB / 1000).ceil();
+  }
+
+  int sweepAllEstimate(int feeRate) {
+    int available = 0;
+    int inputCount = 0;
+    for (final output in outputsList) {
+      if (output.status.confirmed) {
+        available += output.value;
+        inputCount++;
+      }
+    }
+
+    // transaction will only have 1 output minus the fee
+    final estimatedFee = roughFeeEstimate(inputCount, 1, feeRate);
+
+    return available - estimatedFee;
+  }
+
+  @override
+  Future<bool> generateNewAddress() async {
+    try {
+      await _incrementAddressIndexForChain(
+          0, DerivePathType.bip84); // First increment the receiving index
+      final newReceivingIndex = DB.instance.get<dynamic>(
+          boxName: walletId,
+          key: 'receivingIndexP2WPKH') as int; // Check the new receiving index
+      final newReceivingAddress = await _generateAddressForChain(
+          0,
+          newReceivingIndex,
+          DerivePathType
+              .bip84); // Use new index to derive a new receiving address
+      await _addToAddressesArrayForChain(
+          newReceivingAddress,
+          0,
+          DerivePathType
+              .bip84); // Add that new receiving address to the array of receiving addresses
+      _currentReceivingAddress = Future(() =>
+          newReceivingAddress); // Set the new receiving address that the service
+
+      return true;
+    } catch (e, s) {
+      Logging.instance.log(
+          "Exception rethrown from generateNewAddress(): $e\n$s",
+          level: LogLevel.Error);
+      return false;
+    }
+  }
+}

From 8549eda1ed31c8510acab4195a35ce110e36fde4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 28 Oct 2022 09:16:35 -0600
Subject: [PATCH 058/426] desktop stack experience view layout

---
 lib/pages/stack_privacy_calls.dart | 458 +++++++++++++++++------------
 lib/utilities/text_styles.dart     |  19 ++
 2 files changed, 285 insertions(+), 192 deletions(-)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index 7ca21c494..533f8344d 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -8,16 +8,18 @@ import 'package:stackwallet/pages_desktop_specific/create_password/create_passwo
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/prefs.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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 import '../hive/db.dart';
 import '../providers/global/price_provider.dart';
 import '../services/exchange/exchange_data_loading_service.dart';
+import '../widgets/desktop/primary_button.dart';
 
 class StackPrivacyCalls extends ConsumerStatefulWidget {
   const StackPrivacyCalls({
@@ -53,155 +55,195 @@ class _StackPrivacyCalls extends ConsumerState<StackPrivacyCalls> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
-        ),
-      ),
+    return MasterScaffold(
+      background: Theme.of(context).extension<StackColors>()!.background,
+      isDesktop: isDesktop,
+      appBar: isDesktop
+          ? const DesktopAppBar(
+              isCompactHeight: false,
+              leading: AppBarBackButton(),
+            )
+          : AppBar(
+              leading: AppBarBackButton(
+                onPressed: () {
+                  Navigator.of(context).pop();
+                },
+              ),
+            ),
       body: SafeArea(
         child: Padding(
-          padding: const EdgeInsets.fromLTRB(0, 40, 0, 0),
-          child: Column(
-            mainAxisAlignment: MainAxisAlignment.center,
-            children: [
-              Text(
-                "Choose your Stack experience",
-                style: STextStyles.pageTitleH1(context),
-              ),
-              const SizedBox(
-                height: 8,
-              ),
-              Text(
-                "You can change it later in Settings",
-                style: STextStyles.subtitle(context),
-              ),
-              const SizedBox(
-                height: 36,
-              ),
-              Padding(
-                padding: const EdgeInsets.symmetric(
-                  horizontal: 16,
+          padding: EdgeInsets.fromLTRB(0, isDesktop ? 0 : 40, 0, 0),
+          child: ConstrainedBox(
+            constraints: BoxConstraints(
+              maxWidth: isDesktop ? 480 : double.infinity,
+            ),
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                Text(
+                  "Choose your Stack experience",
+                  style: isDesktop
+                      ? STextStyles.desktopH2(context)
+                      : STextStyles.pageTitleH1(context),
                 ),
-                child: PrivacyToggle(
-                  externalCallsEnabled: isEasy,
-                  onChanged: (externalCalls) {
-                    isEasy = externalCalls;
-                    setState(() {
-                      infoToggle = isEasy;
-                    });
-                  },
+                SizedBox(
+                  height: isDesktop ? 16 : 8,
                 ),
-              ),
-              const SizedBox(
-                height: 36,
-              ),
-              Padding(
-                padding: const EdgeInsets.all(16.0),
-                child: RoundedWhiteContainer(
-                  child: Center(
-                    child: RichText(
-                      textAlign: TextAlign.left,
-                      text: TextSpan(
-                        style:
-                            STextStyles.label(context).copyWith(fontSize: 12.0),
-                        children: infoToggle
-                            ? [
-                                const TextSpan(
-                                    text:
-                                        "Exchange data preloaded for a seamless experience."),
-                                const TextSpan(
-                                    text:
-                                        "\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."),
-                                TextSpan(
-                                  text:
-                                      "\n\nRecommended for most crypto users.",
-                                  style: TextStyle(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textDark,
-                                    fontWeight: FontWeight.w600,
-                                  ),
+                Text(
+                  "You can change it later in Settings",
+                  style: isDesktop
+                      ? STextStyles.desktopSubtitleH2(context)
+                      : STextStyles.subtitle(context),
+                ),
+                SizedBox(
+                  height: isDesktop ? 32 : 36,
+                ),
+                Padding(
+                  padding: EdgeInsets.symmetric(
+                    horizontal: isDesktop ? 0 : 16,
+                  ),
+                  child: PrivacyToggle(
+                    externalCallsEnabled: isEasy,
+                    onChanged: (externalCalls) {
+                      isEasy = externalCalls;
+                      setState(() {
+                        infoToggle = isEasy;
+                      });
+                    },
+                  ),
+                ),
+                SizedBox(
+                  height: isDesktop ? 16 : 36,
+                ),
+                Padding(
+                  padding: isDesktop
+                      ? const EdgeInsets.all(0)
+                      : const EdgeInsets.all(16.0),
+                  child: RoundedWhiteContainer(
+                    child: Center(
+                      child: RichText(
+                        textAlign: TextAlign.left,
+                        text: TextSpan(
+                          style: isDesktop
+                              ? STextStyles.desktopTextExtraExtraSmall(context)
+                              : STextStyles.label(context).copyWith(
+                                  fontSize: 12.0,
                                 ),
-                              ]
-                            : [
-                                const TextSpan(
+                          children: infoToggle
+                              ? [
+                                  const TextSpan(
+                                      text:
+                                          "Exchange data preloaded for a seamless experience."),
+                                  const TextSpan(
+                                      text:
+                                          "\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."),
+                                  TextSpan(
                                     text:
-                                        "Exchange data not preloaded (slower experience)."),
-                                const TextSpan(
-                                    text:
-                                        "\n\nCoinGecko disabled (price changes not shown, no wallet value shown in other currencies)."),
-                                TextSpan(
-                                  text:
-                                      "\n\nRecommended for the privacy conscious.",
-                                  style: TextStyle(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textDark,
-                                    fontWeight: FontWeight.w600,
+                                        "\n\nRecommended for most crypto users.",
+                                    style: isDesktop
+                                        ? STextStyles
+                                            .desktopTextExtraExtraSmall600(
+                                                context)
+                                        : TextStyle(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark,
+                                            fontWeight: FontWeight.w600,
+                                          ),
                                   ),
-                                ),
-                              ],
+                                ]
+                              : [
+                                  const TextSpan(
+                                      text:
+                                          "Exchange data not preloaded (slower experience)."),
+                                  const TextSpan(
+                                      text:
+                                          "\n\nCoinGecko disabled (price changes not shown, no wallet value shown in other currencies)."),
+                                  TextSpan(
+                                    text:
+                                        "\n\nRecommended for the privacy conscious.",
+                                    style: isDesktop
+                                        ? STextStyles
+                                            .desktopTextExtraExtraSmall600(
+                                                context)
+                                        : TextStyle(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark,
+                                            fontWeight: FontWeight.w600,
+                                          ),
+                                  ),
+                                ],
+                        ),
                       ),
                     ),
                   ),
                 ),
-              ),
-              const Spacer(
-                flex: 4,
-              ),
-              Padding(
-                padding: const EdgeInsets.symmetric(
-                  horizontal: 16,
-                  vertical: 16,
-                ),
-                child: Row(
-                  children: [
-                    Expanded(
-                      child: ContinueButton(
-                        isDesktop: isDesktop,
-                        label: !widget.isSettings ? "Continue" : "Save changes",
-                        onPressed: () {
-                          ref.read(prefsChangeNotifierProvider).externalCalls =
-                              isEasy;
+                if (!isDesktop)
+                  const Spacer(
+                    flex: 4,
+                  ),
+                if (isDesktop)
+                  const SizedBox(
+                    height: 32,
+                  ),
+                Padding(
+                  padding: isDesktop
+                      ? const EdgeInsets.all(0)
+                      : const EdgeInsets.symmetric(
+                          horizontal: 16,
+                          vertical: 16,
+                        ),
+                  child: Row(
+                    children: [
+                      Expanded(
+                        child: PrimaryButton(
+                          label:
+                              !widget.isSettings ? "Continue" : "Save changes",
+                          onPressed: () {
+                            ref
+                                .read(prefsChangeNotifierProvider)
+                                .externalCalls = isEasy;
 
-                          DB.instance
-                              .put<dynamic>(
-                                  boxName: DB.boxNamePrefs,
-                                  key: "externalCalls",
-                                  value: isEasy)
-                              .then((_) {
-                            if (isEasy) {
-                              unawaited(
-                                  ExchangeDataLoadingService().loadAll(ref));
-                              ref
-                                  .read(priceAnd24hChangeNotifierProvider)
-                                  .start(true);
-                            }
-                          });
-                          if (!widget.isSettings) {
-                            if (isDesktop) {
-                              Navigator.of(context).pushNamed(
-                                CreatePasswordView.routeName,
-                              );
+                            DB.instance
+                                .put<dynamic>(
+                                    boxName: DB.boxNamePrefs,
+                                    key: "externalCalls",
+                                    value: isEasy)
+                                .then((_) {
+                              if (isEasy) {
+                                unawaited(
+                                    ExchangeDataLoadingService().loadAll(ref));
+                                ref
+                                    .read(priceAnd24hChangeNotifierProvider)
+                                    .start(true);
+                              }
+                            });
+                            if (!widget.isSettings) {
+                              if (isDesktop) {
+                                Navigator.of(context).pushNamed(
+                                  CreatePasswordView.routeName,
+                                );
+                              } else {
+                                Navigator.of(context).pushNamed(
+                                  CreatePinView.routeName,
+                                );
+                              }
                             } else {
-                              Navigator.of(context).pushNamed(
-                                CreatePinView.routeName,
-                              );
+                              Navigator.pop(context);
                             }
-                          } else {
-                            Navigator.pop(context);
-                          }
-                        },
+                          },
+                        ),
                       ),
-                    ),
-                  ],
+                    ],
+                  ),
                 ),
-              ),
-            ],
+                if (isDesktop)
+                  const SizedBox(
+                    height: kDesktopAppBarHeight,
+                  ),
+              ],
+            ),
           ),
         ),
       ),
@@ -226,8 +268,11 @@ class PrivacyToggle extends StatefulWidget {
 class _PrivacyToggleState extends State<PrivacyToggle> {
   late bool externalCallsEnabled;
 
+  late final bool isDesktop;
+
   @override
   void initState() {
+    isDesktop = Util.isDesktop;
     // initial toggle state
     externalCallsEnabled = widget.externalCallsEnabled;
     super.initState();
@@ -270,24 +315,39 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
                   Column(
                     crossAxisAlignment: CrossAxisAlignment.stretch,
                     children: [
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 10,
+                        ),
                       SvgPicture.asset(
                         Assets.svg.personaEasy,
-                        width: 140,
-                        height: 140,
+                        width: isDesktop ? 120 : 140,
+                        height: isDesktop ? 120 : 140,
                       ),
-                      Center(
-                          child: Text(
-                        "Easy Crypto",
-                        style: STextStyles.label(context).copyWith(
-                          fontWeight: FontWeight.bold,
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 12,
                         ),
-                      )),
+                      Center(
+                        child: Text(
+                          "Easy Crypto",
+                          style: isDesktop
+                              ? STextStyles.desktopTextSmall(context)
+                              : STextStyles.label700(context),
+                        ),
+                      ),
                       Center(
                         child: Text(
                           "Recommended",
-                          style: STextStyles.label(context),
+                          style: isDesktop
+                              ? STextStyles.desktopTextExtraExtraSmall(context)
+                              : STextStyles.label(context),
                         ),
                       ),
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 12,
+                        ),
                     ],
                   ),
                   if (externalCallsEnabled)
@@ -360,25 +420,39 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
                   Column(
                     crossAxisAlignment: CrossAxisAlignment.stretch,
                     children: [
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 10,
+                        ),
                       SvgPicture.asset(
                         Assets.svg.personaIncognito,
-                        width: 140,
-                        height: 140,
+                        width: isDesktop ? 120 : 140,
+                        height: isDesktop ? 120 : 140,
                       ),
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 12,
+                        ),
                       Center(
                         child: Text(
                           "Incognito",
-                          style: STextStyles.label(context).copyWith(
-                            fontWeight: FontWeight.bold,
-                          ),
+                          style: isDesktop
+                              ? STextStyles.desktopTextSmall(context)
+                              : STextStyles.label700(context),
                         ),
                       ),
                       Center(
                         child: Text(
                           "Privacy conscious",
-                          style: STextStyles.label(context),
+                          style: isDesktop
+                              ? STextStyles.desktopTextExtraExtraSmall(context)
+                              : STextStyles.label(context),
                         ),
                       ),
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 12,
+                        ),
                     ],
                   ),
                   if (!externalCallsEnabled)
@@ -419,49 +493,49 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
   }
 }
 
-class ContinueButton extends ConsumerWidget {
-  const ContinueButton({
-    Key? key,
-    required this.isDesktop,
-    required this.onPressed,
-    required this.label,
-  }) : super(key: key);
-
-  final String label;
-  final bool isDesktop;
-  final VoidCallback onPressed;
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    if (isDesktop) {
-      return SizedBox(
-        width: 328,
-        height: 70,
-        child: TextButton(
-          style: Theme.of(context)
-              .extension<StackColors>()!
-              .getPrimaryEnabledButtonColor(context),
-          onPressed: onPressed,
-          child: Text(
-            label,
-            style: STextStyles.button(context).copyWith(fontSize: 20),
-          ),
-        ),
-      );
-    } else {
-      return TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: onPressed,
-        child: Text(
-          label,
-          style: STextStyles.button(context),
-        ),
-      );
-    }
-  }
-}
+// class ContinueButton extends ConsumerWidget {
+//   const ContinueButton({
+//     Key? key,
+//     required this.isDesktop,
+//     required this.onPressed,
+//     required this.label,
+//   }) : super(key: key);
+//
+//   final String label;
+//   final bool isDesktop;
+//   final VoidCallback onPressed;
+//
+//   @override
+//   Widget build(BuildContext context, WidgetRef ref) {
+//     if (isDesktop) {
+//       return SizedBox(
+//         width: 328,
+//         height: 70,
+//         child: TextButton(
+//           style: Theme.of(context)
+//               .extension<StackColors>()!
+//               .getPrimaryEnabledButtonColor(context),
+//           onPressed: onPressed,
+//           child: Text(
+//             label,
+//             style: STextStyles.button(context).copyWith(fontSize: 20),
+//           ),
+//         ),
+//       );
+//     } else {
+//       return TextButton(
+//         style: Theme.of(context)
+//             .extension<StackColors>()!
+//             .getPrimaryEnabledButtonColor(context),
+//         onPressed: onPressed,
+//         child: Text(
+//           label,
+//           style: STextStyles.button(context),
+//         ),
+//       );
+//     }
+//   }
+// }
 
 // class CustomRadio extends StatefulWidget {
 //   CustomRadio(this.upperCall, {Key? key}) : super(key: key);
diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart
index b583dba98..299ba5bec 100644
--- a/lib/utilities/text_styles.dart
+++ b/lib/utilities/text_styles.dart
@@ -755,6 +755,25 @@ class STextStyles {
     }
   }
 
+  static TextStyle desktopTextExtraExtraSmall600(BuildContext context) {
+    switch (_theme(context).themeType) {
+      case ThemeType.light:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 14,
+          height: 21 / 14,
+        );
+      case ThemeType.dark:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 14,
+          height: 21 / 14,
+        );
+    }
+  }
+
   static TextStyle desktopButtonSmallSecondaryEnabled(BuildContext context) {
     switch (_theme(context).themeType) {
       case ThemeType.light:

From c0fddcd8226b54d147c48815602ea305ca4ac6a1 Mon Sep 17 00:00:00 2001
From: Marco <marco@cypherstack.com>
Date: Fri, 28 Oct 2022 12:03:52 -0600
Subject: [PATCH 059/426] add litecoin support

---
 assets/images/litecoin.png                    | Bin 0 -> 329261 bytes
 assets/svg/coin_icons/Litecoin.svg            |  11 ++
 lib/main.dart                                 | 103 ++++++-------
 lib/pages/exchange_view/send_from_view.dart   |   2 +
 .../add_edit_node_view.dart                   |   2 +
 .../manage_nodes_views/node_details_view.dart |   2 +
 lib/services/coins/coin_service.dart          |  22 +++
 .../coins/litecoin/litecoin_wallet.dart       | 138 +++++++++++-------
 lib/services/price.dart                       |   2 +-
 lib/utilities/address_utils.dart              |   5 +
 lib/utilities/assets.dart                     |   8 +
 lib/utilities/block_explorers.dart            |   4 +
 lib/utilities/constants.dart                  |   6 +
 lib/utilities/default_nodes.dart              |  32 ++++
 lib/utilities/enums/coin_enum.dart            |  35 +++++
 lib/utilities/theme/color_theme.dart          |   4 +
 lib/utilities/theme/stack_colors.dart         |   3 +
 pubspec.lock                                  |  43 +++---
 pubspec.yaml                                  |   2 +
 test/price_test.dart                          |  20 +--
 20 files changed, 305 insertions(+), 139 deletions(-)
 create mode 100644 assets/images/litecoin.png
 create mode 100644 assets/svg/coin_icons/Litecoin.svg

diff --git a/assets/images/litecoin.png b/assets/images/litecoin.png
new file mode 100644
index 0000000000000000000000000000000000000000..17994bd47ed0244f5777f3f026759b1f266a8594
GIT binary patch
literal 329261
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
S4$|U=p8v!CZ1owh)c*ndihia5

literal 0
HcmV?d00001

diff --git a/assets/svg/coin_icons/Litecoin.svg b/assets/svg/coin_icons/Litecoin.svg
new file mode 100644
index 000000000..2b89ca50b
--- /dev/null
+++ b/assets/svg/coin_icons/Litecoin.svg
@@ -0,0 +1,11 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_6052_99642)">
+<rect width="24" height="24" rx="12" fill="white"/>
+<path d="M11.9976 0C9.62389 0 7.30353 0.703873 5.3299 2.02261C3.35627 3.34135 1.81802 5.21572 0.909655 7.4087C0.00129377 9.60167 -0.236375 12.0148 0.226704 14.3428C0.689782 16.6709 1.83281 18.8093 3.51124 20.4878C5.18968 22.1662 7.32813 23.3092 9.65618 23.7723C11.9842 24.2354 14.3973 23.9977 16.5903 23.0893C18.7833 22.181 20.6577 20.6427 21.9764 18.6691C23.2951 16.6955 23.999 14.3751 23.999 12.0015C23.999 10.4254 23.6886 8.86478 23.0854 7.4087C22.4823 5.95261 21.5983 4.62958 20.4839 3.51514C19.3694 2.40071 18.0464 1.51669 16.5903 0.913556C15.1342 0.310427 13.5736 0 11.9976 0V0ZM12.1921 12.3963L10.9437 16.6087H17.6209C17.674 16.6088 17.7263 16.6213 17.7738 16.6451C17.8212 16.669 17.8625 16.7035 17.8943 16.746C17.9261 16.7885 17.9476 16.8378 17.9571 16.8901C17.9666 16.9423 17.9638 16.9961 17.9489 17.0471L17.3683 19.0473C17.3406 19.1429 17.2826 19.2268 17.203 19.2865C17.1234 19.3462 17.0265 19.3784 16.927 19.3783H6.72841L8.45286 13.5546L6.54551 14.1352L6.96646 12.7737L8.87671 12.1931L11.2979 4.0121C11.3245 3.91623 11.3818 3.8317 11.4609 3.77142C11.5401 3.71114 11.6368 3.67842 11.7363 3.67824H14.32C14.3731 3.67805 14.4254 3.69017 14.4729 3.71364C14.5205 3.73712 14.5619 3.77131 14.594 3.81352C14.6261 3.85573 14.6479 3.90482 14.6578 3.95691C14.6677 4.009 14.6654 4.06267 14.651 4.11371L12.6188 11.0318L14.5262 10.4512L14.1168 11.836L12.1921 12.3963Z" fill="#315D9E"/>
+</g>
+<defs>
+<clipPath id="clip0_6052_99642">
+<rect width="24" height="24" rx="12" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/lib/main.dart b/lib/main.dart
index aa2155478..58a287b31 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -68,7 +68,7 @@ final openedFromSWBFileStringStateProvider =
 void main() async {
   WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
   GoogleFonts.config.allowRuntimeFetching = false;
-  if(Platform.isIOS){
+  if (Platform.isIOS) {
     Util.libraryPath = await getLibraryDirectory();
   }
 
@@ -209,56 +209,59 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
   bool didLoad = false;
 
   Future<void> load() async {
-    if (didLoad) {
-      return;
-    }
-    didLoad = true;
-
-    await DB.instance.init();
-    await _prefs.init();
-
-    _notificationsService = ref.read(notificationsProvider);
-    _nodeService = ref.read(nodeServiceChangeNotifierProvider);
-    _tradesService = ref.read(tradesServiceProvider);
-
-    NotificationApi.prefs = _prefs;
-    NotificationApi.notificationsService = _notificationsService;
-
-    unawaited(ref.read(baseCurrenciesProvider).update());
-
-    await _nodeService.updateDefaults();
-    await _notificationsService.init(
-      nodeService: _nodeService,
-      tradesService: _tradesService,
-      prefs: _prefs,
-    );
-    ref.read(priceAnd24hChangeNotifierProvider).start(true);
-    await _wallets.load(_prefs);
-    loadingCompleter.complete();
-    // TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet
-    //  unawaited(_nodeService.updateCommunityNodes());
-
-    // run without awaiting
-    if (Constants.enableExchange &&
-        _prefs.externalCalls &&
-        await _prefs.isExternalCallsSet()) {
-      unawaited(ExchangeDataLoadingService().loadAll(ref));
-    }
-
-    if (_prefs.isAutoBackupEnabled) {
-      switch (_prefs.backupFrequencyType) {
-        case BackupFrequencyType.everyTenMinutes:
-          ref
-              .read(autoSWBServiceProvider)
-              .startPeriodicBackupTimer(duration: const Duration(minutes: 10));
-          break;
-        case BackupFrequencyType.everyAppStart:
-          unawaited(ref.read(autoSWBServiceProvider).doBackup());
-          break;
-        case BackupFrequencyType.afterClosingAWallet:
-          // ignore this case here
-          break;
+    try {
+      if (didLoad) {
+        return;
       }
+      didLoad = true;
+
+      await DB.instance.init();
+      await _prefs.init();
+
+      _notificationsService = ref.read(notificationsProvider);
+      _nodeService = ref.read(nodeServiceChangeNotifierProvider);
+      _tradesService = ref.read(tradesServiceProvider);
+
+      NotificationApi.prefs = _prefs;
+      NotificationApi.notificationsService = _notificationsService;
+
+      unawaited(ref.read(baseCurrenciesProvider).update());
+
+      await _nodeService.updateDefaults();
+      await _notificationsService.init(
+        nodeService: _nodeService,
+        tradesService: _tradesService,
+        prefs: _prefs,
+      );
+      ref.read(priceAnd24hChangeNotifierProvider).start(true);
+      await _wallets.load(_prefs);
+      loadingCompleter.complete();
+      // TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet
+      //  unawaited(_nodeService.updateCommunityNodes());
+
+      // run without awaiting
+      if (Constants.enableExchange &&
+          _prefs.externalCalls &&
+          await _prefs.isExternalCallsSet()) {
+        unawaited(ExchangeDataLoadingService().loadAll(ref));
+      }
+
+      if (_prefs.isAutoBackupEnabled) {
+        switch (_prefs.backupFrequencyType) {
+          case BackupFrequencyType.everyTenMinutes:
+            ref.read(autoSWBServiceProvider).startPeriodicBackupTimer(
+                duration: const Duration(minutes: 10));
+            break;
+          case BackupFrequencyType.everyAppStart:
+            unawaited(ref.read(autoSWBServiceProvider).doBackup());
+            break;
+          case BackupFrequencyType.afterClosingAWallet:
+            // ignore this case here
+            break;
+        }
+      }
+    } catch (e, s) {
+      Logger.print("$e $s", normalLength: false);
     }
   }
 
diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart
index 51c420c82..20fc81903 100644
--- a/lib/pages/exchange_view/send_from_view.dart
+++ b/lib/pages/exchange_view/send_from_view.dart
@@ -52,11 +52,13 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
     switch (coin) {
       case Coin.bitcoin:
       case Coin.bitcoincash:
+      case Coin.litecoin:
       case Coin.dogecoin:
       case Coin.epicCash:
       case Coin.firo:
       case Coin.namecoin:
       case Coin.bitcoinTestNet:
+      case Coin.litecoinTestNet:
       case Coin.bitcoincashTestnet:
       case Coin.dogecoinTestNet:
       case Coin.firoTestNet:
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 100c03e1b..ada3c45f9 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -531,11 +531,13 @@ class _NodeFormState extends ConsumerState<NodeForm> {
     // TODO: which coin servers can have username and password?
     switch (coin) {
       case Coin.bitcoin:
+      case Coin.litecoin:
       case Coin.dogecoin:
       case Coin.firo:
       case Coin.namecoin:
       case Coin.bitcoincash:
       case Coin.bitcoinTestNet:
+      case Coin.litecoinTestNet:
       case Coin.bitcoincashTestnet:
       case Coin.firoTestNet:
       case Coin.dogecoinTestNet:
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index 8baddb700..c5f797e37 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -98,6 +98,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
         break;
 
       case Coin.bitcoin:
+      case Coin.litecoin:
       case Coin.dogecoin:
       case Coin.firo:
       case Coin.bitcoinTestNet:
@@ -105,6 +106,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
       case Coin.dogecoinTestNet:
       case Coin.bitcoincash:
       case Coin.namecoin:
+      case Coin.litecoinTestNet:
       case Coin.bitcoincashTestnet:
         final client = ElectrumX(
           host: node!.host,
diff --git a/lib/services/coins/coin_service.dart b/lib/services/coins/coin_service.dart
index 089b20a33..c36fa9eee 100644
--- a/lib/services/coins/coin_service.dart
+++ b/lib/services/coins/coin_service.dart
@@ -15,6 +15,8 @@ import 'package:stackwallet/services/transaction_notification_tracker.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 
+import 'litecoin/litecoin_wallet.dart';
+
 abstract class CoinServiceAPI {
   CoinServiceAPI();
 
@@ -90,6 +92,26 @@ abstract class CoinServiceAPI {
           tracker: tracker,
         );
 
+      case Coin.litecoin:
+        return LitecoinWallet(
+          walletId: walletId,
+          walletName: walletName,
+          coin: coin,
+          client: client,
+          cachedClient: cachedClient,
+          tracker: tracker,
+        );
+
+      case Coin.litecoinTestNet:
+        return LitecoinWallet(
+          walletId: walletId,
+          walletName: walletName,
+          coin: coin,
+          client: client,
+          cachedClient: cachedClient,
+          tracker: tracker,
+        );
+
       case Coin.bitcoinTestNet:
         return BitcoinWallet(
           walletId: walletId,
diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart
index da3bdfed0..0ab3a92a8 100644
--- a/lib/services/coins/litecoin/litecoin_wallet.dart
+++ b/lib/services/coins/litecoin/litecoin_wallet.dart
@@ -46,9 +46,9 @@ const int MINIMUM_CONFIRMATIONS = 1;
 const int DUST_LIMIT = 294;
 
 const String GENESIS_HASH_MAINNET =
-    "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f";
+    "12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2";
 const String GENESIS_HASH_TESTNET =
-    "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943";
+    "4966625a4b2851d9fdee139e56211a0d88575f59ed816ff5e6a63deb4e3e29a0";
 
 enum DerivePathType { bip44, bip49, bip84 }
 
@@ -86,14 +86,14 @@ bip32.BIP32 getBip32NodeFromRoot(
 ) {
   String coinType;
   switch (root.network.wif) {
-    case 0x80: // btc mainnet wif
-      coinType = "0"; // btc mainnet
+    case 0xb0: // ltc mainnet wif
+      coinType = "2"; // ltc mainnet
       break;
-    case 0xef: // btc testnet wif
-      coinType = "1"; // btc testnet
+    case 0xef: // ltc testnet wif
+      coinType = "1"; // ltc testnet
       break;
     default:
-      throw Exception("Invalid Bitcoin network type used!");
+      throw Exception("Invalid Litecoin network type used!");
   }
   switch (derivePathType) {
     case DerivePathType.bip44:
@@ -138,7 +138,7 @@ bip32.BIP32 getBip32RootWrapper(Tuple2<String, NetworkType> args) {
   return getBip32Root(args.item1, args.item2);
 }
 
-class BitcoinWallet extends CoinServiceAPI {
+class LitecoinWallet extends CoinServiceAPI {
   static const integrationTestFlag =
       bool.fromEnvironment("IS_INTEGRATION_TEST");
 
@@ -151,10 +151,10 @@ class BitcoinWallet extends CoinServiceAPI {
 
   NetworkType get _network {
     switch (coin) {
-      case Coin.bitcoin:
-        return bitcoin;
-      case Coin.bitcoinTestNet:
-        return testnet;
+      case Coin.litecoin:
+        return litecoin;
+      case Coin.litecoinTestNet:
+        return litecointestnet;
       default:
         throw Exception("Invalid network type!");
     }
@@ -314,7 +314,7 @@ class BitcoinWallet extends CoinServiceAPI {
       throw ArgumentError('Invalid version or Network mismatch');
     } else {
       try {
-        decodeBech32 = segwit.decode(address);
+        decodeBech32 = segwit.decode(address, _network.bech32!);
       } catch (err) {
         // Bech32 decode fail
       }
@@ -347,19 +347,19 @@ class BitcoinWallet extends CoinServiceAPI {
         final features = await electrumXClient.getServerFeatures();
         Logging.instance.log("features: $features", level: LogLevel.Info);
         switch (coin) {
-          case Coin.bitcoin:
+          case Coin.litecoin:
             if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
               throw Exception("genesis hash does not match main net!");
             }
             break;
-          case Coin.bitcoinTestNet:
+          case Coin.litecoinTestNet:
             if (features['genesis_hash'] != GENESIS_HASH_TESTNET) {
               throw Exception("genesis hash does not match test net!");
             }
             break;
           default:
             throw Exception(
-                "Attempted to generate a BitcoinWallet using a non bitcoin coin type: ${coin.name}");
+                "Attempted to generate a LitecoinWallet using a non litecoin coin type: ${coin.name}");
         }
         // if (_networkType == BasicNetworkType.main) {
         //   if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
@@ -446,7 +446,8 @@ class BitcoinWallet extends CoinServiceAPI {
                     data: PaymentData(
                         redeem: P2WPKH(
                                 data: PaymentData(pubkey: node.publicKey),
-                                network: _network)
+                                network: _network,
+                                overridePrefix: _network.bech32!)
                             .data),
                     network: _network)
                 .data
@@ -455,7 +456,8 @@ class BitcoinWallet extends CoinServiceAPI {
           case DerivePathType.bip84:
             address = P2WPKH(
                     network: _network,
-                    data: PaymentData(pubkey: node.publicKey))
+                    data: PaymentData(pubkey: node.publicKey),
+                    overridePrefix: _network.bech32!)
                 .data
                 .address!;
             break;
@@ -1284,7 +1286,7 @@ class BitcoinWallet extends CoinServiceAPI {
 
   @override
   bool validateAddress(String address) {
-    return Address.validateAddress(address, _network);
+    return Address.validateAddress(address, _network, _network.bech32!);
   }
 
   @override
@@ -1311,7 +1313,7 @@ class BitcoinWallet extends CoinServiceAPI {
 
   late PriceAPI _priceAPI;
 
-  BitcoinWallet({
+  LitecoinWallet({
     required String walletId,
     required String walletName,
     required Coin coin,
@@ -1469,19 +1471,20 @@ class BitcoinWallet extends CoinServiceAPI {
       final features = await electrumXClient.getServerFeatures();
       Logging.instance.log("features: $features", level: LogLevel.Info);
       switch (coin) {
-        case Coin.bitcoin:
+        case Coin.litecoin:
           if (features['genesis_hash'] != GENESIS_HASH_MAINNET) {
+            print(features['genesis_hash']);
             throw Exception("genesis hash does not match main net!");
           }
           break;
-        case Coin.bitcoinTestNet:
+        case Coin.litecoinTestNet:
           if (features['genesis_hash'] != GENESIS_HASH_TESTNET) {
             throw Exception("genesis hash does not match test net!");
           }
           break;
         default:
           throw Exception(
-              "Attempted to generate a BitcoinWallet using a non bitcoin coin type: ${coin.name}");
+              "Attempted to generate a LitecoinWallet using a non litecoin coin type: ${coin.name}");
       }
     }
 
@@ -1636,13 +1639,20 @@ class BitcoinWallet extends CoinServiceAPI {
       case DerivePathType.bip49:
         address = P2SH(
                 data: PaymentData(
-                    redeem: P2WPKH(data: data, network: _network).data),
+                    redeem: P2WPKH(
+                            data: data,
+                            network: _network,
+                            overridePrefix: _network.bech32!)
+                        .data),
                 network: _network)
             .data
             .address!;
         break;
       case DerivePathType.bip84:
-        address = P2WPKH(network: _network, data: data).data.address!;
+        address = P2WPKH(
+                network: _network, data: data, overridePrefix: _network.bech32!)
+            .data
+            .address!;
         break;
     }
 
@@ -2216,10 +2226,11 @@ class BitcoinWallet extends CoinServiceAPI {
 
   /// attempts to convert a string to a valid scripthash
   ///
-  /// Returns the scripthash or throws an exception on invalid bitcoin address
-  String _convertToScriptHash(String bitcoinAddress, NetworkType network) {
+  /// Returns the scripthash or throws an exception on invalid litecoin address
+  String _convertToScriptHash(String litecoinAddress, NetworkType network) {
     try {
-      final output = Address.addressToOutputScript(bitcoinAddress, network);
+      final output = Address.addressToOutputScript(
+          litecoinAddress, network, _network.bech32!);
       final hash = sha256.convert(output.toList(growable: false)).toString();
 
       final chars = hash.split("");
@@ -2442,7 +2453,7 @@ class BitcoinWallet extends CoinServiceAPI {
 
         for (final out in tx["vout"] as List) {
           if (prevOut == out["n"]) {
-            final address = out["scriptPubKey"]["address"] as String?;
+            final address = out["scriptPubKey"]["addresses"][0] as String?;
             if (address != null) {
               sendersArray.add(address);
             }
@@ -2453,7 +2464,7 @@ class BitcoinWallet extends CoinServiceAPI {
       Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info);
 
       for (final output in txObject["vout"] as List) {
-        final address = output["scriptPubKey"]["address"] as String?;
+        final address = output["scriptPubKey"]["addresses"][0] as String?;
         if (address != null) {
           recipientsArray.add(address);
         }
@@ -2493,7 +2504,8 @@ class BitcoinWallet extends CoinServiceAPI {
         int totalOutput = 0;
 
         for (final output in txObject["vout"] as List) {
-          final String address = output["scriptPubKey"]!["address"] as String;
+          final String address =
+              output["scriptPubKey"]!["addresses"][0] as String;
           final value = output["value"]!;
           final _value = (Decimal.parse(value.toString()) *
                   Decimal.fromInt(Constants.satsPerCoin))
@@ -2518,7 +2530,7 @@ class BitcoinWallet extends CoinServiceAPI {
 
         // add up received tx value
         for (final output in txObject["vout"] as List) {
-          final address = output["scriptPubKey"]["address"];
+          final address = output["scriptPubKey"]["addresses"][0];
           if (address != null) {
             final value = (Decimal.parse(output["value"].toString()) *
                     Decimal.fromInt(Constants.satsPerCoin))
@@ -3034,7 +3046,7 @@ class BitcoinWallet extends CoinServiceAPI {
         for (final output in tx["vout"] as List) {
           final n = output["n"];
           if (n != null && n == utxosToUse[i].vout) {
-            final address = output["scriptPubKey"]["address"] as String;
+            final address = output["scriptPubKey"]["addresses"][0] as String;
             if (!addressTxid.containsKey(address)) {
               addressTxid[address] = <String>[];
             }
@@ -3132,7 +3144,8 @@ class BitcoinWallet extends CoinServiceAPI {
                     data: PaymentData(
                         pubkey: Format.stringToUint8List(
                             receiveDerivation["pubKey"] as String)),
-                    network: _network)
+                    network: _network,
+                    overridePrefix: _network.bech32!)
                 .data;
 
             final redeemScript = p2wpkh.output;
@@ -3159,7 +3172,8 @@ class BitcoinWallet extends CoinServiceAPI {
                       data: PaymentData(
                           pubkey: Format.stringToUint8List(
                               changeDerivation["pubKey"] as String)),
-                      network: _network)
+                      network: _network,
+                      overridePrefix: _network.bech32!)
                   .data;
 
               final redeemScript = p2wpkh.output;
@@ -3201,11 +3215,12 @@ class BitcoinWallet extends CoinServiceAPI {
           // if a match exists it will not be null
           if (receiveDerivation != null) {
             final data = P2WPKH(
-              data: PaymentData(
-                  pubkey: Format.stringToUint8List(
-                      receiveDerivation["pubKey"] as String)),
-              network: _network,
-            ).data;
+                    data: PaymentData(
+                        pubkey: Format.stringToUint8List(
+                            receiveDerivation["pubKey"] as String)),
+                    network: _network,
+                    overridePrefix: _network.bech32!)
+                .data;
 
             for (String tx in addressTxid[addressesP2WPKH[i]]!) {
               results[tx] = {
@@ -3222,11 +3237,12 @@ class BitcoinWallet extends CoinServiceAPI {
             // if a match exists it will not be null
             if (changeDerivation != null) {
               final data = P2WPKH(
-                data: PaymentData(
-                    pubkey: Format.stringToUint8List(
-                        changeDerivation["pubKey"] as String)),
-                network: _network,
-              ).data;
+                      data: PaymentData(
+                          pubkey: Format.stringToUint8List(
+                              changeDerivation["pubKey"] as String)),
+                      network: _network,
+                      overridePrefix: _network.bech32!)
+                  .data;
 
               for (String tx in addressTxid[addressesP2WPKH[i]]!) {
                 results[tx] = {
@@ -3267,12 +3283,12 @@ class BitcoinWallet extends CoinServiceAPI {
     for (var i = 0; i < utxosToUse.length; i++) {
       final txid = utxosToUse[i].txid;
       txb.addInput(txid, utxosToUse[i].vout, null,
-          utxoSigningData[txid]["output"] as Uint8List);
+          utxoSigningData[txid]["output"] as Uint8List, _network.bech32!);
     }
 
     // Add transaction output
     for (var i = 0; i < recipients.length; i++) {
-      txb.addOutput(recipients[i], satoshiAmounts[i]);
+      txb.addOutput(recipients[i], satoshiAmounts[i], _network.bech32!);
     }
 
     try {
@@ -3280,11 +3296,11 @@ class BitcoinWallet extends CoinServiceAPI {
       for (var i = 0; i < utxosToUse.length; i++) {
         final txid = utxosToUse[i].txid;
         txb.sign(
-          vin: i,
-          keyPair: utxoSigningData[txid]["keyPair"] as ECPair,
-          witnessValue: utxosToUse[i].value,
-          redeemScript: utxoSigningData[txid]["redeemScript"] as Uint8List?,
-        );
+            vin: i,
+            keyPair: utxoSigningData[txid]["keyPair"] as ECPair,
+            witnessValue: utxosToUse[i].value,
+            redeemScript: utxoSigningData[txid]["redeemScript"] as Uint8List?,
+            overridePrefix: _network.bech32!);
       }
     } catch (e, s) {
       Logging.instance.log("Caught exception while signing transaction: $e\n$s",
@@ -3292,7 +3308,7 @@ class BitcoinWallet extends CoinServiceAPI {
       rethrow;
     }
 
-    final builtTx = txb.build();
+    final builtTx = txb.build(_network.bech32!);
     final vSize = builtTx.virtualSize();
 
     return {"hex": builtTx.toHex(), "vSize": vSize};
@@ -3794,3 +3810,19 @@ class BitcoinWallet extends CoinServiceAPI {
     }
   }
 }
+
+final litecoin = NetworkType(
+    messagePrefix: '\x19Litecoin Signed Message:\n',
+    bech32: 'ltc',
+    bip32: Bip32Type(public: 0x0488b21e, private: 0x0488ade4),
+    pubKeyHash: 0x30,
+    scriptHash: 0x32,
+    wif: 0xb0);
+
+final litecointestnet = NetworkType(
+    messagePrefix: '\x19Litecoin Signed Message:\n',
+    bech32: 'tltc',
+    bip32: Bip32Type(public: 0x043587cf, private: 0x04358394),
+    pubKeyHash: 0x6f,
+    scriptHash: 0x3a,
+    wif: 0xef);
diff --git a/lib/services/price.dart b/lib/services/price.dart
index b44e055d5..2514cc12a 100644
--- a/lib/services/price.dart
+++ b/lib/services/price.dart
@@ -87,7 +87,7 @@ class PriceAPI {
     Map<Coin, Tuple2<Decimal, double>> result = {};
     try {
       final uri = Uri.parse(
-          "https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false");
+          "https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false");
       // final uri = Uri.parse(
       //     "https://api.coingecko.com/api/v3/coins/markets?vs_currency=${baseCurrency.toLowerCase()}&ids=monero%2Cbitcoin%2Cepic-cash%2Czcoin%2Cdogecoin&order=market_cap_desc&per_page=10&page=1&sparkline=false");
 
diff --git a/lib/utilities/address_utils.dart b/lib/utilities/address_utils.dart
index d73c5d3ce..65303b24d 100644
--- a/lib/utilities/address_utils.dart
+++ b/lib/utilities/address_utils.dart
@@ -6,6 +6,7 @@ import 'package:flutter_libepiccash/epic_cash.dart';
 import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart';
 import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
+import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart';
 import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
@@ -42,6 +43,8 @@ class AddressUtils {
     switch (coin) {
       case Coin.bitcoin:
         return Address.validateAddress(address, bitcoin);
+      case Coin.litecoin:
+        return Address.validateAddress(address, litecoin);
       case Coin.bitcoincash:
         return Address.validateAddress(address, bitcoincash);
       case Coin.dogecoin:
@@ -60,6 +63,8 @@ class AddressUtils {
         return Address.validateAddress(address, namecoin, namecoin.bech32!);
       case Coin.bitcoinTestNet:
         return Address.validateAddress(address, testnet);
+      case Coin.litecoinTestNet:
+        return Address.validateAddress(address, litecointestnet);
       case Coin.bitcoincashTestnet:
         return Address.validateAddress(address, bitcoincashtestnet);
       case Coin.firoTestNet:
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index ebe2d9848..ba93f3a31 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -149,6 +149,7 @@ class _SVG {
   String get ellipse2 => "assets/svg/Ellipse-42.svg";
 
   String get bitcoin => "assets/svg/coin_icons/Bitcoin.svg";
+  String get litecoin => "assets/svg/coin_icons/Litecoin.svg";
   String get bitcoincash => "assets/svg/coin_icons/Bitcoincash.svg";
   String get dogecoin => "assets/svg/coin_icons/Dogecoin.svg";
   String get epicCash => "assets/svg/coin_icons/EpicCash.svg";
@@ -173,6 +174,9 @@ class _SVG {
     switch (coin) {
       case Coin.bitcoin:
         return bitcoin;
+      case Coin.litecoin:
+      case Coin.litecoinTestNet:
+        return litecoin;
       case Coin.bitcoincash:
         return bitcoincash;
       case Coin.dogecoin:
@@ -210,6 +214,7 @@ class _PNG {
   String get firo => "assets/images/firo.png";
   String get dogecoin => "assets/images/doge.png";
   String get bitcoin => "assets/images/bitcoin.png";
+  String get litecoin => "assets/images/litecoin.png";
   String get epicCash => "assets/images/epic-cash.png";
   String get bitcoincash => "assets/images/bitcoincash.png";
   String get namecoin => "assets/images/namecoin.png";
@@ -219,6 +224,9 @@ class _PNG {
       case Coin.bitcoin:
       case Coin.bitcoinTestNet:
         return bitcoin;
+      case Coin.litecoin:
+      case Coin.litecoinTestNet:
+        return litecoin;
       case Coin.bitcoincash:
       case Coin.bitcoincashTestnet:
         return bitcoincash;
diff --git a/lib/utilities/block_explorers.dart b/lib/utilities/block_explorers.dart
index f89f270be..69afb4a83 100644
--- a/lib/utilities/block_explorers.dart
+++ b/lib/utilities/block_explorers.dart
@@ -7,6 +7,10 @@ Uri getBlockExplorerTransactionUrlFor({
   switch (coin) {
     case Coin.bitcoin:
       return Uri.parse("https://chain.so/tx/BTC/$txid");
+    case Coin.litecoin:
+      return Uri.parse("https://chain.so/tx/LTC/$txid");
+    case Coin.litecoinTestNet:
+      return Uri.parse("https://chain.so/tx/LTCTEST/$txid");
     case Coin.bitcoinTestNet:
       return Uri.parse("https://chain.so/tx/BTCTEST/$txid");
     case Coin.dogecoin:
diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart
index c4ac4bbe9..4fb3fb54b 100644
--- a/lib/utilities/constants.dart
+++ b/lib/utilities/constants.dart
@@ -48,6 +48,8 @@ abstract class Constants {
     final List<int> values = [];
     switch (coin) {
       case Coin.bitcoin:
+      case Coin.litecoin:
+      case Coin.litecoinTestNet:
       case Coin.bitcoincash:
       case Coin.bitcoincashTestnet:
       case Coin.dogecoin:
@@ -85,6 +87,10 @@ abstract class Constants {
       case Coin.dogecoinTestNet:
         return 60;
 
+      case Coin.litecoin:
+      case Coin.litecoinTestNet:
+        return 150;
+
       case Coin.firo:
       case Coin.firoTestNet:
         return 150;
diff --git a/lib/utilities/default_nodes.dart b/lib/utilities/default_nodes.dart
index 566b829ce..bfe5ada88 100644
--- a/lib/utilities/default_nodes.dart
+++ b/lib/utilities/default_nodes.dart
@@ -9,6 +9,7 @@ abstract class DefaultNodes {
 
   static List<NodeModel> get all => [
         bitcoin,
+        litecoin,
         dogecoin,
         firo,
         monero,
@@ -17,6 +18,7 @@ abstract class DefaultNodes {
         namecoin,
         wownero,
         bitcoinTestnet,
+        litecoinTestNet,
         bitcoincashTestnet,
         dogecoinTestnet,
         firoTestnet,
@@ -34,6 +36,30 @@ abstract class DefaultNodes {
         isDown: false,
       );
 
+  static NodeModel get litecoin => NodeModel(
+        host: "electrum1.cipig.net",
+        port: 20063,
+        name: defaultName,
+        id: _nodeId(Coin.litecoin),
+        useSSL: true,
+        enabled: true,
+        coinName: Coin.litecoin.name,
+        isFailover: true,
+        isDown: false,
+      );
+
+  static NodeModel get litecoinTestNet => NodeModel(
+        host: "electrum.ltc.xurious.com",
+        port: 51002,
+        name: defaultName,
+        id: _nodeId(Coin.litecoinTestNet),
+        useSSL: true,
+        enabled: true,
+        coinName: Coin.litecoinTestNet.name,
+        isFailover: true,
+        isDown: false,
+      );
+
   static NodeModel get bitcoincash => NodeModel(
         host: "bitcoincash.stackwallet.com",
         port: 50002,
@@ -171,6 +197,9 @@ abstract class DefaultNodes {
       case Coin.bitcoin:
         return bitcoin;
 
+      case Coin.litecoin:
+        return litecoin;
+
       case Coin.bitcoincash:
         return bitcoincash;
 
@@ -195,6 +224,9 @@ abstract class DefaultNodes {
       case Coin.bitcoinTestNet:
         return bitcoinTestnet;
 
+      case Coin.litecoinTestNet:
+        return litecoinTestNet;
+
       case Coin.bitcoincashTestnet:
         return bitcoincashTestnet;
 
diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart
index c25a5ca4e..86054979a 100644
--- a/lib/utilities/enums/coin_enum.dart
+++ b/lib/utilities/enums/coin_enum.dart
@@ -1,4 +1,6 @@
 import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as btc;
+import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart'
+    as ltc;
 import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'
     as bch;
 import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'
@@ -22,10 +24,13 @@ enum Coin {
   namecoin,
 
   ///
+  litecoin,
+
   ///
   ///
 
   bitcoinTestNet,
+  litecoinTestNet,
   bitcoincashTestnet,
   dogecoinTestNet,
   firoTestNet,
@@ -39,6 +44,8 @@ extension CoinExt on Coin {
     switch (this) {
       case Coin.bitcoin:
         return "Bitcoin";
+      case Coin.litecoin:
+        return "Litecoin";
       case Coin.bitcoincash:
         return "Bitcoin Cash";
       case Coin.dogecoin:
@@ -55,6 +62,8 @@ extension CoinExt on Coin {
         return "Namecoin";
       case Coin.bitcoinTestNet:
         return "tBitcoin";
+      case Coin.litecoinTestNet:
+        return "tLitecoin";
       case Coin.bitcoincashTestnet:
         return "tBitcoin Cash";
       case Coin.firoTestNet:
@@ -68,6 +77,8 @@ extension CoinExt on Coin {
     switch (this) {
       case Coin.bitcoin:
         return "BTC";
+      case Coin.litecoin:
+        return "LTC";
       case Coin.bitcoincash:
         return "BCH";
       case Coin.dogecoin:
@@ -84,6 +95,8 @@ extension CoinExt on Coin {
         return "NMC";
       case Coin.bitcoinTestNet:
         return "tBTC";
+      case Coin.litecoinTestNet:
+        return "tLTC";
       case Coin.bitcoincashTestnet:
         return "tBCH";
       case Coin.firoTestNet:
@@ -97,6 +110,8 @@ extension CoinExt on Coin {
     switch (this) {
       case Coin.bitcoin:
         return "bitcoin";
+      case Coin.litecoin:
+        return "litecoin";
       case Coin.bitcoincash:
         return "bitcoincash";
       case Coin.dogecoin:
@@ -114,6 +129,8 @@ extension CoinExt on Coin {
         return "namecoin";
       case Coin.bitcoinTestNet:
         return "bitcoin";
+      case Coin.litecoinTestNet:
+        return "litecoin";
       case Coin.bitcoincashTestnet:
         return "bitcoincash";
       case Coin.firoTestNet:
@@ -126,11 +143,13 @@ extension CoinExt on Coin {
   bool get isElectrumXCoin {
     switch (this) {
       case Coin.bitcoin:
+      case Coin.litecoin:
       case Coin.bitcoincash:
       case Coin.dogecoin:
       case Coin.firo:
       case Coin.namecoin:
       case Coin.bitcoinTestNet:
+      case Coin.litecoinTestNet:
       case Coin.bitcoincashTestnet:
       case Coin.firoTestNet:
       case Coin.dogecoinTestNet:
@@ -149,6 +168,10 @@ extension CoinExt on Coin {
       case Coin.bitcoinTestNet:
         return btc.MINIMUM_CONFIRMATIONS;
 
+      case Coin.litecoin:
+      case Coin.litecoinTestNet:
+        return ltc.MINIMUM_CONFIRMATIONS;
+
       case Coin.bitcoincash:
       case Coin.bitcoincashTestnet:
         return bch.MINIMUM_CONFIRMATIONS;
@@ -182,6 +205,10 @@ Coin coinFromPrettyName(String name) {
     case "bitcoin":
       return Coin.bitcoin;
 
+    case "Litecoin":
+    case "litecoin":
+      return Coin.litecoin;
+
     case "Bitcoincash":
     case "bitcoincash":
     case "Bitcoin Cash":
@@ -212,6 +239,12 @@ Coin coinFromPrettyName(String name) {
     case "bitcoinTestNet":
       return Coin.bitcoinTestNet;
 
+    case "Litecoin Testnet":
+    case "tlitecoin":
+    case "litecoinTestNet":
+    case "tLitecoin":
+      return Coin.litecoinTestNet;
+
     case "Bitcoincash Testnet":
     case "tBitcoin Cash":
     case "Bitcoin Cash Testnet":
@@ -243,6 +276,8 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
   switch (ticker.toLowerCase()) {
     case "btc":
       return Coin.bitcoin;
+    case "ltc":
+      return Coin.litecoin;
     case "bch":
       return Coin.bitcoincash;
     case "doge":
diff --git a/lib/utilities/theme/color_theme.dart b/lib/utilities/theme/color_theme.dart
index 361d922dc..49fd41a6e 100644
--- a/lib/utilities/theme/color_theme.dart
+++ b/lib/utilities/theme/color_theme.dart
@@ -181,6 +181,7 @@ class CoinThemeColor {
   const CoinThemeColor();
 
   Color get bitcoin => const Color(0xFFFCC17B);
+  Color get litecoin => const Color(0xFF7FA6E1);
   Color get bitcoincash => const Color(0xFF7BCFB8);
   Color get firo => const Color(0xFFFF897A);
   Color get dogecoin => const Color(0xFFFFE079);
@@ -194,6 +195,9 @@ class CoinThemeColor {
       case Coin.bitcoin:
       case Coin.bitcoinTestNet:
         return bitcoin;
+      case Coin.litecoin:
+      case Coin.litecoinTestNet:
+        return litecoin;
       case Coin.bitcoincash:
       case Coin.bitcoincashTestnet:
         return bitcoincash;
diff --git a/lib/utilities/theme/stack_colors.dart b/lib/utilities/theme/stack_colors.dart
index 67f1601f1..8a241db06 100644
--- a/lib/utilities/theme/stack_colors.dart
+++ b/lib/utilities/theme/stack_colors.dart
@@ -1406,6 +1406,9 @@ class StackColors extends ThemeExtension<StackColors> {
       case Coin.bitcoin:
       case Coin.bitcoinTestNet:
         return _coin.bitcoin;
+      case Coin.litecoin:
+      case Coin.litecoinTestNet:
+        return _coin.litecoin;
       case Coin.bitcoincash:
       case Coin.bitcoincashTestnet:
         return _coin.bitcoincash;
diff --git a/pubspec.lock b/pubspec.lock
index 394d1ec8e..6b8a140f6 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -42,7 +42,7 @@ packages:
       name: archive
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "3.1.11"
+    version: "3.3.0"
   args:
     dependency: transitive
     description:
@@ -63,7 +63,7 @@ packages:
       name: async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.8.2"
+    version: "2.9.0"
   barcode_scan2:
     dependency: "direct main"
     description:
@@ -190,14 +190,7 @@ packages:
       name: characters
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.2.0"
-  charcode:
-    dependency: transitive
-    description:
-      name: charcode
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "1.3.1"
+    version: "1.2.1"
   checked_yaml:
     dependency: transitive
     description:
@@ -211,7 +204,7 @@ packages:
       name: clock
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.0"
+    version: "1.1.1"
   code_builder:
     dependency: transitive
     description:
@@ -281,7 +274,7 @@ packages:
       name: coverage
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.2.0"
+    version: "1.5.0"
   cross_file:
     dependency: transitive
     description:
@@ -435,7 +428,7 @@ packages:
       name: fake_async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.0"
+    version: "1.3.1"
   ffi:
     dependency: "direct main"
     description:
@@ -864,21 +857,21 @@ packages:
       name: matcher
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.12.11"
+    version: "0.12.12"
   material_color_utilities:
     dependency: transitive
     description:
       name: material_color_utilities
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.1.4"
+    version: "0.1.5"
   meta:
     dependency: transitive
     description:
       name: meta
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.7.0"
+    version: "1.8.0"
   mime:
     dependency: transitive
     description:
@@ -990,7 +983,7 @@ packages:
       name: path
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.8.1"
+    version: "1.8.2"
   path_drawing:
     dependency: transitive
     description:
@@ -1366,7 +1359,7 @@ packages:
       name: source_span
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.8.2"
+    version: "1.9.0"
   stack_trace:
     dependency: transitive
     description:
@@ -1424,35 +1417,35 @@ packages:
       name: sync_http
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.3.0"
+    version: "0.3.1"
   term_glyph:
     dependency: transitive
     description:
       name: term_glyph
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.2.0"
+    version: "1.2.1"
   test:
     dependency: transitive
     description:
       name: test
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.21.1"
+    version: "1.21.4"
   test_api:
     dependency: transitive
     description:
       name: test_api
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.9"
+    version: "0.4.12"
   test_core:
     dependency: transitive
     description:
       name: test_core
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.13"
+    version: "0.4.16"
   time:
     dependency: transitive
     description:
@@ -1501,7 +1494,7 @@ packages:
       name: typed_data
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.0"
+    version: "1.3.1"
   universal_io:
     dependency: transitive
     description:
@@ -1585,7 +1578,7 @@ packages:
       name: vm_service
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "8.2.2"
+    version: "9.0.0"
   wakelock:
     dependency: "direct main"
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 42934fd5c..ca3c253ac 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -196,6 +196,7 @@ flutter:
     - assets/images/monero.png
     - assets/images/wownero.png
     - assets/images/firo.png
+    - assets/images/litecoin.png
     - assets/images/doge.png
     - assets/images/bitcoin.png
     - assets/images/epic-cash.png
@@ -310,6 +311,7 @@ flutter:
     - assets/svg/exit-desktop.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
+    - assets/svg/coin_icons/Litecoin.svg
     - assets/svg/coin_icons/Bitcoincash.svg
     - assets/svg/coin_icons/Dogecoin.svg
     - assets/svg/coin_icons/EpicCash.svg
diff --git a/test/price_test.dart b/test/price_test.dart
index 6abbb6741..0dbcdd450 100644
--- a/test/price_test.dart
+++ b/test/price_test.dart
@@ -26,7 +26,7 @@ void main() {
 
     when(client.get(
         Uri.parse(
-            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
+            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
         headers: {
           'Content-Type': 'application/json'
         })).thenAnswer((_) async => Response(
@@ -39,10 +39,10 @@ void main() {
     final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
 
     expect(price.toString(),
-        '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
+        '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
     verify(client.get(
         Uri.parse(
-            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
+            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
         headers: {'Content-Type': 'application/json'})).called(1);
 
     verifyNoMoreInteractions(client);
@@ -53,7 +53,7 @@ void main() {
 
     when(client.get(
         Uri.parse(
-            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
+            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
         headers: {
           'Content-Type': 'application/json'
         })).thenAnswer((_) async => Response(
@@ -71,12 +71,12 @@ void main() {
         await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
 
     expect(cachedPrice.toString(),
-        '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
+        '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
 
     // verify only called once during filling of cache
     verify(client.get(
         Uri.parse(
-            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
+            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
         headers: {'Content-Type': 'application/json'})).called(1);
 
     verifyNoMoreInteractions(client);
@@ -87,7 +87,7 @@ void main() {
 
     when(client.get(
         Uri.parse(
-            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
+            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
         headers: {
           'Content-Type': 'application/json'
         })).thenAnswer((_) async => Response(
@@ -100,7 +100,7 @@ void main() {
     final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
 
     expect(price.toString(),
-        '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
+        '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
   });
 
   test("no internet available", () async {
@@ -108,7 +108,7 @@ void main() {
 
     when(client.get(
         Uri.parse(
-            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
+            "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
         headers: {
           'Content-Type': 'application/json'
         })).thenThrow(const SocketException(
@@ -120,7 +120,7 @@ void main() {
     final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
 
     expect(price.toString(),
-        '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
+        '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
   });
 
   tearDown(() async {

From 86119f7189f469bac6a51bc7f208deceb40bdca6 Mon Sep 17 00:00:00 2001
From: Marco <marco@cypherstack.com>
Date: Fri, 28 Oct 2022 13:17:35 -0600
Subject: [PATCH 060/426] change to stack wallet node

---
 lib/utilities/default_nodes.dart | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/utilities/default_nodes.dart b/lib/utilities/default_nodes.dart
index bfe5ada88..abe702b78 100644
--- a/lib/utilities/default_nodes.dart
+++ b/lib/utilities/default_nodes.dart
@@ -37,7 +37,7 @@ abstract class DefaultNodes {
       );
 
   static NodeModel get litecoin => NodeModel(
-        host: "electrum1.cipig.net",
+        host: "litecoin.stackwallet.com",
         port: 20063,
         name: defaultName,
         id: _nodeId(Coin.litecoin),
@@ -49,7 +49,7 @@ abstract class DefaultNodes {
       );
 
   static NodeModel get litecoinTestNet => NodeModel(
-        host: "electrum.ltc.xurious.com",
+        host: "litecoin.stackwallet.com",
         port: 51002,
         name: defaultName,
         id: _nodeId(Coin.litecoinTestNet),

From 3a15538273bebc377b1c2b22fd5c91ee81fb441a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 28 Oct 2022 13:51:25 -0600
Subject: [PATCH 061/426] WIP: desktop wallet keys popup layouts

---
 assets/svg/keys.svg                           |  23 ++
 .../sub_widgets/mnemonic_table.dart           |   4 +
 .../sub_widgets/mnemonic_table_item.dart      |   3 +
 .../wallet_view/desktop_wallet_view.dart      | 332 +++++++++++++++++-
 lib/utilities/assets.dart                     |   1 +
 lib/widgets/rounded_white_container.dart      |   2 +-
 pubspec.yaml                                  |   1 +
 7 files changed, 363 insertions(+), 3 deletions(-)
 create mode 100644 assets/svg/keys.svg

diff --git a/assets/svg/keys.svg b/assets/svg/keys.svg
new file mode 100644
index 000000000..cf86daea5
--- /dev/null
+++ b/assets/svg/keys.svg
@@ -0,0 +1,23 @@
+<svg width="99" height="57" viewBox="0 0 99 57" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_6055_8386)">
+<path d="M90.1893 8.04883H18.9405C14.0708 8.04883 10.123 11.9965 10.123 16.8663V47.6738C10.123 52.5436 14.0708 56.4913 18.9405 56.4913H90.1893C95.0591 56.4913 99.0068 52.5436 99.0068 47.6738V16.8663C99.0068 11.9965 95.0591 8.04883 90.1893 8.04883Z" fill="#E1E2E3"/>
+<path d="M91.9528 5.84445V44.9928C91.9528 47.7275 89.7366 49.9437 87.002 49.9437H5.85138C3.11082 49.9437 0.894531 47.7275 0.894531 44.9928V5.84445C0.894531 3.10984 3.11082 0.893555 5.85138 0.893555L88.2888 1.06037C90.4038 1.63232 91.9528 3.55667 91.9528 5.84445V5.84445Z" stroke="#222222" stroke-width="3" stroke-miterlimit="10"/>
+<path d="M15.9121 18.4336V32.4045" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M9.86523 21.9248L21.9595 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M21.9595 21.9248L9.86523 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M36.252 18.4336V32.4045" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M30.2051 21.9248L42.2993 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M42.2993 21.9248L30.2051 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M56.5918 18.4336V32.4045" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M50.5449 21.9248L62.6392 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M62.6392 21.9248L50.5449 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M76.9316 18.4336V32.4045" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M70.8848 21.9248L82.979 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+<path d="M82.979 21.9248L70.8848 28.9073" stroke="#222222" stroke-width="3" stroke-miterlimit="10" stroke-linecap="round"/>
+</g>
+<defs>
+<clipPath id="clip0_6055_8386">
+<rect width="99" height="56.4914" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart
index 946f54d4a..7d21dfec4 100644
--- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart
+++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart
@@ -6,10 +6,12 @@ class MnemonicTable extends StatelessWidget {
     Key? key,
     required this.words,
     required this.isDesktop,
+    this.itemBorderColor,
   }) : super(key: key);
 
   final List<String> words;
   final bool isDesktop;
+  final Color? itemBorderColor;
 
   @override
   Widget build(BuildContext context) {
@@ -40,6 +42,7 @@ class MnemonicTable extends StatelessWidget {
                       number: ++index,
                       word: words[index - 1],
                       isDesktop: isDesktop,
+                      borderColor: itemBorderColor,
                     ),
                   ),
                 ],
@@ -61,6 +64,7 @@ class MnemonicTable extends StatelessWidget {
                       number: i + 1,
                       word: words[i],
                       isDesktop: isDesktop,
+                      borderColor: itemBorderColor,
                     ),
                   ),
                 ],
diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart
index 8928ff3a6..ec103dfc6 100644
--- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart
+++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart
@@ -9,16 +9,19 @@ class MnemonicTableItem extends StatelessWidget {
     required this.number,
     required this.word,
     required this.isDesktop,
+    this.borderColor,
   }) : super(key: key);
 
   final int number;
   final String word;
   final bool isDesktop;
+  final Color? borderColor;
 
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
     return RoundedWhiteContainer(
+      borderColor: borderColor,
       padding: isDesktop
           ? const EdgeInsets.symmetric(horizontal: 12, vertical: 9)
           : const EdgeInsets.all(8),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 35b63174c..513be380b 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -4,6 +4,7 @@ import 'package:event_bus/event_bus.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
 import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
 import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
@@ -30,10 +31,14 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 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/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:tuple/tuple.dart';
 
 /// [eventBus] should only be set during testing
@@ -246,7 +251,9 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
             const SizedBox(
               width: 32,
             ),
-            const WalletKeysButton(),
+            WalletKeysButton(
+              walletId: walletId,
+            ),
             const SizedBox(
               width: 32,
             ),
@@ -766,11 +773,24 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
 }
 
 class WalletKeysButton extends StatelessWidget {
-  const WalletKeysButton({Key? key}) : super(key: key);
+  const WalletKeysButton({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
 
   @override
   Widget build(BuildContext context) {
     return GestureDetector(
+      onTap: () {
+        showDialog<void>(
+          context: context,
+          builder: (context) => UnlockWalletKeysDesktop(
+            walletId: walletId,
+          ),
+        );
+      },
       child: Container(
         color: Colors.transparent,
         child: Row(
@@ -796,3 +816,311 @@ class WalletKeysButton extends StatelessWidget {
     );
   }
 }
+
+class UnlockWalletKeysDesktop extends ConsumerStatefulWidget {
+  const UnlockWalletKeysDesktop({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  @override
+  ConsumerState<UnlockWalletKeysDesktop> createState() =>
+      _UnlockWalletKeysDesktopState();
+}
+
+class _UnlockWalletKeysDesktopState
+    extends ConsumerState<UnlockWalletKeysDesktop> {
+  late final TextEditingController passwordController;
+
+  late final FocusNode passwordFocusNode;
+
+  bool continueEnabled = false;
+  bool hidePassword = true;
+
+  @override
+  void initState() {
+    passwordController = TextEditingController();
+    passwordFocusNode = FocusNode();
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    passwordController.dispose();
+    passwordFocusNode.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 579,
+      maxHeight: double.infinity,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.end,
+            children: const [
+              DesktopDialogCloseButton(),
+            ],
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          SvgPicture.asset(
+            Assets.svg.keys,
+            width: 100,
+            height: 58,
+          ),
+          const SizedBox(
+            height: 55,
+          ),
+          Text(
+            "Wallet keys",
+            style: STextStyles.desktopH2(context),
+          ),
+          const SizedBox(
+            height: 16,
+          ),
+          Text(
+            "Enter your password",
+            style: STextStyles.desktopTextMedium(context).copyWith(
+              color: Theme.of(context).extension<StackColors>()!.textDark3,
+            ),
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                key: const Key("enterPasswordUnlockWalletKeysDesktopFieldKey"),
+                focusNode: passwordFocusNode,
+                controller: passwordController,
+                style: STextStyles.desktopTextMedium(context).copyWith(
+                  height: 2,
+                ),
+                obscureText: hidePassword,
+                enableSuggestions: false,
+                autocorrect: false,
+                decoration: standardInputDecoration(
+                  "Enter password",
+                  passwordFocusNode,
+                  context,
+                ).copyWith(
+                  suffixIcon: UnconstrainedBox(
+                    child: SizedBox(
+                      height: 70,
+                      child: Row(
+                        children: [
+                          GestureDetector(
+                            key: const Key(
+                                "enterUnlockWalletKeysDesktopFieldShowPasswordButtonKey"),
+                            onTap: () async {
+                              setState(() {
+                                hidePassword = !hidePassword;
+                              });
+                            },
+                            child: Container(
+                              decoration: BoxDecoration(
+                                color: Colors.transparent,
+                                borderRadius: BorderRadius.circular(1000),
+                              ),
+                              height: 32,
+                              width: 32,
+                              child: Center(
+                                child: SvgPicture.asset(
+                                  hidePassword
+                                      ? Assets.svg.eye
+                                      : Assets.svg.eyeSlash,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark3,
+                                  width: 24,
+                                  height: 19,
+                                ),
+                              ),
+                            ),
+                          ),
+                          const SizedBox(
+                            width: 10,
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                onChanged: (newValue) {
+                  setState(() {
+                    continueEnabled = newValue.isNotEmpty;
+                  });
+                },
+              ),
+            ),
+          ),
+          const SizedBox(
+            height: 55,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    onPressed: Navigator.of(context).pop,
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Continue",
+                    enabled: continueEnabled,
+                    onPressed: continueEnabled
+                        ? () async {
+                            // todo: check password
+                            Navigator.of(context).pop();
+                            final words = await ref
+                                .read(walletsChangeNotifierProvider)
+                                .getManager(widget.walletId)
+                                .mnemonic;
+                            await showDialog<void>(
+                              context: context,
+                              builder: (context) => WalletKeysDesktopPopup(
+                                words: words,
+                              ),
+                            );
+                          }
+                        : null,
+                  ),
+                ),
+              ],
+            ),
+          ),
+          const SizedBox(
+            height: 32,
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class WalletKeysDesktopPopup extends StatelessWidget {
+  const WalletKeysDesktopPopup({
+    Key? key,
+    required this.words,
+  }) : super(key: key);
+
+  final List<String> words;
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 614,
+      maxHeight: double.infinity,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.only(
+                  left: 32,
+                ),
+                child: Text(
+                  "Wallet keys",
+                  style: STextStyles.desktopH3(context),
+                ),
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+          const SizedBox(
+            height: 28,
+          ),
+          Text(
+            "Recovery phrase",
+            style: STextStyles.desktopTextMedium(context),
+          ),
+          const SizedBox(
+            height: 8,
+          ),
+          Center(
+            child: Padding(
+              padding: const EdgeInsets.symmetric(
+                horizontal: 32,
+              ),
+              child: Text(
+                "Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
+                style: STextStyles.desktopTextExtraExtraSmall(context),
+                textAlign: TextAlign.center,
+              ),
+            ),
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: MnemonicTable(
+              words: words,
+              isDesktop: true,
+              itemBorderColor: Theme.of(context)
+                  .extension<StackColors>()!
+                  .buttonBackSecondary,
+            ),
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Show QR code",
+                    onPressed: () {
+                      // todo show qr code
+                    },
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Copy",
+                    onPressed: () {
+                      // todo copy to clipboard
+                    },
+                  ),
+                ),
+              ],
+            ),
+          ),
+          const SizedBox(
+            height: 32,
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index ebe2d9848..c730b1aa1 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -144,6 +144,7 @@ class _SVG {
   String get aboutDesktop => "assets/svg/about-desktop.svg";
   String get walletDesktop => "assets/svg/wallet-desktop.svg";
   String get exitDesktop => "assets/svg/exit-desktop.svg";
+  String get keys => "assets/svg/keys.svg";
 
   String get ellipse1 => "assets/svg/Ellipse-43.svg";
   String get ellipse2 => "assets/svg/Ellipse-42.svg";
diff --git a/lib/widgets/rounded_white_container.dart b/lib/widgets/rounded_white_container.dart
index a574dc1ce..1173e95b1 100644
--- a/lib/widgets/rounded_white_container.dart
+++ b/lib/widgets/rounded_white_container.dart
@@ -28,8 +28,8 @@ class RoundedWhiteContainer extends StatelessWidget {
       radiusMultiplier: radiusMultiplier,
       width: width,
       height: height,
-      child: child,
       borderColor: borderColor,
+      child: child,
     );
   }
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index 42934fd5c..75cdc985a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -308,6 +308,7 @@ flutter:
     - assets/svg/exchange-desktop.svg
     - assets/svg/wallet-desktop.svg
     - assets/svg/exit-desktop.svg
+    - assets/svg/keys.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Bitcoincash.svg

From 549087a4f45fb00e7f474eaa37ec67cd1c0640ec Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 28 Oct 2022 14:42:50 -0600
Subject: [PATCH 062/426] WIP: desktop wallet keys popup qr code

---
 .../wallet_view/desktop_wallet_view.dart      | 91 +++++++++++++++++--
 lib/route_generator.dart                      | 28 ++++++
 2 files changed, 113 insertions(+), 6 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 513be380b..0e5aa925f 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -2,8 +2,11 @@ import 'dart:async';
 
 import 'package:event_bus/event_bus.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:qr_flutter/qr_flutter.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
 import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
@@ -16,15 +19,19 @@ import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_vie
 import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_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/exchange/change_now/change_now_exchange.dart';
 import 'package:stackwallet/services/exchange/exchange_data_loading_service.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/constants.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -786,6 +793,7 @@ class WalletKeysButton extends StatelessWidget {
       onTap: () {
         showDialog<void>(
           context: context,
+          barrierDismissible: false,
           builder: (context) => UnlockWalletKeysDesktop(
             walletId: walletId,
           ),
@@ -998,8 +1006,20 @@ class _UnlockWalletKeysDesktopState
                                 .mnemonic;
                             await showDialog<void>(
                               context: context,
-                              builder: (context) => WalletKeysDesktopPopup(
-                                words: words,
+                              barrierDismissible: false,
+                              builder: (context) => Navigator(
+                                initialRoute: WalletKeysDesktopPopup.routeName,
+                                onGenerateRoute: RouteGenerator.generateRoute,
+                                onGenerateInitialRoutes: (_, __) {
+                                  return [
+                                    RouteGenerator.generateRoute(
+                                      RouteSettings(
+                                        name: WalletKeysDesktopPopup.routeName,
+                                        arguments: words,
+                                      ),
+                                    )
+                                  ];
+                                },
                               ),
                             );
                           }
@@ -1022,9 +1042,13 @@ class WalletKeysDesktopPopup extends StatelessWidget {
   const WalletKeysDesktopPopup({
     Key? key,
     required this.words,
+    this.clipboardInterface = const ClipboardWrapper(),
   }) : super(key: key);
 
   final List<String> words;
+  final ClipboardInterface clipboardInterface;
+
+  static const String routeName = "walletKeysDesktopPopup";
 
   @override
   Widget build(BuildContext context) {
@@ -1045,7 +1069,11 @@ class WalletKeysDesktopPopup extends StatelessWidget {
                   style: STextStyles.desktopH3(context),
                 ),
               ),
-              const DesktopDialogCloseButton(),
+              DesktopDialogCloseButton(
+                onPressedOverride: () {
+                  Navigator.of(context, rootNavigator: true).pop();
+                },
+              ),
             ],
           ),
           const SizedBox(
@@ -1098,7 +1126,11 @@ class WalletKeysDesktopPopup extends StatelessWidget {
                   child: SecondaryButton(
                     label: "Show QR code",
                     onPressed: () {
-                      // todo show qr code
+                      final String value = AddressUtils.encodeQRSeedData(words);
+                      Navigator.of(context).pushNamed(
+                        QRCodeDesktopPopupContent.routeName,
+                        arguments: value,
+                      );
                     },
                   ),
                 ),
@@ -1108,8 +1140,18 @@ class WalletKeysDesktopPopup extends StatelessWidget {
                 Expanded(
                   child: PrimaryButton(
                     label: "Copy",
-                    onPressed: () {
-                      // todo copy to clipboard
+                    onPressed: () async {
+                      await clipboardInterface.setData(
+                        ClipboardData(text: words.join(" ")),
+                      );
+                      unawaited(
+                        showFloatingFlushBar(
+                          type: FlushBarType.info,
+                          message: "Copied to clipboard",
+                          iconAsset: Assets.svg.copy,
+                          context: context,
+                        ),
+                      );
                     },
                   ),
                 ),
@@ -1124,3 +1166,40 @@ class WalletKeysDesktopPopup extends StatelessWidget {
     );
   }
 }
+
+class QRCodeDesktopPopupContent extends StatelessWidget {
+  const QRCodeDesktopPopupContent({
+    Key? key,
+    required this.value,
+  }) : super(key: key);
+
+  final String value;
+
+  static const String routeName = "qrCodeDesktopPopupContent";
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 614,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.end,
+            children: const [
+              DesktopDialogCloseButton(),
+            ],
+          ),
+          const SizedBox(
+            height: 14,
+          ),
+          QrImage(
+            data: value,
+            size: 300,
+            foregroundColor:
+                Theme.of(context).extension<StackColors>()!.accentColorDark,
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index f915e7837..c37e0da5c 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -1048,6 +1048,34 @@ class RouteGenerator {
             builder: (_) => const AdvancedSettings(),
             settings: RouteSettings(name: settings.name));
 
+      case WalletKeysDesktopPopup.routeName:
+        if (args is List<String>) {
+          return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => WalletKeysDesktopPopup(
+              words: args,
+            ),
+            settings: RouteSettings(
+              name: settings.name,
+            ),
+          );
+        }
+        return _routeError("${settings.name} invalid args: ${args.toString()}");
+
+      case QRCodeDesktopPopupContent.routeName:
+        if (args is String) {
+          return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => QRCodeDesktopPopupContent(
+              value: args,
+            ),
+            settings: RouteSettings(
+              name: settings.name,
+            ),
+          );
+        }
+        return _routeError("${settings.name} invalid args: ${args.toString()}");
+
       // == End of desktop specific routes =====================================
 
       default:

From e64c0672121fd0e0151d3ec3b70125623059a97a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 28 Oct 2022 15:11:01 -0600
Subject: [PATCH 063/426] desktop all transaction list item layout

---
 .../all_transactions_view.dart                | 268 +++++++++++++++++-
 1 file changed, 257 insertions(+), 11 deletions(-)

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 7122f5379..192389720 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -1,15 +1,23 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/models/paymint/transactions_model.dart';
 import 'package:stackwallet/models/transaction_filter.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/pages/wallet_view/transaction_views/transaction_search_filter_view.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';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
+import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
@@ -437,21 +445,46 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
                                   const SizedBox(
                                     height: 12,
                                   ),
-                                  RoundedWhiteContainer(
-                                    padding: const EdgeInsets.all(0),
-                                    child: Column(
-                                      children: [
-                                        ...month.item2.map(
-                                          (tx) => TransactionCard(
-                                            key: Key(
-                                                "transactionCard_key_${tx.txid}"),
-                                            transaction: tx,
+                                  if (isDesktop)
+                                    RoundedWhiteContainer(
+                                      padding: const EdgeInsets.all(0),
+                                      child: ListView.separated(
+                                        shrinkWrap: true,
+                                        primary: false,
+                                        separatorBuilder: (context, _) =>
+                                            Container(
+                                          height: 1,
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .background,
+                                        ),
+                                        itemCount: month.item2.length,
+                                        itemBuilder: (context, index) =>
+                                            Padding(
+                                          padding: const EdgeInsets.all(4),
+                                          child: DesktopTransactionCardRow(
+                                            transaction: month.item2[index],
                                             walletId: walletId,
                                           ),
                                         ),
-                                      ],
+                                      ),
+                                    ),
+                                  if (!isDesktop)
+                                    RoundedWhiteContainer(
+                                      padding: const EdgeInsets.all(0),
+                                      child: Column(
+                                        children: [
+                                          ...month.item2.map(
+                                            (tx) => TransactionCard(
+                                              key: Key(
+                                                  "transactionCard_key_${tx.txid}"),
+                                              transaction: tx,
+                                              walletId: walletId,
+                                            ),
+                                          ),
+                                        ],
+                                      ),
                                     ),
-                                  ),
                                 ],
                               ),
                             );
@@ -472,3 +505,216 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
     );
   }
 }
+
+class DesktopTransactionCardRow extends ConsumerStatefulWidget {
+  const DesktopTransactionCardRow({
+    Key? key,
+    required this.transaction,
+    required this.walletId,
+  }) : super(key: key);
+
+  final Transaction transaction;
+  final String walletId;
+
+  @override
+  ConsumerState<DesktopTransactionCardRow> createState() =>
+      _DesktopTransactionCardRowState();
+}
+
+class _DesktopTransactionCardRowState
+    extends ConsumerState<DesktopTransactionCardRow> {
+  late final Transaction _transaction;
+  late final String walletId;
+
+  String whatIsIt(String type, Coin coin) {
+    if (coin == Coin.epicCash && _transaction.slateId == null) {
+      return "Restored Funds";
+    }
+
+    if (_transaction.subType == "mint") {
+      if (_transaction.confirmedStatus) {
+        return "Anonymized";
+      } else {
+        return "Anonymizing";
+      }
+    }
+
+    if (type == "Received") {
+      if (_transaction.confirmedStatus) {
+        return "Received";
+      } else {
+        return "Receiving";
+      }
+    } else if (type == "Sent") {
+      if (_transaction.confirmedStatus) {
+        return "Sent";
+      } else {
+        return "Sending";
+      }
+    } else {
+      return type;
+    }
+  }
+
+  @override
+  void initState() {
+    walletId = widget.walletId;
+    _transaction = widget.transaction;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final locale = ref.watch(
+        localeServiceChangeNotifierProvider.select((value) => value.locale));
+    final manager = ref.watch(walletsChangeNotifierProvider
+        .select((value) => value.getManager(walletId)));
+
+    final baseCurrency = ref
+        .watch(prefsChangeNotifierProvider.select((value) => value.currency));
+
+    final coin = manager.coin;
+
+    final price = ref
+        .watch(priceAnd24hChangeNotifierProvider
+            .select((value) => value.getPrice(coin)))
+        .item1;
+
+    late final String prefix;
+    if (Util.isDesktop) {
+      if (_transaction.txType == "Sent") {
+        prefix = "-";
+      } else if (_transaction.txType == "Received") {
+        prefix = "+";
+      }
+    } else {
+      prefix = "";
+    }
+
+    return Material(
+      color: Theme.of(context).extension<StackColors>()!.popupBG,
+      elevation: 0,
+      shape: RoundedRectangleBorder(
+        borderRadius:
+            BorderRadius.circular(Constants.size.circularBorderRadius),
+      ),
+      child: RawMaterialButton(
+        shape: RoundedRectangleBorder(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
+          ),
+        ),
+        onPressed: () async {
+          if (coin == Coin.epicCash && _transaction.slateId == null) {
+            unawaited(
+              showFloatingFlushBar(
+                context: context,
+                message:
+                    "Restored Epic funds from your Seed have no Data.\nUse Stack Backup to keep your transaction history.",
+                type: FlushBarType.warning,
+                duration: const Duration(seconds: 5),
+              ),
+            );
+            return;
+          }
+          unawaited(
+            Navigator.of(context).pushNamed(
+              TransactionDetailsView.routeName,
+              arguments: Tuple3(
+                _transaction,
+                coin,
+                walletId,
+              ),
+            ),
+          );
+        },
+        child: Padding(
+          padding: const EdgeInsets.symmetric(
+            vertical: 10,
+            horizontal: 16,
+          ),
+          child: Row(
+            children: [
+              TxIcon(transaction: _transaction),
+              const SizedBox(
+                width: 12,
+              ),
+              Expanded(
+                flex: 3,
+                child: Text(
+                  _transaction.isCancelled
+                      ? "Cancelled"
+                      : whatIsIt(_transaction.txType, coin),
+                  style:
+                      STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                    color: Theme.of(context).extension<StackColors>()!.textDark,
+                  ),
+                ),
+              ),
+              Expanded(
+                flex: 4,
+                child: Text(
+                  Format.extractDateFrom(_transaction.timestamp),
+                  style: STextStyles.label(context),
+                ),
+              ),
+              Expanded(
+                flex: 6,
+                child: Builder(
+                  builder: (_) {
+                    final amount = coin == Coin.monero
+                        ? (_transaction.amount ~/ 10000)
+                        : coin == Coin.wownero
+                            ? (_transaction.amount ~/ 1000)
+                            : _transaction.amount;
+                    return Text(
+                      "$prefix${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}",
+                      style: STextStyles.desktopTextExtraExtraSmall(context)
+                          .copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark,
+                      ),
+                    );
+                  },
+                ),
+              ),
+              if (ref.watch(prefsChangeNotifierProvider
+                  .select((value) => value.externalCalls)))
+                Expanded(
+                  flex: 4,
+                  child: Builder(
+                    builder: (_) {
+                      // TODO: modify Format.<functions> to take optional Coin parameter so this type oif check isn't done in ui
+                      int value = _transaction.amount;
+                      if (coin == Coin.monero) {
+                        value = (value ~/ 10000);
+                      } else if (coin == Coin.wownero) {
+                        value = (value ~/ 1000);
+                      }
+
+                      return Text(
+                        "$prefix${Format.localizedStringAsFixed(
+                          value: Format.satoshisToAmount(value) * price,
+                          locale: locale,
+                          decimalPlaces: 2,
+                        )} $baseCurrency",
+                        style: STextStyles.desktopTextExtraExtraSmall(context),
+                      );
+                    },
+                  ),
+                ),
+              SvgPicture.asset(
+                Assets.svg.circleInfo,
+                width: 20,
+                height: 20,
+                color:
+                    Theme.of(context).extension<StackColors>()!.textSubtitle2,
+              ),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}

From 0074fcabd250106d383f1b054296d941c75c94d7 Mon Sep 17 00:00:00 2001
From: Marco <marco@cypherstack.com>
Date: Fri, 28 Oct 2022 15:45:03 -0600
Subject: [PATCH 064/426] add new litecoin nodes

---
 .../manage_nodes_views/add_edit_node_view.dart                  | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index ada3c45f9..77349f399 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -117,10 +117,12 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
 
       case Coin.bitcoin:
       case Coin.bitcoincash:
+      case Coin.litecoin:
       case Coin.dogecoin:
       case Coin.firo:
       case Coin.namecoin:
       case Coin.bitcoinTestNet:
+      case Coin.litecoinTestNet:
       case Coin.bitcoincashTestnet:
       case Coin.firoTestNet:
       case Coin.dogecoinTestNet:

From d75f2ed13dc1473e8db8c1b8de7805e1def7f3a5 Mon Sep 17 00:00:00 2001
From: Marco <marco@cypherstack.com>
Date: Fri, 28 Oct 2022 15:50:40 -0600
Subject: [PATCH 065/426] another node switching bug

---
 lib/widgets/node_options_sheet.dart | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/widgets/node_options_sheet.dart b/lib/widgets/node_options_sheet.dart
index effe97097..a5345161c 100644
--- a/lib/widgets/node_options_sheet.dart
+++ b/lib/widgets/node_options_sheet.dart
@@ -102,12 +102,14 @@ class NodeOptionsSheet extends ConsumerWidget {
         break;
 
       case Coin.bitcoin:
+      case Coin.litecoin:
       case Coin.dogecoin:
       case Coin.firo:
       case Coin.bitcoinTestNet:
       case Coin.firoTestNet:
       case Coin.dogecoinTestNet:
       case Coin.bitcoincash:
+      case Coin.litecoinTestNet:
       case Coin.namecoin:
       case Coin.bitcoincashTestnet:
         final client = ElectrumX(

From 2512d65678abfccb6b2646cf3661202a306ff43e Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 28 Oct 2022 16:10:26 -0600
Subject: [PATCH 066/426] v1.5.11 build 83

---
 ios/Runner.xcodeproj/project.pbxproj | 16 +++++++++-------
 pubspec.yaml                         |  2 +-
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 4b7b1058d..2e5d4bac0 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 50;
+	objectVersion = 46;
 	objects = {
 
 /* Begin PBXBuildFile section */
@@ -255,6 +255,7 @@
 				"${BUILT_PRODUCTS_DIR}/cw_monero/cw_monero.framework",
 				"${BUILT_PRODUCTS_DIR}/cw_shared_external/cw_shared_external.framework",
 				"${BUILT_PRODUCTS_DIR}/cw_wownero/cw_wownero.framework",
+				"${BUILT_PRODUCTS_DIR}/device_info_plus/device_info_plus.framework",
 				"${BUILT_PRODUCTS_DIR}/devicelocale/devicelocale.framework",
 				"${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework",
 				"${BUILT_PRODUCTS_DIR}/flutter_libmonero/flutter_libmonero.framework",
@@ -288,6 +289,7 @@
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cw_monero.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cw_shared_external.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cw_wownero.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info_plus.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/devicelocale.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_libmonero.framework",
@@ -454,7 +456,7 @@
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 79;
+				CURRENT_PROJECT_VERSION = 83;
 				DEVELOPMENT_TEAM = 4DQKUWSG6C;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -508,7 +510,7 @@
 					"$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios/**",
 					"$(PROJECT_DIR)/../crypto_plugins/flutter_libepiccash/ios/libs",
 				);
-				MARKETING_VERSION = 1.5.9;
+				MARKETING_VERSION = 1.5.11;
 				ONLY_ACTIVE_ARCH = NO;
 				PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stackwallet;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -641,7 +643,7 @@
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 79;
+				CURRENT_PROJECT_VERSION = 83;
 				DEVELOPMENT_TEAM = 4DQKUWSG6C;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -695,7 +697,7 @@
 					"$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios/**",
 					"$(PROJECT_DIR)/../crypto_plugins/flutter_libepiccash/ios/libs",
 				);
-				MARKETING_VERSION = 1.5.9;
+				MARKETING_VERSION = 1.5.11;
 				ONLY_ACTIVE_ARCH = NO;
 				PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stackwallet;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -720,7 +722,7 @@
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 79;
+				CURRENT_PROJECT_VERSION = 83;
 				DEVELOPMENT_TEAM = 4DQKUWSG6C;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -774,7 +776,7 @@
 					"$(PROJECT_DIR)/../crypto_plugins/flutter_libmonero/cw_shared_external/ios/External/ios/**",
 					"$(PROJECT_DIR)/../crypto_plugins/flutter_libepiccash/ios/libs",
 				);
-				MARKETING_VERSION = 1.5.9;
+				MARKETING_VERSION = 1.5.11;
 				ONLY_ACTIVE_ARCH = NO;
 				PRODUCT_BUNDLE_IDENTIFIER = com.cypherstack.stackwallet;
 				PRODUCT_NAME = "$(TARGET_NAME)";
diff --git a/pubspec.yaml b/pubspec.yaml
index ca3c253ac..ea2fbaa6d 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.9+79
+version: 1.5.11+83
 
 environment:
   sdk: ">=2.17.0 <3.0.0"

From ccdfa8db44a199f891dd35ab457759570f15cbcd Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 28 Oct 2022 16:51:50 -0600
Subject: [PATCH 067/426] WIP: transaction filter+search fixes

---
 lib/models/transaction_filter.dart            |  10 +-
 .../all_transactions_view.dart                | 260 +++++++++++++++++-
 .../transaction_search_filter_view.dart       |  38 ++-
 3 files changed, 287 insertions(+), 21 deletions(-)

diff --git a/lib/models/transaction_filter.dart b/lib/models/transaction_filter.dart
index 119ac7015..7ef5f0bff 100644
--- a/lib/models/transaction_filter.dart
+++ b/lib/models/transaction_filter.dart
@@ -1,14 +1,16 @@
 class TransactionFilter {
   final bool sent;
   final bool received;
-  final DateTime from;
-  final DateTime to;
+  final bool trade;
+  final DateTime? from;
+  final DateTime? to;
   final int? amount;
   final String keyword;
 
   TransactionFilter({
     required this.sent,
     required this.received,
+    required this.trade,
     required this.from,
     required this.to,
     required this.amount,
@@ -18,6 +20,7 @@ class TransactionFilter {
   TransactionFilter copyWith({
     bool? sent,
     bool? received,
+    bool? trade,
     DateTime? from,
     DateTime? to,
     int? amount,
@@ -26,6 +29,7 @@ class TransactionFilter {
     return TransactionFilter(
       sent: sent ?? this.sent,
       received: received ?? this.received,
+      trade: trade ?? this.trade,
       from: from ?? this.from,
       to: to ?? this.to,
       amount: amount ?? this.amount,
@@ -35,6 +39,6 @@ class TransactionFilter {
 
   @override
   String toString() {
-    return "TxFilter { sent: $sent, received: $received, from: $from, to: $to, amount: $amount, keyword: $keyword }";
+    return "TxFilter { sent: $sent, received: $received, trade: $trade, from: $from, to: $to, amount: $amount, keyword: $keyword }";
   }
 }
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 192389720..120425c2a 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -96,8 +96,12 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
       }
 
       final date = DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000);
-      if (date.millisecondsSinceEpoch > filter.to.millisecondsSinceEpoch ||
-          date.millisecondsSinceEpoch < filter.from.millisecondsSinceEpoch) {
+      if ((filter.to != null &&
+              date.millisecondsSinceEpoch >
+                  filter.to!.millisecondsSinceEpoch) ||
+          (filter.from != null &&
+              date.millisecondsSinceEpoch <
+                  filter.from!.millisecondsSinceEpoch)) {
         return false;
       }
 
@@ -125,13 +129,25 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
         .isNotEmpty;
 
     // check if address contains
-    contains |= tx.address.contains(keyword);
+    contains |= tx.address.toLowerCase().contains(keyword);
 
     // check if note contains
-    contains |= notes[tx.txid] != null && notes[tx.txid]!.contains(keyword);
+    contains |= notes[tx.txid] != null &&
+        notes[tx.txid]!.toLowerCase().contains(keyword);
 
     // check if txid contains
-    contains |= tx.txid.contains(keyword);
+    contains |= tx.txid.toLowerCase().contains(keyword);
+
+    // check if subType contains
+    contains |=
+        tx.subType.isNotEmpty && tx.subType.toLowerCase().contains(keyword);
+
+    // check if txType contains
+    contains |= tx.txType.toLowerCase().contains(keyword);
+
+    // check if date contains
+    contains |=
+        Format.extractDateFrom(tx.timestamp).toLowerCase().contains(keyword);
 
     return contains;
   }
@@ -311,7 +327,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
                               )
                             : STextStyles.field(context),
                         decoration: standardInputDecoration(
-                          "Search",
+                          "Search...",
                           searchFieldFocusNode,
                           context,
                           desktopMed: isDesktop,
@@ -393,6 +409,22 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
                 ],
               ),
             ),
+            if (isDesktop)
+              const SizedBox(
+                height: 8,
+              ),
+            if (isDesktop &&
+                ref.watch(transactionFilterProvider.state).state != null)
+              Padding(
+                padding: const EdgeInsets.symmetric(
+                  vertical: 8,
+                ),
+                child: Row(
+                  children: const [
+                    TransactionFilterOptionBar(),
+                  ],
+                ),
+              ),
             const SizedBox(
               height: 8,
             ),
@@ -463,6 +495,8 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
                                             Padding(
                                           padding: const EdgeInsets.all(4),
                                           child: DesktopTransactionCardRow(
+                                            key: Key(
+                                                "transactionCard_key_${month.item2[index].txid}"),
                                             transaction: month.item2[index],
                                             walletId: walletId,
                                           ),
@@ -506,6 +540,220 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
   }
 }
 
+class TransactionFilterOptionBar extends ConsumerStatefulWidget {
+  const TransactionFilterOptionBar({Key? key}) : super(key: key);
+
+  @override
+  ConsumerState<TransactionFilterOptionBar> createState() =>
+      _TransactionFilterOptionBarState();
+}
+
+class _TransactionFilterOptionBarState
+    extends ConsumerState<TransactionFilterOptionBar> {
+  final List<TransactionFilterOptionBarItem> items = [];
+  TransactionFilter? _filter;
+
+  @override
+  void initState() {
+    _filter = ref.read(transactionFilterProvider.state).state;
+
+    if (_filter != null) {
+      if (_filter!.sent) {
+        const label = "Sent";
+        final item = TransactionFilterOptionBarItem(
+          label: label,
+          onPressed: (s) {
+            items.removeWhere((e) => e.label == label);
+            if (items.isEmpty) {
+              ref.read(transactionFilterProvider.state).state = null;
+            } else {
+              ref.read(transactionFilterProvider.state).state =
+                  ref.read(transactionFilterProvider.state).state?.copyWith(
+                        sent: false,
+                      );
+              setState(() {});
+            }
+          },
+        );
+        items.add(item);
+      }
+      if (_filter!.received) {
+        const label = ("Received");
+        final item = TransactionFilterOptionBarItem(
+          label: label,
+          onPressed: (s) {
+            items.removeWhere((e) => e.label == label);
+            if (items.isEmpty) {
+              ref.read(transactionFilterProvider.state).state = null;
+            } else {
+              ref.read(transactionFilterProvider.state).state =
+                  ref.read(transactionFilterProvider.state).state?.copyWith(
+                        received: false,
+                      );
+              setState(() {});
+            }
+          },
+        );
+        items.add(item);
+      }
+
+      if (_filter!.to != null) {
+        final label = _filter!.from.toString();
+        final item = TransactionFilterOptionBarItem(
+          label: label,
+          onPressed: (s) {
+            items.removeWhere((e) => e.label == label);
+            if (items.isEmpty) {
+              ref.read(transactionFilterProvider.state).state = null;
+            } else {
+              ref.read(transactionFilterProvider.state).state =
+                  ref.read(transactionFilterProvider.state).state?.copyWith(
+                        to: null,
+                      );
+              setState(() {});
+            }
+          },
+        );
+        items.add(item);
+      }
+      if (_filter!.from != null) {
+        final label2 = _filter!.to.toString();
+        final item2 = TransactionFilterOptionBarItem(
+          label: label2,
+          onPressed: (s) {
+            items.removeWhere((e) => e.label == label2);
+            if (items.isEmpty) {
+              ref.read(transactionFilterProvider.state).state = null;
+            } else {
+              ref.read(transactionFilterProvider.state).state =
+                  ref.read(transactionFilterProvider.state).state?.copyWith(
+                        from: null,
+                      );
+              setState(() {});
+            }
+          },
+        );
+        items.add(item2);
+      }
+
+      if (_filter!.amount != null) {
+        final label = _filter!.amount!.toString();
+        final item = TransactionFilterOptionBarItem(
+          label: label,
+          onPressed: (s) {
+            items.removeWhere((e) => e.label == label);
+            if (items.isEmpty) {
+              ref.read(transactionFilterProvider.state).state = null;
+            } else {
+              ref.read(transactionFilterProvider.state).state =
+                  ref.read(transactionFilterProvider.state).state?.copyWith(
+                        amount: null,
+                      );
+              setState(() {});
+            }
+          },
+        );
+        items.add(item);
+      }
+      if (_filter!.keyword.isNotEmpty) {
+        final label = _filter!.keyword;
+        final item = TransactionFilterOptionBarItem(
+          label: label,
+          onPressed: (s) {
+            items.removeWhere((e) => e.label == label);
+            if (items.isEmpty) {
+              ref.read(transactionFilterProvider.state).state = null;
+            } else {
+              ref.read(transactionFilterProvider.state).state =
+                  ref.read(transactionFilterProvider.state).state?.copyWith(
+                        keyword: "",
+                      );
+              setState(() {});
+            }
+          },
+        );
+        items.add(item);
+      }
+    }
+
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return SizedBox(
+      height: 32,
+      child: ListView.separated(
+        primary: false,
+        scrollDirection: Axis.horizontal,
+        shrinkWrap: true,
+        itemCount: items.length,
+        separatorBuilder: (_, __) => const SizedBox(
+          width: 16,
+        ),
+        itemBuilder: (context, index) => items[index],
+      ),
+    );
+  }
+}
+
+class TransactionFilterOptionBarItem extends StatelessWidget {
+  const TransactionFilterOptionBarItem({
+    Key? key,
+    required this.label,
+    this.onPressed,
+  }) : super(key: key);
+
+  final String label;
+  final void Function(String)? onPressed;
+
+  @override
+  Widget build(BuildContext context) {
+    return GestureDetector(
+      onTap: () => onPressed?.call(label),
+      child: Container(
+        height: 32,
+        decoration: BoxDecoration(
+            color:
+                Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
+            borderRadius: BorderRadius.circular(1000)),
+        child: Padding(
+          padding: const EdgeInsets.symmetric(
+            horizontal: 14,
+          ),
+          child: Row(
+            mainAxisAlignment: MainAxisAlignment.center,
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              Center(
+                child: Padding(
+                  padding: const EdgeInsets.only(top: 2),
+                  child: Text(
+                    label,
+                    textAlign: TextAlign.center,
+                    style: STextStyles.labelExtraExtraSmall(context).copyWith(
+                      color:
+                          Theme.of(context).extension<StackColors>()!.textDark,
+                    ),
+                  ),
+                ),
+              ),
+              const SizedBox(
+                width: 10,
+              ),
+              XIcon(
+                width: 16,
+                height: 16,
+                color: Theme.of(context).extension<StackColors>()!.textDark,
+              ),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}
+
 class DesktopTransactionCardRow extends ConsumerStatefulWidget {
   const DesktopTransactionCardRow({
     Key? key,
diff --git a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
index 7d18d4428..abebb71e4 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
@@ -68,8 +68,11 @@ class _TransactionSearchViewState
       _selectedFromDate = filterState.from;
       _keywordTextEditingController.text = filterState.keyword;
 
-      _fromDateString = Format.formatDate(_selectedFromDate);
-      _toDateString = Format.formatDate(_selectedToDate);
+      _fromDateString = _selectedFromDate == null
+          ? ""
+          : Format.formatDate(_selectedFromDate!);
+      _toDateString =
+          _selectedToDate == null ? "" : Format.formatDate(_selectedToDate!);
 
       // TODO: Fix XMR (modify Format.funcs to take optional Coin parameter)
       // final amt = Format.satoshisToAmount(widget.coin == Coin.monero ? )
@@ -118,8 +121,8 @@ class _TransactionSearchViewState
     );
   }
 
-  var _selectedFromDate = DateTime(2007);
-  var _selectedToDate = DateTime.now();
+  DateTime? _selectedFromDate = DateTime(2007);
+  DateTime? _selectedToDate = DateTime.now();
 
   MaterialRoundedDatePickerStyle _buildDatePickerStyle() {
     return MaterialRoundedDatePickerStyle(
@@ -226,17 +229,22 @@ class _TransactionSearchViewState
                 _selectedFromDate = date;
 
                 // flag to adjust date so from date is always before to date
-                final flag = !_selectedFromDate.isBefore(_selectedToDate);
+                final flag = _selectedToDate != null &&
+                    !_selectedFromDate!.isBefore(_selectedToDate!);
                 if (flag) {
                   _selectedToDate = DateTime.fromMillisecondsSinceEpoch(
-                      _selectedFromDate.millisecondsSinceEpoch);
+                      _selectedFromDate!.millisecondsSinceEpoch);
                 }
 
                 setState(() {
                   if (flag) {
-                    _toDateString = Format.formatDate(_selectedToDate);
+                    _toDateString = _selectedToDate == null
+                        ? ""
+                        : Format.formatDate(_selectedToDate!);
                   }
-                  _fromDateString = Format.formatDate(_selectedFromDate);
+                  _fromDateString = _selectedFromDate == null
+                      ? ""
+                      : Format.formatDate(_selectedFromDate!);
                 });
               }
             },
@@ -333,17 +341,22 @@ class _TransactionSearchViewState
                 _selectedToDate = date;
 
                 // flag to adjust date so from date is always before to date
-                final flag = !_selectedToDate.isAfter(_selectedFromDate);
+                final flag = _selectedFromDate != null &&
+                    !_selectedToDate!.isAfter(_selectedFromDate!);
                 if (flag) {
                   _selectedFromDate = DateTime.fromMillisecondsSinceEpoch(
-                      _selectedToDate.millisecondsSinceEpoch);
+                      _selectedToDate!.millisecondsSinceEpoch);
                 }
 
                 setState(() {
                   if (flag) {
-                    _fromDateString = Format.formatDate(_selectedFromDate);
+                    _fromDateString = _selectedFromDate == null
+                        ? ""
+                        : Format.formatDate(_selectedFromDate!);
                   }
-                  _toDateString = Format.formatDate(_selectedToDate);
+                  _toDateString = _selectedToDate == null
+                      ? ""
+                      : Format.formatDate(_selectedToDate!);
                 });
               }
             },
@@ -975,6 +988,7 @@ class _TransactionSearchViewState
     final TransactionFilter filter = TransactionFilter(
       sent: _isActiveSentCheckbox,
       received: _isActiveReceivedCheckbox,
+      trade: _isActiveTradeCheckbox,
       from: _selectedFromDate,
       to: _selectedToDate,
       amount: amount,

From 300b1fa0018236a124837281f400d920c64c5424 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 28 Oct 2022 17:04:48 -0600
Subject: [PATCH 068/426] route update

---
 .../home/desktop_settings_view.dart           |   2 +-
 .../backup_and_restore_settings.dart          | 311 ++++++++++++++++++
 .../create_auto_backup.dart                   | 136 ++++++++
 .../enable_backup_dialog.dart                 |  87 +++++
 .../restore_backup_dialog.dart                |  93 ++++++
 .../home/settings_menu/nodes_settings.dart    |   5 +-
 lib/route_generator.dart                      |   2 +-
 7 files changed, 631 insertions(+), 5 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart

diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index 7aff94b66..719a37a3a 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
new file mode 100644
index 000000000..6ab82401b
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -0,0 +1,311 @@
+import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+import 'enable_backup_dialog.dart';
+
+class BackupRestoreSettings extends ConsumerStatefulWidget {
+  const BackupRestoreSettings({Key? key}) : super(key: key);
+
+  static const String routeName = "/settingsMenuBackupRestore";
+
+  @override
+  ConsumerState<BackupRestoreSettings> createState() =>
+      _BackupRestoreSettings();
+}
+
+class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return ListView(
+      shrinkWrap: true,
+      scrollDirection: Axis.vertical,
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.backupAuto,
+                  width: 48,
+                  height: 48,
+                ),
+                Center(
+                  child: Padding(
+                    padding: const EdgeInsets.all(10),
+                    child: RichText(
+                      textAlign: TextAlign.start,
+                      text: TextSpan(
+                        children: [
+                          TextSpan(
+                            text: "Auto Backup",
+                            style: STextStyles.desktopTextSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nAuto backup is a custom Stack Wallet feature that offers a convenient backup of your data."
+                                "To ensure maximum security, we recommend using a unique password that you haven't used anywhere "
+                                "else on the internet before. Your password is not stored.",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nFor more information, please see our website ",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                          TextSpan(
+                            text: "stackwallet.com",
+                            style: STextStyles.richLink(context)
+                                .copyWith(fontSize: 14),
+                            recognizer: TapGestureRecognizer()
+                              ..onTap = () {
+                                launchUrl(
+                                  Uri.parse("https://stackwallet.com/"),
+                                  mode: LaunchMode.externalApplication,
+                                );
+                              },
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: AutoBackupButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 25,
+        ),
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.backupAdd,
+                  width: 48,
+                  height: 48,
+                  alignment: Alignment.topLeft,
+                ),
+                Center(
+                  child: Padding(
+                    padding: const EdgeInsets.all(10),
+                    child: RichText(
+                      textAlign: TextAlign.start,
+                      text: TextSpan(
+                        children: [
+                          TextSpan(
+                            text: "Manual Backup",
+                            style: STextStyles.desktopTextSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nCreate manual backup to easily transfer your data between devices. "
+                                "You will create a backup file that can be later used in the Restore option. "
+                                "Use a strong password to encrypt your data.",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: ManualBackupButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 25,
+        ),
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.backupRestore,
+                  width: 48,
+                  height: 48,
+                  alignment: Alignment.topLeft,
+                ),
+                Center(
+                  child: Padding(
+                    padding: const EdgeInsets.all(10),
+                    child: RichText(
+                      textAlign: TextAlign.start,
+                      text: TextSpan(
+                        children: [
+                          TextSpan(
+                            text: "Restore Backup",
+                            style: STextStyles.desktopTextSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nUse your Stack Wallet backup file to restore your wallets, address book "
+                                "and wallet preferences.",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: RestoreBackupButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class AutoBackupButton extends ConsumerWidget {
+  const AutoBackupButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    Future<void> enableAutoBackup() async {
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: true,
+        builder: (context) {
+          return const EnableBackupDialog();
+        },
+      );
+    }
+
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {
+          enableAutoBackup();
+        },
+        child: Text(
+          "Enable auto backup",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
+
+class ManualBackupButton extends ConsumerWidget {
+  const ManualBackupButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {},
+        child: Text(
+          "Create manual backup",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
+
+class RestoreBackupButton extends ConsumerWidget {
+  const RestoreBackupButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    Future<void> restoreBackup() async {
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: true,
+        builder: (context) {
+          return const RestoreBackupDialog();
+        },
+      );
+    }
+
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {
+          restoreBackup();
+        },
+        child: Text(
+          "Restore",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
new file mode 100644
index 000000000..29be17228
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -0,0 +1,136 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+import '../../../../utilities/assets.dart';
+import '../../../../widgets/custom_buttons/app_bar_icon_button.dart';
+import '../../../../widgets/stack_text_field.dart';
+
+class CreateAutoBackup extends StatelessWidget {
+  // const CreateAutoBackup({Key? key, required this.chooseFileLocation})
+  //     : super(key: key);
+
+  late final TextEditingController fileLocationController;
+
+  late final FocusNode chooseFileLocation;
+
+  @override
+  void initState() {
+    fileLocationController = TextEditingController();
+    // passwordRepeatController = TextEditingController();
+
+    chooseFileLocation = FocusNode();
+    // passwordRepeatFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    fileLocationController.dispose();
+    // passwordRepeatController.dispose();
+
+    chooseFileLocation.dispose();
+    // passwordRepeatFocusNode.dispose();
+
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxHeight: 600,
+      maxWidth: 600,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.all(32),
+                child: Text(
+                  "Create auto backup",
+                  style: STextStyles.desktopH3(context),
+                  textAlign: TextAlign.center,
+                ),
+              ),
+              Padding(
+                padding: const EdgeInsets.all(20.0),
+                child: AppBarIconButton(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldDefaultBG,
+                  size: 40,
+                  icon: SvgPicture.asset(
+                    Assets.svg.x,
+                    color: Theme.of(context).extension<StackColors>()!.textDark,
+                    width: 22,
+                    height: 22,
+                  ),
+                  onPressed: () {
+                    int count = 0;
+                    Navigator.of(context).popUntil((_) => count++ >= 2);
+                  },
+                ),
+              ),
+            ],
+          ),
+          const SizedBox(
+            height: 30,
+          ),
+          Container(
+            alignment: Alignment.centerLeft,
+            padding: EdgeInsets.only(left: 32),
+            child: Text(
+              "Choose file location",
+              style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
+              ),
+              textAlign: TextAlign.left,
+            ),
+          ),
+          TextField(
+            key: const Key("backupChooseFileLocation"),
+            style: STextStyles.desktopTextMedium(context).copyWith(
+              height: 2,
+            ),
+            enableSuggestions: false,
+            autocorrect: false,
+            decoration: standardInputDecoration(
+                "Save to...", chooseFileLocation, context),
+          ),
+          const Spacer(),
+          Padding(
+            padding: const EdgeInsets.all(32),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    onPressed: () {
+                      int count = 0;
+                      Navigator.of(context).popUntil((_) => count++ >= 2);
+                    },
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Enable Auto Backup",
+                    onPressed: () {},
+                  ),
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
new file mode 100644
index 000000000..046d136a8
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
@@ -0,0 +1,87 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+class EnableBackupDialog extends StatelessWidget {
+  const EnableBackupDialog({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    Future<void> createAutoBackup() async {
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: true,
+        builder: (context) {
+          return CreateAutoBackup();
+        },
+      );
+    }
+
+    return DesktopDialog(
+      maxHeight: 300,
+      maxWidth: 570,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.all(32),
+                child: Text(
+                  "Enable Auto Backup",
+                  style: STextStyles.desktopH3(context),
+                  textAlign: TextAlign.center,
+                ),
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+          const SizedBox(
+            height: 30,
+          ),
+          Text(
+            "To enable Auto Backup, you need to create a backup file.",
+            style: STextStyles.desktopTextSmall(context).copyWith(
+              color: Theme.of(context).extension<StackColors>()!.textDark3,
+            ),
+            textAlign: TextAlign.center,
+          ),
+          const Spacer(),
+          Padding(
+            padding: const EdgeInsets.all(32),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    onPressed: () {
+                      int count = 0;
+                      Navigator.of(context).popUntil((_) => count++ >= 2);
+                    },
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Continue",
+                    onPressed: () {
+                      createAutoBackup();
+                    },
+                  ),
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart
new file mode 100644
index 000000000..07d49274a
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart
@@ -0,0 +1,93 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+class RestoreBackupDialog extends StatelessWidget {
+  const RestoreBackupDialog({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.start,
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.all(32),
+                child: Text(
+                  "Restoring Stack Wallet",
+                  style: STextStyles.desktopH3(context),
+                  textAlign: TextAlign.center,
+                ),
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+          const SizedBox(
+            height: 30,
+          ),
+          Padding(
+            padding: const EdgeInsets.only(
+              left: 32,
+              right: 32,
+            ),
+            child: Row(
+              children: [
+                Text(
+                  "Settings",
+                  style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.textDark3,
+                  ),
+                  textAlign: TextAlign.left,
+                ),
+              ],
+            ),
+          ),
+          // RoundedWhiteContainer(
+          //   child: Column(
+          //     crossAxisAlignment: CrossAxisAlignment.start,
+          //     children: [
+          //       Row(),
+          //     ],
+          //   ),
+          // ),
+          const Spacer(),
+          Padding(
+            padding: const EdgeInsets.all(32),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    onPressed: () {
+                      Navigator.of(context).pop();
+                    },
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Continue",
+                    onPressed: () {
+                      // Navigator.of(context).pop();
+                      // onConfirm.call();
+                    },
+                  ),
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index f354927c4..bb60061d8 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -2,16 +2,15 @@ import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
 import 'package:stackwallet/providers/global/node_service_provider.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import '../../../pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
-import '../../../utilities/constants.dart';
-
 class NodesSettings extends ConsumerStatefulWidget {
   const NodesSettings({Key? key}) : super(key: key);
 
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index c37e0da5c..202edd972 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -89,7 +89,7 @@ import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_v
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';

From 234794e4ca003e9f93e3fb7139b6e327099cf2be Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 28 Oct 2022 17:07:13 -0600
Subject: [PATCH 069/426] WIP: security_settings and dialog popups

---
 .../backup_and_restore_settings.dart          | 282 ------------------
 .../settings_menu/enable_backup_dialog.dart   |  73 -----
 .../home/settings_menu/security_settings.dart |  44 +--
 3 files changed, 23 insertions(+), 376 deletions(-)
 delete mode 100644 lib/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart
 delete mode 100644 lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart
deleted file mode 100644
index 04c23ee83..000000000
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore_settings.dart
+++ /dev/null
@@ -1,282 +0,0 @@
-import 'package:flutter/gestures.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_svg/flutter_svg.dart';
-import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
-import 'package:stackwallet/widgets/rounded_white_container.dart';
-import 'package:url_launcher/url_launcher.dart';
-
-class BackupRestoreSettings extends ConsumerStatefulWidget {
-  const BackupRestoreSettings({Key? key}) : super(key: key);
-
-  static const String routeName = "/settingsMenuBackupRestore";
-
-  @override
-  ConsumerState<BackupRestoreSettings> createState() =>
-      _BackupRestoreSettings();
-}
-
-class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
-  @override
-  Widget build(BuildContext context) {
-    debugPrint("BUILD: $runtimeType");
-    return ListView(
-      shrinkWrap: true,
-      scrollDirection: Axis.vertical,
-      children: [
-        Padding(
-          padding: const EdgeInsets.only(
-            right: 30,
-          ),
-          child: RoundedWhiteContainer(
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                SvgPicture.asset(
-                  Assets.svg.backupAuto,
-                  width: 48,
-                  height: 48,
-                ),
-                Center(
-                  child: Padding(
-                    padding: const EdgeInsets.all(10),
-                    child: RichText(
-                      textAlign: TextAlign.start,
-                      text: TextSpan(
-                        children: [
-                          TextSpan(
-                            text: "Auto Backup",
-                            style: STextStyles.desktopTextSmall(context),
-                          ),
-                          TextSpan(
-                            text:
-                                "\n\nAuto backup is a custom Stack Wallet feature that offers a convenient backup of your data."
-                                "To ensure maximum security, we recommend using a unique password that you haven't used anywhere "
-                                "else on the internet before. Your password is not stored.",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
-                          ),
-                          TextSpan(
-                            text:
-                                "\n\nFor more information, please see our website ",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
-                          ),
-                          TextSpan(
-                            text: "stackwallet.com",
-                            style: STextStyles.richLink(context)
-                                .copyWith(fontSize: 14),
-                            recognizer: TapGestureRecognizer()
-                              ..onTap = () {
-                                launchUrl(
-                                  Uri.parse("https://stackwallet.com/"),
-                                  mode: LaunchMode.externalApplication,
-                                );
-                              },
-                          ),
-                        ],
-                      ),
-                    ),
-                  ),
-                ),
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
-                    Padding(
-                      padding: EdgeInsets.all(
-                        10,
-                      ),
-                      child: AutoBackupButton(),
-                    ),
-                  ],
-                ),
-              ],
-            ),
-          ),
-        ),
-        const SizedBox(
-          height: 25,
-        ),
-        Padding(
-          padding: const EdgeInsets.only(
-            right: 30,
-          ),
-          child: RoundedWhiteContainer(
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                SvgPicture.asset(
-                  Assets.svg.backupAdd,
-                  width: 48,
-                  height: 48,
-                  alignment: Alignment.topLeft,
-                ),
-                Center(
-                  child: Padding(
-                    padding: const EdgeInsets.all(10),
-                    child: RichText(
-                      textAlign: TextAlign.start,
-                      text: TextSpan(
-                        children: [
-                          TextSpan(
-                            text: "Manual Backup",
-                            style: STextStyles.desktopTextSmall(context),
-                          ),
-                          TextSpan(
-                            text:
-                                "\n\nCreate manual backup to easily transfer your data between devices. "
-                                "You will create a backup file that can be later used in the Restore option. "
-                                "Use a strong password to encrypt your data.",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
-                          ),
-                        ],
-                      ),
-                    ),
-                  ),
-                ),
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
-                    Padding(
-                      padding: EdgeInsets.all(
-                        10,
-                      ),
-                      child: ManualBackupButton(),
-                    ),
-                  ],
-                ),
-              ],
-            ),
-          ),
-        ),
-        const SizedBox(
-          height: 25,
-        ),
-        Padding(
-          padding: const EdgeInsets.only(
-            right: 30,
-          ),
-          child: RoundedWhiteContainer(
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                SvgPicture.asset(
-                  Assets.svg.backupRestore,
-                  width: 48,
-                  height: 48,
-                  alignment: Alignment.topLeft,
-                ),
-                Center(
-                  child: Padding(
-                    padding: const EdgeInsets.all(10),
-                    child: RichText(
-                      textAlign: TextAlign.start,
-                      text: TextSpan(
-                        children: [
-                          TextSpan(
-                            text: "Restore Backup",
-                            style: STextStyles.desktopTextSmall(context),
-                          ),
-                          TextSpan(
-                            text:
-                                "\n\nUse your Stack Wallet backup file to restore your wallets, address book "
-                                "and wallet preferences.",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
-                          ),
-                        ],
-                      ),
-                    ),
-                  ),
-                ),
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
-                    Padding(
-                      padding: EdgeInsets.all(
-                        10,
-                      ),
-                      child: ManualBackupButton(),
-                    ),
-                  ],
-                ),
-              ],
-            ),
-          ),
-        ),
-      ],
-    );
-  }
-}
-
-class AutoBackupButton extends ConsumerWidget {
-  const AutoBackupButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
-        child: Text(
-          "Enable auto backup",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
-
-class ManualBackupButton extends ConsumerWidget {
-  const ManualBackupButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
-        child: Text(
-          "Create manual backup",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
-
-class RestoreBackupButton extends ConsumerWidget {
-  const RestoreBackupButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
-        child: Text(
-          "Restore backup",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
diff --git a/lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart
deleted file mode 100644
index 4925177c3..000000000
--- a/lib/pages_desktop_specific/home/settings_menu/enable_backup_dialog.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
-import 'package:stackwallet/widgets/desktop/primary_button.dart';
-import 'package:stackwallet/widgets/desktop/secondary_button.dart';
-
-class EnableBackupDialog extends StatelessWidget {
-  const EnableBackupDialog({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return DesktopDialog(
-      child: Column(
-        children: [
-          Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            children: [
-              Padding(
-                padding: const EdgeInsets.all(32),
-                child: Text(
-                  "Enable Auto Backup",
-                  style: STextStyles.desktopH3(context),
-                  textAlign: TextAlign.center,
-                ),
-              ),
-              const DesktopDialogCloseButton(),
-            ],
-          ),
-          const SizedBox(
-            height: 30,
-          ),
-          Text(
-            "To enable Auto Backup, you need to create a backup file.",
-            style: STextStyles.desktopTextSmall(context).copyWith(
-              color: Theme.of(context).extension<StackColors>()!.textDark3,
-            ),
-            textAlign: TextAlign.center,
-          ),
-          const Spacer(),
-          Padding(
-            padding: const EdgeInsets.all(32),
-            child: Row(
-              children: [
-                Expanded(
-                  child: SecondaryButton(
-                    label: "Cancel",
-                    onPressed: () {
-                      Navigator.of(context).pop();
-                    },
-                  ),
-                ),
-                const SizedBox(
-                  width: 16,
-                ),
-                Expanded(
-                  child: PrimaryButton(
-                    label: "Continue",
-                    onPressed: () {
-                      // Navigator.of(context).pop();
-                      // onConfirm.call();
-                    },
-                  ),
-                )
-              ],
-            ),
-          ),
-        ],
-      ),
-    );
-  }
-}
diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index 7c36be8cd..cdcaed49a 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -2,13 +2,12 @@ import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import '../../../utilities/theme/stack_colors.dart';
-import 'enable_backup_dialog.dart';
-
 class SecuritySettings extends ConsumerStatefulWidget {
   const SecuritySettings({Key? key}) : super(key: key);
 
@@ -104,23 +103,6 @@ class NewPasswordButton extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    Future<void> enableAutoBackup() async {
-      // wait for keyboard to disappear
-      FocusScope.of(context).unfocus();
-      await Future<void>.delayed(
-        const Duration(milliseconds: 100),
-      );
-
-      await showDialog<dynamic>(
-        context: context,
-        useSafeArea: false,
-        barrierDismissible: true,
-        builder: (context) {
-          return EnableBackupDialog();
-        },
-      );
-    }
-
     return SizedBox(
       width: 200,
       height: 48,
@@ -129,7 +111,27 @@ class NewPasswordButton extends ConsumerWidget {
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {
-          enableAutoBackup();
+          // Expandable(
+          //   header: Row(
+          //     mainAxisAlignment: MainAxisAlignment.start,
+          //     children: [
+          //       NewPasswordButton(),
+          //     ],
+          //   ),
+          //   body: Column(
+          //     mainAxisAlignment: MainAxisAlignment.start,
+          //     children: [
+          //       Text(
+          //         "Current Password",
+          //         style: STextStyles.desktopTextExtraSmall(context).copyWith(
+          //           color:
+          //               Theme.of(context).extension<StackColors>()!.textDark3,
+          //         ),
+          //         textAlign: TextAlign.left,
+          //       ),
+          //     ],
+          //   ),
+          // );
         },
         child: Text(
           "Set up new password",

From 5b2d9ce141910e0093a3b19c2c0c77a40b173e1b Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 29 Oct 2022 09:14:59 -0600
Subject: [PATCH 070/426] Coin enum clean up and bug fixes

---
 .../add_wallet_view/add_wallet_view.dart        |  1 -
 .../sub_widgets/mobile_coin_list.dart           |  2 --
 .../sub_widgets/searchable_coin_list.dart       |  3 ++-
 lib/utilities/enums/coin_enum.dart              | 17 +++++++++++------
 4 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
index df5c44d18..e964610ae 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
@@ -206,7 +206,6 @@ class _AddWalletViewState extends State<AddWalletView> {
                 Expanded(
                   child: MobileCoinList(
                     coins: coins,
-                    isDesktop: false,
                   ),
                 ),
                 const SizedBox(
diff --git a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/mobile_coin_list.dart b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/mobile_coin_list.dart
index 1f36f3b65..fd950963c 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/mobile_coin_list.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/mobile_coin_list.dart
@@ -8,11 +8,9 @@ class MobileCoinList extends StatelessWidget {
   const MobileCoinList({
     Key? key,
     required this.coins,
-    required this.isDesktop,
   }) : super(key: key);
 
   final List<Coin> coins;
-  final bool isDesktop;
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart
index fb443b915..d89d42bbf 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart
@@ -26,7 +26,8 @@ class SearchableCoinList extends ConsumerWidget {
           e.name.toLowerCase().contains(lowercaseTerm));
     }
     if (!showTestNetCoins) {
-      _coins.removeWhere((e) => e.name.endsWith("TestNet"));
+      _coins.removeWhere(
+          (e) => e.name.endsWith("TestNet") || e == Coin.bitcoincashTestnet);
     }
     // remove firo testnet regardless
     _coins.remove(Coin.firoTestNet);
diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart
index 86054979a..95294c8aa 100644
--- a/lib/utilities/enums/coin_enum.dart
+++ b/lib/utilities/enums/coin_enum.dart
@@ -1,6 +1,4 @@
 import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as btc;
-import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart'
-    as ltc;
 import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'
     as bch;
 import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'
@@ -8,6 +6,8 @@ import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'
 import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'
     as epic;
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as firo;
+import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart'
+    as ltc;
 import 'package:stackwallet/services/coins/monero/monero_wallet.dart' as xmr;
 import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'
     as nmc;
@@ -19,12 +19,12 @@ enum Coin {
   dogecoin,
   epicCash,
   firo,
+  litecoin,
   monero,
-  wownero,
   namecoin,
+  wownero,
 
   ///
-  litecoin,
 
   ///
   ///
@@ -37,7 +37,7 @@ enum Coin {
 }
 
 // remove firotestnet for now
-const int kTestNetCoinCount = 3;
+const int kTestNetCoinCount = 4;
 
 extension CoinExt on Coin {
   String get prettyName {
@@ -268,7 +268,10 @@ Coin coinFromPrettyName(String name) {
 
     default:
       throw ArgumentError.value(
-          name, "name", "No Coin enum value with that prettyName");
+        name,
+        "name",
+        "No Coin enum value with that prettyName",
+      );
   }
 }
 
@@ -290,6 +293,8 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
       return Coin.monero;
     case "nmc":
       return Coin.namecoin;
+    case "tltc":
+      return Coin.litecoinTestNet;
     case "tbtc":
       return Coin.bitcoinTestNet;
     case "tbch":

From f7dd7b01aa43e4900796b295632afe99e6f0fc43 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 29 Oct 2022 09:14:59 -0600
Subject: [PATCH 071/426] Coin enum clean up and bug fixes

---
 .../add_wallet_view/add_wallet_view.dart        |  1 -
 .../sub_widgets/mobile_coin_list.dart           |  2 --
 .../sub_widgets/searchable_coin_list.dart       |  3 ++-
 lib/utilities/enums/coin_enum.dart              | 17 +++++++++++------
 4 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
index df5c44d18..e964610ae 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
@@ -206,7 +206,6 @@ class _AddWalletViewState extends State<AddWalletView> {
                 Expanded(
                   child: MobileCoinList(
                     coins: coins,
-                    isDesktop: false,
                   ),
                 ),
                 const SizedBox(
diff --git a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/mobile_coin_list.dart b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/mobile_coin_list.dart
index 1f36f3b65..fd950963c 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/mobile_coin_list.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/mobile_coin_list.dart
@@ -8,11 +8,9 @@ class MobileCoinList extends StatelessWidget {
   const MobileCoinList({
     Key? key,
     required this.coins,
-    required this.isDesktop,
   }) : super(key: key);
 
   final List<Coin> coins;
-  final bool isDesktop;
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart
index fb443b915..d89d42bbf 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart
@@ -26,7 +26,8 @@ class SearchableCoinList extends ConsumerWidget {
           e.name.toLowerCase().contains(lowercaseTerm));
     }
     if (!showTestNetCoins) {
-      _coins.removeWhere((e) => e.name.endsWith("TestNet"));
+      _coins.removeWhere(
+          (e) => e.name.endsWith("TestNet") || e == Coin.bitcoincashTestnet);
     }
     // remove firo testnet regardless
     _coins.remove(Coin.firoTestNet);
diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart
index 86054979a..95294c8aa 100644
--- a/lib/utilities/enums/coin_enum.dart
+++ b/lib/utilities/enums/coin_enum.dart
@@ -1,6 +1,4 @@
 import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as btc;
-import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart'
-    as ltc;
 import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'
     as bch;
 import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'
@@ -8,6 +6,8 @@ import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'
 import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart'
     as epic;
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as firo;
+import 'package:stackwallet/services/coins/litecoin/litecoin_wallet.dart'
+    as ltc;
 import 'package:stackwallet/services/coins/monero/monero_wallet.dart' as xmr;
 import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'
     as nmc;
@@ -19,12 +19,12 @@ enum Coin {
   dogecoin,
   epicCash,
   firo,
+  litecoin,
   monero,
-  wownero,
   namecoin,
+  wownero,
 
   ///
-  litecoin,
 
   ///
   ///
@@ -37,7 +37,7 @@ enum Coin {
 }
 
 // remove firotestnet for now
-const int kTestNetCoinCount = 3;
+const int kTestNetCoinCount = 4;
 
 extension CoinExt on Coin {
   String get prettyName {
@@ -268,7 +268,10 @@ Coin coinFromPrettyName(String name) {
 
     default:
       throw ArgumentError.value(
-          name, "name", "No Coin enum value with that prettyName");
+        name,
+        "name",
+        "No Coin enum value with that prettyName",
+      );
   }
 }
 
@@ -290,6 +293,8 @@ Coin coinFromTickerCaseInsensitive(String ticker) {
       return Coin.monero;
     case "nmc":
       return Coin.namecoin;
+    case "tltc":
+      return Coin.litecoinTestNet;
     case "tbtc":
       return Coin.bitcoinTestNet;
     case "tbch":

From 1f6338892efe71efb050712889ed0cf6e33d0909 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 29 Oct 2022 09:30:39 -0600
Subject: [PATCH 072/426] desktop favorite card navigation fix

---
 .../sub_widgets/favorite_card.dart            | 23 +++++++++++++------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/lib/pages/wallets_view/sub_widgets/favorite_card.dart b/lib/pages/wallets_view/sub_widgets/favorite_card.dart
index 924e904f3..8ce8add17 100644
--- a/lib/pages/wallets_view/sub_widgets/favorite_card.dart
+++ b/lib/pages/wallets_view/sub_widgets/favorite_card.dart
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -11,6 +12,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
 import 'package:tuple/tuple.dart';
 
 class FavoriteCard extends ConsumerStatefulWidget {
@@ -54,13 +56,20 @@ class _FavoriteCardState extends ConsumerState<FavoriteCard> {
 
     return GestureDetector(
       onTap: () {
-        Navigator.of(context).pushNamed(
-          WalletView.routeName,
-          arguments: Tuple2(
-            walletId,
-            managerProvider,
-          ),
-        );
+        if (Util.isDesktop) {
+          Navigator.of(context).pushNamed(
+            DesktopWalletView.routeName,
+            arguments: walletId,
+          );
+        } else {
+          Navigator.of(context).pushNamed(
+            WalletView.routeName,
+            arguments: Tuple2(
+              walletId,
+              managerProvider,
+            ),
+          );
+        }
       },
       child: SizedBox(
         width: widget.width,

From 5fd47de9a2473b0d682c3bcfd2bf4cc29c63ddd0 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 29 Oct 2022 13:35:03 -0600
Subject: [PATCH 073/426] desktop tx details + edit note ui

---
 .../all_transactions_view.dart                |   34 +-
 .../transaction_views/edit_note_view.dart     |  272 ++-
 .../transaction_details_view.dart             | 1474 +++++++++++------
 lib/widgets/icon_widgets/copy_icon.dart       |   27 +
 lib/widgets/icon_widgets/pencil_icon.dart     |   27 +
 lib/widgets/transaction_card.dart             |   34 +-
 pubspec.lock                                  |   43 +-
 7 files changed, 1302 insertions(+), 609 deletions(-)
 create mode 100644 lib/widgets/icon_widgets/copy_icon.dart
 create mode 100644 lib/widgets/icon_widgets/pencil_icon.dart

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 120425c2a..8604ae721 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -23,6 +23,7 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
@@ -865,16 +866,31 @@ class _DesktopTransactionCardRowState
             );
             return;
           }
-          unawaited(
-            Navigator.of(context).pushNamed(
-              TransactionDetailsView.routeName,
-              arguments: Tuple3(
-                _transaction,
-                coin,
-                walletId,
+          if (Util.isDesktop) {
+            await showDialog<void>(
+              context: context,
+              builder: (context) => DesktopDialog(
+                maxHeight: MediaQuery.of(context).size.height - 64,
+                maxWidth: 580,
+                child: TransactionDetailsView(
+                  transaction: _transaction,
+                  coin: coin,
+                  walletId: walletId,
+                ),
               ),
-            ),
-          );
+            );
+          } else {
+            unawaited(
+              Navigator.of(context).pushNamed(
+                TransactionDetailsView.routeName,
+                arguments: Tuple3(
+                  _transaction,
+                  coin,
+                  walletId,
+                ),
+              ),
+            );
+          }
         },
         child: Padding(
           padding: const EdgeInsets.symmetric(
diff --git a/lib/pages/wallet_view/transaction_views/edit_note_view.dart b/lib/pages/wallet_view/transaction_views/edit_note_view.dart
index b811dc62d..4baaaffc9 100644
--- a/lib/pages/wallet_view/transaction_views/edit_note_view.dart
+++ b/lib/pages/wallet_view/transaction_views/edit_note_view.dart
@@ -4,13 +4,14 @@ import 'package:stackwallet/providers/providers.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/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';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class EditNoteView extends ConsumerStatefulWidget {
   const EditNoteView({
     Key? key,
@@ -33,8 +34,11 @@ class _EditNoteViewState extends ConsumerState<EditNoteView> {
   late final TextEditingController _noteController;
   final noteFieldFocusNode = FocusNode();
 
+  late final bool isDesktop;
+
   @override
   void initState() {
+    isDesktop = Util.isDesktop;
     _noteController = TextEditingController();
     _noteController.text = widget.note;
     super.initState();
@@ -50,29 +54,178 @@ class _EditNoteViewState extends ConsumerState<EditNoteView> {
   @override
   Widget build(BuildContext context) {
     return Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: 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 note",
-            style: STextStyles.navBarTitle(context),
-          ),
+      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 note",
+                style: STextStyles.navBarTitle(context),
+              ),
+            ),
+      body: MobileEditNoteScaffold(
+        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 note",
+                      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: _noteController,
+                  style: isDesktop
+                      ? STextStyles.desktopTextExtraSmall(context).copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textFieldActiveText,
+                          height: 1.8,
+                        )
+                      : STextStyles.field(context),
+                  focusNode: noteFieldFocusNode,
+                  decoration: standardInputDecoration(
+                    "Note",
+                    noteFieldFocusNode,
+                    context,
+                    desktopMed: isDesktop,
+                  ).copyWith(
+                    contentPadding: isDesktop
+                        ? const EdgeInsets.only(
+                            left: 16,
+                            top: 11,
+                            bottom: 12,
+                            right: 5,
+                          )
+                        : null,
+                    suffixIcon: _noteController.text.isNotEmpty
+                        ? Padding(
+                            padding: const EdgeInsets.only(right: 0),
+                            child: UnconstrainedBox(
+                              child: Row(
+                                children: [
+                                  TextFieldIconButton(
+                                    child: const XIcon(),
+                                    onTap: () async {
+                                      setState(() {
+                                        _noteController.text = "";
+                                      });
+                                    },
+                                  ),
+                                ],
+                              ),
+                            ),
+                          )
+                        : null,
+                  ),
+                ),
+              ),
+            ),
+            // if (!isDesktop)
+            const Spacer(),
+            if (isDesktop)
+              Padding(
+                padding: const EdgeInsets.all(32),
+                child: PrimaryButton(
+                  label: "Save",
+                  onPressed: () async {
+                    await ref
+                        .read(
+                            notesServiceChangeNotifierProvider(widget.walletId))
+                        .editOrAddNote(
+                          txid: widget.txid,
+                          note: _noteController.text,
+                        );
+                    if (mounted) {
+                      Navigator.of(context).pop();
+                    }
+                  },
+                ),
+              ),
+            if (!isDesktop)
+              TextButton(
+                onPressed: () async {
+                  await ref
+                      .read(notesServiceChangeNotifierProvider(widget.walletId))
+                      .editOrAddNote(
+                        txid: widget.txid,
+                        note: _noteController.text,
+                      );
+                  if (mounted) {
+                    Navigator.of(context).pop();
+                  }
+                },
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getPrimaryEnabledButtonColor(context),
+                child: Text(
+                  "Save",
+                  style: STextStyles.button(context),
+                ),
+              )
+          ],
         ),
-        body: Padding(
-          padding: const EdgeInsets.all(12),
-          child: LayoutBuilder(builder: (context, constraints) {
+      ),
+    );
+  }
+}
+
+class MobileEditNoteScaffold extends StatelessWidget {
+  const MobileEditNoteScaffold({
+    Key? key,
+    required this.child,
+  }) : super(key: key);
+
+  final Widget child;
+
+  @override
+  Widget build(BuildContext context) {
+    if (Util.isDesktop) {
+      return child;
+    } else {
+      return Padding(
+        padding: const EdgeInsets.all(12),
+        child: LayoutBuilder(
+          builder: (context, constraints) {
             return SingleChildScrollView(
               child: ConstrainedBox(
                 constraints: BoxConstraints(
@@ -81,75 +234,14 @@ class _EditNoteViewState extends ConsumerState<EditNoteView> {
                 child: IntrinsicHeight(
                   child: Padding(
                     padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            controller: _noteController,
-                            style: STextStyles.field(context),
-                            focusNode: noteFieldFocusNode,
-                            decoration: standardInputDecoration(
-                              "Note",
-                              noteFieldFocusNode,
-                              context,
-                            ).copyWith(
-                              suffixIcon: _noteController.text.isNotEmpty
-                                  ? Padding(
-                                      padding: const EdgeInsets.only(right: 0),
-                                      child: UnconstrainedBox(
-                                        child: Row(
-                                          children: [
-                                            TextFieldIconButton(
-                                              child: const XIcon(),
-                                              onTap: () async {
-                                                setState(() {
-                                                  _noteController.text = "";
-                                                });
-                                              },
-                                            ),
-                                          ],
-                                        ),
-                                      ),
-                                    )
-                                  : null,
-                            ),
-                          ),
-                        ),
-                        const Spacer(),
-                        TextButton(
-                          onPressed: () async {
-                            await ref
-                                .read(notesServiceChangeNotifierProvider(
-                                    widget.walletId))
-                                .editOrAddNote(
-                                  txid: widget.txid,
-                                  note: _noteController.text,
-                                );
-                            if (mounted) {
-                              Navigator.of(context).pop();
-                            }
-                          },
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context),
-                          child: Text(
-                            "Save",
-                            style: STextStyles.button(context),
-                          ),
-                        )
-                      ],
-                    ),
+                    child: child,
                   ),
                 ),
               ),
             );
-          }),
-        ));
+          },
+        ),
+      );
+    }
   }
 }
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 8d7aac85f..d7f06095d 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -2,6 +2,7 @@ import 'dart:async';
 
 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/models.dart';
@@ -23,8 +24,13 @@ import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/icon_widgets/copy_icon.dart';
+import 'package:stackwallet/widgets/icon_widgets/pencil_icon.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:tuple/tuple.dart';
@@ -51,6 +57,7 @@ class TransactionDetailsView extends ConsumerStatefulWidget {
 
 class _TransactionDetailsViewState
     extends ConsumerState<TransactionDetailsView> {
+  late final bool isDesktop;
   late Transaction _transaction;
   late final String walletId;
 
@@ -63,6 +70,7 @@ class _TransactionDetailsViewState
 
   @override
   void initState() {
+    isDesktop = Util.isDesktop;
     _transaction = widget.transaction;
     walletId = widget.walletId;
 
@@ -74,7 +82,7 @@ class _TransactionDetailsViewState
         _transaction.subType == "mint") {
       amountPrefix = "";
     } else {
-      amountPrefix = _transaction.txType.toLowerCase() == "sent" ? "- " : "+ ";
+      amountPrefix = _transaction.txType.toLowerCase() == "sent" ? "-" : "+";
     }
 
     // if (coin == Coin.firo || coin == Coin.firoTestNet) {
@@ -205,267 +213,524 @@ class _TransactionDetailsViewState
   @override
   Widget build(BuildContext context) {
     return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: 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(Duration(milliseconds: 50));
-            // }
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Transaction details",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
+      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(Duration(milliseconds: 50));
+                  // }
+                  Navigator.of(context).pop();
+                },
+              ),
+              title: Text(
+                "Transaction details",
+                style: STextStyles.navBarTitle(context),
+              ),
+            ),
       body: Padding(
-        padding: const EdgeInsets.all(12),
-        child: SingleChildScrollView(
-          child: Padding(
-            padding: const EdgeInsets.all(4),
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.stretch,
-              children: [
-                RoundedWhiteContainer(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Column(
-                        crossAxisAlignment: CrossAxisAlignment.start,
-                        children: [
-                          SelectableText(
-                            "$amountPrefix${Format.localizedStringAsFixed(
-                              value: coin == Coin.monero
-                                  ? (amount / 10000.toDecimal()).toDecimal()
-                                  : coin == Coin.wownero
-                                      ? (amount / 1000.toDecimal()).toDecimal()
-                                      : amount,
-                              locale: ref.watch(
-                                localeServiceChangeNotifierProvider
-                                    .select((value) => value.locale),
-                              ),
-                              decimalPlaces: Constants.decimalPlaces,
-                            )} ${coin.ticker}",
-                            style: STextStyles.titleBold12(context),
-                          ),
-                          const SizedBox(
-                            height: 2,
-                          ),
-                          if (ref.watch(prefsChangeNotifierProvider
-                              .select((value) => value.externalCalls)))
-                            SelectableText(
-                              "${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch(
-                                    localeServiceChangeNotifierProvider
-                                        .select((value) => value.locale),
-                                  ), decimalPlaces: 2)} ${ref.watch(
-                                prefsChangeNotifierProvider.select(
-                                  (value) => value.currency,
-                                ),
-                              )}",
-                              style: STextStyles.itemSubtitle(context),
-                            ),
-                        ],
-                      ),
-                      TxIcon(
-                        transaction: _transaction,
-                      ),
-                    ],
+        padding: isDesktop
+            ? const EdgeInsets.only(left: 32)
+            : const EdgeInsets.all(12),
+        child: Column(
+          children: [
+            if (isDesktop)
+              Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Text(
+                    "Transaction details",
+                    style: STextStyles.desktopH3(context),
                   ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "Status",
-                        style: STextStyles.itemSubtitle(context),
-                      ),
-                      // Flexible(
-                      //   child: FittedBox(
-                      //     fit: BoxFit.scaleDown,
-                      //     child:
-                      SelectableText(
-                        _transaction.isCancelled
-                            ? "Cancelled"
-                            : whatIsIt(_transaction.txType),
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
-                      //   ),
-                      // ),
-                    ],
-                  ),
-                ),
-                if (!((coin == Coin.monero || coin == Coin.wownero) &&
-                        _transaction.txType.toLowerCase() == "sent") &&
-                    !((coin == Coin.firo || coin == Coin.firoTestNet) &&
-                        _transaction.subType == "mint"))
-                  const SizedBox(
-                    height: 12,
-                  ),
-                if (!((coin == Coin.monero || coin == Coin.wownero) &&
-                        _transaction.txType.toLowerCase() == "sent") &&
-                    !((coin == Coin.firo || coin == Coin.firoTestNet) &&
-                        _transaction.subType == "mint"))
-                  RoundedWhiteContainer(
+                  const DesktopDialogCloseButton(),
+                ],
+              ),
+            Padding(
+              padding: isDesktop
+                  ? const EdgeInsets.only(
+                      right: 32,
+                      bottom: 32,
+                    )
+                  : const EdgeInsets.all(0),
+              child: RoundedWhiteContainer(
+                borderColor: isDesktop
+                    ? Theme.of(context).extension<StackColors>()!.background
+                    : null,
+                padding: const EdgeInsets.all(0),
+                child: SingleChildScrollView(
+                  child: Padding(
+                    padding: isDesktop
+                        ? const EdgeInsets.all(0)
+                        : const EdgeInsets.all(4),
                     child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
                       children: [
-                        Text(
-                          _transaction.txType.toLowerCase() == "sent"
-                              ? "Sent to"
-                              : "Received on",
-                          style: STextStyles.itemSubtitle(context),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        _transaction.txType.toLowerCase() == "received"
-                            ? FutureBuilder(
-                                future:
-                                    fetchContactNameFor(_transaction.address),
-                                builder: (builderContext,
-                                    AsyncSnapshot<String> snapshot) {
-                                  String addressOrContactName =
-                                      _transaction.address;
-                                  if (snapshot.connectionState ==
-                                          ConnectionState.done &&
-                                      snapshot.hasData) {
-                                    addressOrContactName = snapshot.data!;
-                                  }
-                                  return SelectableText(
-                                    addressOrContactName,
-                                    style: STextStyles.itemSubtitle12(context),
-                                  );
-                                },
-                              )
-                            : SelectableText(
-                                _transaction.address,
-                                style: STextStyles.itemSubtitle12(context),
+                        RoundedWhiteContainer(
+                          padding: isDesktop
+                              ? const EdgeInsets.all(0)
+                              : const EdgeInsets.all(12),
+                          child: Container(
+                            decoration: isDesktop
+                                ? BoxDecoration(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .background,
+                                    borderRadius: BorderRadius.vertical(
+                                      top: Radius.circular(
+                                        Constants.size.circularBorderRadius,
+                                      ),
+                                    ),
+                                  )
+                                : null,
+                            child: Padding(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(12)
+                                  : const EdgeInsets.all(0),
+                              child: Row(
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
+                                children: [
+                                  if (isDesktop)
+                                    Row(
+                                      children: [
+                                        TxIcon(
+                                          transaction: _transaction,
+                                        ),
+                                        const SizedBox(
+                                          width: 16,
+                                        ),
+                                        SelectableText(
+                                          _transaction.isCancelled
+                                              ? "Cancelled"
+                                              : whatIsIt(_transaction.txType),
+                                          style: STextStyles.desktopTextMedium(
+                                              context),
+                                        ),
+                                      ],
+                                    ),
+                                  Column(
+                                    crossAxisAlignment: isDesktop
+                                        ? CrossAxisAlignment.end
+                                        : CrossAxisAlignment.start,
+                                    children: [
+                                      SelectableText(
+                                        "$amountPrefix${Format.localizedStringAsFixed(
+                                          value: coin == Coin.monero
+                                              ? (amount / 10000.toDecimal())
+                                                  .toDecimal()
+                                              : coin == Coin.wownero
+                                                  ? (amount / 1000.toDecimal())
+                                                      .toDecimal()
+                                                  : amount,
+                                          locale: ref.watch(
+                                            localeServiceChangeNotifierProvider
+                                                .select(
+                                                    (value) => value.locale),
+                                          ),
+                                          decimalPlaces:
+                                              Constants.decimalPlaces,
+                                        )} ${coin.ticker}",
+                                        style: isDesktop
+                                            ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark,
+                                              )
+                                            : STextStyles.titleBold12(context),
+                                      ),
+                                      const SizedBox(
+                                        height: 2,
+                                      ),
+                                      if (ref.watch(
+                                          prefsChangeNotifierProvider.select(
+                                              (value) => value.externalCalls)))
+                                        SelectableText(
+                                          "$amountPrefix${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch(
+                                                localeServiceChangeNotifierProvider
+                                                    .select((value) =>
+                                                        value.locale),
+                                              ), decimalPlaces: 2)} ${ref.watch(
+                                            prefsChangeNotifierProvider.select(
+                                              (value) => value.currency,
+                                            ),
+                                          )}",
+                                          style: isDesktop
+                                              ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              : STextStyles.itemSubtitle(
+                                                  context),
+                                        ),
+                                    ],
+                                  ),
+                                  if (!isDesktop)
+                                    TxIcon(
+                                      transaction: _transaction,
+                                    ),
+                                ],
                               ),
-                      ],
-                    ),
-                  ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      Row(
-                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        children: [
-                          Text(
-                            "Note",
-                            style: STextStyles.itemSubtitle(context),
+                            ),
                           ),
-                          GestureDetector(
-                            onTap: () {
-                              Navigator.of(context).pushNamed(
-                                EditNoteView.routeName,
-                                arguments: Tuple3(
-                                  _transaction.txid,
-                                  walletId,
-                                  _note,
+                        ),
+
+                        isDesktop
+                            ? const _Divider()
+                            : const SizedBox(
+                                height: 12,
+                              ),
+                        RoundedWhiteContainer(
+                          padding: isDesktop
+                              ? const EdgeInsets.all(16)
+                              : const EdgeInsets.all(12),
+                          child: Row(
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            children: [
+                              Text(
+                                "Status",
+                                style: isDesktop
+                                    ? STextStyles.desktopTextExtraExtraSmall(
+                                        context)
+                                    : STextStyles.itemSubtitle(context),
+                              ),
+                              // Flexible(
+                              //   child: FittedBox(
+                              //     fit: BoxFit.scaleDown,
+                              //     child:
+                              SelectableText(
+                                _transaction.isCancelled
+                                    ? "Cancelled"
+                                    : whatIsIt(_transaction.txType),
+                                style: isDesktop
+                                    ? STextStyles.desktopTextExtraExtraSmall(
+                                            context)
+                                        .copyWith(
+                                        color: _transaction.txType == "Sent"
+                                            ? Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .accentColorOrange
+                                            : Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .accentColorGreen,
+                                      )
+                                    : STextStyles.itemSubtitle12(context),
+                              ),
+                              //   ),
+                              // ),
+                            ],
+                          ),
+                        ),
+                        if (!((coin == Coin.monero || coin == Coin.wownero) &&
+                                _transaction.txType.toLowerCase() == "sent") &&
+                            !((coin == Coin.firo || coin == Coin.firoTestNet) &&
+                                _transaction.subType == "mint"))
+                          isDesktop
+                              ? const _Divider()
+                              : const SizedBox(
+                                  height: 12,
                                 ),
-                              );
-                            },
+                        if (!((coin == Coin.monero || coin == Coin.wownero) &&
+                                _transaction.txType.toLowerCase() == "sent") &&
+                            !((coin == Coin.firo || coin == Coin.firoTestNet) &&
+                                _transaction.subType == "mint"))
+                          RoundedWhiteContainer(
+                            padding: isDesktop
+                                ? const EdgeInsets.all(16)
+                                : const EdgeInsets.all(12),
                             child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              crossAxisAlignment: CrossAxisAlignment.start,
                               children: [
-                                SvgPicture.asset(
-                                  Assets.svg.pencil,
-                                  width: 10,
-                                  height: 10,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .infoItemIcons,
-                                ),
-                                const SizedBox(
-                                  width: 4,
-                                ),
-                                Text(
-                                  "Edit",
-                                  style: STextStyles.link2(context),
+                                Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      _transaction.txType.toLowerCase() ==
+                                              "sent"
+                                          ? "Sent to"
+                                          : "Receiving address",
+                                      style: isDesktop
+                                          ? STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          : STextStyles.itemSubtitle(context),
+                                    ),
+                                    const SizedBox(
+                                      height: 8,
+                                    ),
+                                    _transaction.txType.toLowerCase() ==
+                                            "received"
+                                        ? FutureBuilder(
+                                            future: fetchContactNameFor(
+                                                _transaction.address),
+                                            builder: (builderContext,
+                                                AsyncSnapshot<String>
+                                                    snapshot) {
+                                              String addressOrContactName =
+                                                  _transaction.address;
+                                              if (snapshot.connectionState ==
+                                                      ConnectionState.done &&
+                                                  snapshot.hasData) {
+                                                addressOrContactName =
+                                                    snapshot.data!;
+                                              }
+                                              return SelectableText(
+                                                addressOrContactName,
+                                                style: isDesktop
+                                                    ? STextStyles
+                                                            .desktopTextExtraExtraSmall(
+                                                                context)
+                                                        .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .textDark,
+                                                      )
+                                                    : STextStyles
+                                                        .itemSubtitle12(
+                                                            context),
+                                              );
+                                            },
+                                          )
+                                        : SelectableText(
+                                            _transaction.address,
+                                            style: isDesktop
+                                                ? STextStyles
+                                                        .desktopTextExtraExtraSmall(
+                                                            context)
+                                                    .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark,
+                                                  )
+                                                : STextStyles.itemSubtitle12(
+                                                    context),
+                                          ),
+                                  ],
                                 ),
+                                if (isDesktop)
+                                  IconCopyButton(
+                                    data: _transaction.address,
+                                  ),
                               ],
                             ),
                           ),
-                        ],
-                      ),
-                      const SizedBox(
-                        height: 8,
-                      ),
-                      FutureBuilder(
-                        future: ref.watch(
-                            notesServiceChangeNotifierProvider(walletId).select(
-                                (value) =>
-                                    value.getNoteFor(txid: _transaction.txid))),
-                        builder:
-                            (builderContext, AsyncSnapshot<String> snapshot) {
-                          if (snapshot.connectionState ==
-                                  ConnectionState.done &&
-                              snapshot.hasData) {
-                            _note = snapshot.data ?? "";
-                          }
-                          return SelectableText(
-                            _note,
-                            style: STextStyles.itemSubtitle12(context),
-                          );
-                        },
-                      ),
-                    ],
-                  ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "Date",
-                        style: STextStyles.itemSubtitle(context),
-                      ),
-                      // Flexible(
-                      //   child: FittedBox(
-                      //     fit: BoxFit.scaleDown,
-                      //     child:
-                      SelectableText(
-                        Format.extractDateFrom(_transaction.timestamp),
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
-                      //   ),
-                      // ),
-                    ],
-                  ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "Transaction fee",
-                        style: STextStyles.itemSubtitle(context),
-                      ),
-                      // Flexible(
-                      //   child: FittedBox(
-                      //     fit: BoxFit.scaleDown,
-                      //     child:
-                      SelectableText(
-                        showFeePending
-                            ? _transaction.confirmedStatus
-                                ? Format.localizedStringAsFixed(
+                        isDesktop
+                            ? const _Divider()
+                            : const SizedBox(
+                                height: 12,
+                              ),
+
+                        RoundedWhiteContainer(
+                          padding: isDesktop
+                              ? const EdgeInsets.all(16)
+                              : const EdgeInsets.all(12),
+                          child: Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              Row(
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
+                                children: [
+                                  Text(
+                                    "Note",
+                                    style: isDesktop
+                                        ? STextStyles
+                                            .desktopTextExtraExtraSmall(context)
+                                        : STextStyles.itemSubtitle(context),
+                                  ),
+                                  isDesktop
+                                      ? IconPencilButton(
+                                          onPressed: () {
+                                            showDialog<void>(
+                                              context: context,
+                                              builder: (context) {
+                                                return DesktopDialog(
+                                                  maxWidth: 580,
+                                                  maxHeight: 360,
+                                                  child: EditNoteView(
+                                                    txid: _transaction.txid,
+                                                    walletId: walletId,
+                                                    note: _note,
+                                                  ),
+                                                );
+                                              },
+                                            );
+                                          },
+                                        )
+                                      : GestureDetector(
+                                          onTap: () {
+                                            Navigator.of(context).pushNamed(
+                                              EditNoteView.routeName,
+                                              arguments: Tuple3(
+                                                _transaction.txid,
+                                                walletId,
+                                                _note,
+                                              ),
+                                            );
+                                          },
+                                          child: Row(
+                                            children: [
+                                              SvgPicture.asset(
+                                                Assets.svg.pencil,
+                                                width: 10,
+                                                height: 10,
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .infoItemIcons,
+                                              ),
+                                              const SizedBox(
+                                                width: 4,
+                                              ),
+                                              Text(
+                                                "Edit",
+                                                style:
+                                                    STextStyles.link2(context),
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                ],
+                              ),
+                              const SizedBox(
+                                height: 8,
+                              ),
+                              FutureBuilder(
+                                future: ref.watch(
+                                    notesServiceChangeNotifierProvider(walletId)
+                                        .select((value) => value.getNoteFor(
+                                            txid: _transaction.txid))),
+                                builder: (builderContext,
+                                    AsyncSnapshot<String> snapshot) {
+                                  if (snapshot.connectionState ==
+                                          ConnectionState.done &&
+                                      snapshot.hasData) {
+                                    _note = snapshot.data ?? "";
+                                  }
+                                  return SelectableText(
+                                    _note,
+                                    style: isDesktop
+                                        ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            .copyWith(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark,
+                                          )
+                                        : STextStyles.itemSubtitle12(context),
+                                  );
+                                },
+                              ),
+                            ],
+                          ),
+                        ),
+                        isDesktop
+                            ? const _Divider()
+                            : const SizedBox(
+                                height: 12,
+                              ),
+                        RoundedWhiteContainer(
+                          padding: isDesktop
+                              ? const EdgeInsets.all(16)
+                              : const EdgeInsets.all(12),
+                          child: Row(
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    "Date",
+                                    style: isDesktop
+                                        ? STextStyles
+                                            .desktopTextExtraExtraSmall(context)
+                                        : STextStyles.itemSubtitle(context),
+                                  ),
+                                  if (isDesktop)
+                                    const SizedBox(
+                                      height: 2,
+                                    ),
+                                  if (isDesktop)
+                                    SelectableText(
+                                      Format.extractDateFrom(
+                                        _transaction.timestamp,
+                                      ),
+                                      style: isDesktop
+                                          ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark,
+                                            )
+                                          : STextStyles.itemSubtitle12(context),
+                                    ),
+                                ],
+                              ),
+                              if (!isDesktop)
+                                SelectableText(
+                                  Format.extractDateFrom(
+                                    _transaction.timestamp,
+                                  ),
+                                  style: isDesktop
+                                      ? STextStyles.desktopTextExtraExtraSmall(
+                                              context)
+                                          .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .textDark,
+                                        )
+                                      : STextStyles.itemSubtitle12(context),
+                                ),
+                              if (isDesktop)
+                                IconCopyButton(
+                                  data: Format.extractDateFrom(
+                                    _transaction.timestamp,
+                                  ),
+                                ),
+                            ],
+                          ),
+                        ),
+                        isDesktop
+                            ? const _Divider()
+                            : const SizedBox(
+                                height: 12,
+                              ),
+                        RoundedWhiteContainer(
+                          padding: isDesktop
+                              ? const EdgeInsets.all(16)
+                              : const EdgeInsets.all(12),
+                          child: Builder(builder: (context) {
+                            final feeString = showFeePending
+                                ? _transaction.confirmedStatus
+                                    ? Format.localizedStringAsFixed(
+                                        value: coin == Coin.monero
+                                            ? (fee / 10000.toDecimal())
+                                                .toDecimal()
+                                            : coin == Coin.wownero
+                                                ? (fee / 1000.toDecimal())
+                                                    .toDecimal()
+                                                : fee,
+                                        locale: ref.watch(
+                                            localeServiceChangeNotifierProvider
+                                                .select(
+                                                    (value) => value.locale)),
+                                        decimalPlaces: Constants.decimalPlaces)
+                                    : "Pending"
+                                : Format.localizedStringAsFixed(
                                     value: coin == Coin.monero
                                         ? (fee / 10000.toDecimal()).toDecimal()
                                         : coin == Coin.wownero
@@ -475,251 +740,403 @@ class _TransactionDetailsViewState
                                     locale: ref.watch(
                                         localeServiceChangeNotifierProvider
                                             .select((value) => value.locale)),
-                                    decimalPlaces: Constants.decimalPlaces)
-                                : "Pending"
-                            : Format.localizedStringAsFixed(
-                                value: coin == Coin.monero
-                                    ? (fee / 10000.toDecimal()).toDecimal()
-                                    : coin == Coin.wownero
-                                        ? (fee / 1000.toDecimal()).toDecimal()
-                                        : fee,
-                                locale: ref.watch(
-                                    localeServiceChangeNotifierProvider
-                                        .select((value) => value.locale)),
-                                decimalPlaces: Constants.decimalPlaces),
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
-                      //   ),
-                      // ),
-                    ],
-                  ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "Block height",
-                        style: STextStyles.itemSubtitle(context),
-                      ),
-                      // Flexible(
-                      //   child: FittedBox(
-                      //     fit: BoxFit.scaleDown,
-                      //     child:
-                      SelectableText(
-                        widget.coin != Coin.epicCash &&
-                                _transaction.confirmedStatus
-                            ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
-                            : _transaction.confirmations > 0
-                                ? "${_transaction.height}"
-                                : "Pending",
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
-                      //   ),
-                      // ),
-                    ],
-                  ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      Row(
-                        // mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        children: [
-                          Text(
-                            "Transaction ID",
-                            style: STextStyles.itemSubtitle(context),
-                          ),
-                        ],
-                      ),
-                      const SizedBox(
-                        height: 8,
-                      ),
-                      // Flexible(
-                      //   child: FittedBox(
-                      //     fit: BoxFit.scaleDown,
-                      //     child:
-                      SelectableText(
-                        _transaction.txid,
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
-                      if (coin != Coin.epicCash)
-                        const SizedBox(
-                          height: 8,
-                        ),
-                      if (coin != Coin.epicCash)
-                        BlueTextButton(
-                          text: "Open in block explorer",
-                          onTap: () async {
-                            final uri = getBlockExplorerTransactionUrlFor(
-                              coin: coin,
-                              txid: _transaction.txid,
-                            );
+                                    decimalPlaces: Constants.decimalPlaces);
 
-                            if (ref
-                                    .read(prefsChangeNotifierProvider)
-                                    .hideBlockExplorerWarning ==
-                                false) {
-                              final shouldContinue = await showExplorerWarning(
-                                  "${uri.scheme}://${uri.host}");
-
-                              if (!shouldContinue) {
-                                return;
-                              }
-                            }
-
-                            // ref
-                            //     .read(
-                            //         shouldShowLockscreenOnResumeStateProvider
-                            //             .state)
-                            //     .state = false;
-                            try {
-                              await launchUrl(
-                                uri,
-                                mode: LaunchMode.externalApplication,
-                              );
-                            } catch (_) {
-                              unawaited(showDialog<void>(
-                                context: context,
-                                builder: (_) => StackOkDialog(
-                                  title: "Could not open in block explorer",
-                                  message:
-                                      "Failed to open \"${uri.toString()}\"",
+                            return Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Transaction fee",
+                                      style: isDesktop
+                                          ? STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          : STextStyles.itemSubtitle(context),
+                                    ),
+                                    if (isDesktop)
+                                      const SizedBox(
+                                        height: 2,
+                                      ),
+                                    if (isDesktop)
+                                      SelectableText(
+                                        feeString,
+                                        style: isDesktop
+                                            ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark,
+                                              )
+                                            : STextStyles.itemSubtitle12(
+                                                context),
+                                      ),
+                                  ],
                                 ),
-                              ));
-                            } finally {
-                              // Future<void>.delayed(
-                              //   const Duration(seconds: 1),
-                              //   () => ref
-                              //       .read(
-                              //           shouldShowLockscreenOnResumeStateProvider
-                              //               .state)
-                              //       .state = true,
-                              // );
-                            }
-                          },
+                                if (!isDesktop)
+                                  SelectableText(
+                                    feeString,
+                                    style: isDesktop
+                                        ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            .copyWith(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark,
+                                          )
+                                        : STextStyles.itemSubtitle12(context),
+                                  ),
+                                if (isDesktop) IconCopyButton(data: feeString)
+                              ],
+                            );
+                          }),
                         ),
-                      //   ),
-                      // ),
-                    ],
-                  ),
-                ),
-                // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
-                //     _transaction.subType == "mint")
-                //   const SizedBox(
-                //     height: 12,
-                //   ),
-                // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
-                //     _transaction.subType == "mint")
-                //   RoundedWhiteContainer(
-                //     child: Column(
-                //       crossAxisAlignment: CrossAxisAlignment.start,
-                //       children: [
-                //         Row(
-                //           mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                //           children: [
-                //             Text(
-                //               "Mint Transaction ID",
-                //               style: STextStyles.itemSubtitle(context),
-                //             ),
-                //           ],
-                //         ),
-                //         const SizedBox(
-                //           height: 8,
-                //         ),
-                //         // Flexible(
-                //         //   child: FittedBox(
-                //         //     fit: BoxFit.scaleDown,
-                //         //     child:
-                //         SelectableText(
-                //           _transaction.otherData ?? "Unknown",
-                //           style: STextStyles.itemSubtitle12(context),
-                //         ),
-                //         //   ),
-                //         // ),
-                //         const SizedBox(
-                //           height: 8,
-                //         ),
-                //         BlueTextButton(
-                //           text: "Open in block explorer",
-                //           onTap: () async {
-                //             final uri = getBlockExplorerTransactionUrlFor(
-                //               coin: coin,
-                //               txid: _transaction.otherData ?? "Unknown",
-                //             );
-                //             // ref
-                //             //     .read(
-                //             //         shouldShowLockscreenOnResumeStateProvider
-                //             //             .state)
-                //             //     .state = false;
-                //             try {
-                //               await launchUrl(
-                //                 uri,
-                //                 mode: LaunchMode.externalApplication,
-                //               );
-                //             } catch (_) {
-                //               unawaited(showDialog<void>(
-                //                 context: context,
-                //                 builder: (_) => StackOkDialog(
-                //                   title: "Could not open in block explorer",
-                //                   message:
-                //                       "Failed to open \"${uri.toString()}\"",
-                //                 ),
-                //               ));
-                //             } finally {
-                //               // Future<void>.delayed(
-                //               //   const Duration(seconds: 1),
-                //               //   () => ref
-                //               //       .read(
-                //               //           shouldShowLockscreenOnResumeStateProvider
-                //               //               .state)
-                //               //       .state = true,
-                //               // );
-                //             }
-                //           },
-                //         ),
-                //       ],
-                //     ),
-                //   ),
-                if (coin == Coin.epicCash)
-                  const SizedBox(
-                    height: 12,
-                  ),
-                if (coin == Coin.epicCash)
-                  RoundedWhiteContainer(
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        Text(
-                          "Slate ID",
-                          style: STextStyles.itemSubtitle(context),
+                        isDesktop
+                            ? const _Divider()
+                            : const SizedBox(
+                                height: 12,
+                              ),
+                        RoundedWhiteContainer(
+                          padding: isDesktop
+                              ? const EdgeInsets.all(16)
+                              : const EdgeInsets.all(12),
+                          child: Builder(builder: (context) {
+                            final height = widget.coin != Coin.epicCash &&
+                                    _transaction.confirmedStatus
+                                ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
+                                : _transaction.confirmations > 0
+                                    ? "${_transaction.height}"
+                                    : "Pending";
+
+                            return Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Block height",
+                                      style: isDesktop
+                                          ? STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          : STextStyles.itemSubtitle(context),
+                                    ),
+                                    if (isDesktop)
+                                      const SizedBox(
+                                        height: 2,
+                                      ),
+                                    if (isDesktop)
+                                      SelectableText(
+                                        height,
+                                        style: isDesktop
+                                            ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark,
+                                              )
+                                            : STextStyles.itemSubtitle12(
+                                                context),
+                                      ),
+                                  ],
+                                ),
+                                if (!isDesktop)
+                                  SelectableText(
+                                    height,
+                                    style: isDesktop
+                                        ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            .copyWith(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark,
+                                          )
+                                        : STextStyles.itemSubtitle12(context),
+                                  ),
+                                if (isDesktop) IconCopyButton(data: height),
+                              ],
+                            );
+                          }),
                         ),
-                        // Flexible(
-                        //   child: FittedBox(
-                        //     fit: BoxFit.scaleDown,
-                        //     child:
-                        SelectableText(
-                          _transaction.slateId ?? "Unknown",
-                          style: STextStyles.itemSubtitle12(context),
+                        isDesktop
+                            ? const _Divider()
+                            : const SizedBox(
+                                height: 12,
+                              ),
+                        RoundedWhiteContainer(
+                          padding: isDesktop
+                              ? const EdgeInsets.all(16)
+                              : const EdgeInsets.all(12),
+                          child: Row(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            children: [
+                              Expanded(
+                                child: Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Transaction ID",
+                                      style: isDesktop
+                                          ? STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          : STextStyles.itemSubtitle(context),
+                                    ),
+                                    const SizedBox(
+                                      height: 8,
+                                    ),
+                                    // Flexible(
+                                    //   child: FittedBox(
+                                    //     fit: BoxFit.scaleDown,
+                                    //     child:
+                                    SelectableText(
+                                      _transaction.txid,
+                                      style: isDesktop
+                                          ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark,
+                                            )
+                                          : STextStyles.itemSubtitle12(context),
+                                    ),
+                                    if (coin != Coin.epicCash)
+                                      const SizedBox(
+                                        height: 8,
+                                      ),
+                                    if (coin != Coin.epicCash)
+                                      BlueTextButton(
+                                        text: "Open in block explorer",
+                                        onTap: () async {
+                                          final uri =
+                                              getBlockExplorerTransactionUrlFor(
+                                            coin: coin,
+                                            txid: _transaction.txid,
+                                          );
+
+                                          if (ref
+                                                  .read(
+                                                      prefsChangeNotifierProvider)
+                                                  .hideBlockExplorerWarning ==
+                                              false) {
+                                            final shouldContinue =
+                                                await showExplorerWarning(
+                                                    "${uri.scheme}://${uri.host}");
+
+                                            if (!shouldContinue) {
+                                              return;
+                                            }
+                                          }
+
+                                          // ref
+                                          //     .read(
+                                          //         shouldShowLockscreenOnResumeStateProvider
+                                          //             .state)
+                                          //     .state = false;
+                                          try {
+                                            await launchUrl(
+                                              uri,
+                                              mode: LaunchMode
+                                                  .externalApplication,
+                                            );
+                                          } catch (_) {
+                                            unawaited(showDialog<void>(
+                                              context: context,
+                                              builder: (_) => StackOkDialog(
+                                                title:
+                                                    "Could not open in block explorer",
+                                                message:
+                                                    "Failed to open \"${uri.toString()}\"",
+                                              ),
+                                            ));
+                                          } finally {
+                                            // Future<void>.delayed(
+                                            //   const Duration(seconds: 1),
+                                            //   () => ref
+                                            //       .read(
+                                            //           shouldShowLockscreenOnResumeStateProvider
+                                            //               .state)
+                                            //       .state = true,
+                                            // );
+                                          }
+                                        },
+                                      ),
+                                    //   ),
+                                    // ),
+                                  ],
+                                ),
+                              ),
+                              if (isDesktop)
+                                const SizedBox(
+                                  width: 12,
+                                ),
+                              if (isDesktop)
+                                IconCopyButton(
+                                  data: _transaction.txid,
+                                ),
+                            ],
+                          ),
                         ),
+                        // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                        //     _transaction.subType == "mint")
+                        //   const SizedBox(
+                        //     height: 12,
                         //   ),
-                        // ),
+                        // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                        //     _transaction.subType == "mint")
+                        //   RoundedWhiteContainer(
+                        //     child: Column(
+                        //       crossAxisAlignment: CrossAxisAlignment.start,
+                        //       children: [
+                        //         Row(
+                        //           mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        //           children: [
+                        //             Text(
+                        //               "Mint Transaction ID",
+                        //               style: STextStyles.itemSubtitle(context),
+                        //             ),
+                        //           ],
+                        //         ),
+                        //         const SizedBox(
+                        //           height: 8,
+                        //         ),
+                        //         // Flexible(
+                        //         //   child: FittedBox(
+                        //         //     fit: BoxFit.scaleDown,
+                        //         //     child:
+                        //         SelectableText(
+                        //           _transaction.otherData ?? "Unknown",
+                        //           style: STextStyles.itemSubtitle12(context),
+                        //         ),
+                        //         //   ),
+                        //         // ),
+                        //         const SizedBox(
+                        //           height: 8,
+                        //         ),
+                        //         BlueTextButton(
+                        //           text: "Open in block explorer",
+                        //           onTap: () async {
+                        //             final uri = getBlockExplorerTransactionUrlFor(
+                        //               coin: coin,
+                        //               txid: _transaction.otherData ?? "Unknown",
+                        //             );
+                        //             // ref
+                        //             //     .read(
+                        //             //         shouldShowLockscreenOnResumeStateProvider
+                        //             //             .state)
+                        //             //     .state = false;
+                        //             try {
+                        //               await launchUrl(
+                        //                 uri,
+                        //                 mode: LaunchMode.externalApplication,
+                        //               );
+                        //             } catch (_) {
+                        //               unawaited(showDialog<void>(
+                        //                 context: context,
+                        //                 builder: (_) => StackOkDialog(
+                        //                   title: "Could not open in block explorer",
+                        //                   message:
+                        //                       "Failed to open \"${uri.toString()}\"",
+                        //                 ),
+                        //               ));
+                        //             } finally {
+                        //               // Future<void>.delayed(
+                        //               //   const Duration(seconds: 1),
+                        //               //   () => ref
+                        //               //       .read(
+                        //               //           shouldShowLockscreenOnResumeStateProvider
+                        //               //               .state)
+                        //               //       .state = true,
+                        //               // );
+                        //             }
+                        //           },
+                        //         ),
+                        //       ],
+                        //     ),
+                        //   ),
+                        if (coin == Coin.epicCash)
+                          isDesktop
+                              ? const _Divider()
+                              : const SizedBox(
+                                  height: 12,
+                                ),
+                        if (coin == Coin.epicCash)
+                          RoundedWhiteContainer(
+                            padding: isDesktop
+                                ? const EdgeInsets.all(16)
+                                : const EdgeInsets.all(12),
+                            child: Row(
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              children: [
+                                Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Slate ID",
+                                      style: isDesktop
+                                          ? STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          : STextStyles.itemSubtitle(context),
+                                    ),
+                                    // Flexible(
+                                    //   child: FittedBox(
+                                    //     fit: BoxFit.scaleDown,
+                                    //     child:
+                                    SelectableText(
+                                      _transaction.slateId ?? "Unknown",
+                                      style: isDesktop
+                                          ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark,
+                                            )
+                                          : STextStyles.itemSubtitle12(context),
+                                    ),
+                                    //   ),
+                                    // ),
+                                  ],
+                                ),
+                                if (isDesktop)
+                                  const SizedBox(
+                                    width: 12,
+                                  ),
+                                if (isDesktop)
+                                  IconCopyButton(
+                                    data: _transaction.slateId ?? "Unknown",
+                                  ),
+                              ],
+                            ),
+                          ),
+                        if (!isDesktop)
+                          const SizedBox(
+                            height: 12,
+                          ),
                       ],
                     ),
                   ),
-                const SizedBox(
-                  height: 12,
                 ),
-              ],
+              ),
             ),
-          ),
+          ],
         ),
       ),
       floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
@@ -805,3 +1222,94 @@ class _TransactionDetailsViewState
     );
   }
 }
+
+class _Divider extends StatelessWidget {
+  const _Divider({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      height: 1,
+      color: Theme.of(context).extension<StackColors>()!.background,
+    );
+  }
+}
+
+class IconCopyButton extends StatelessWidget {
+  const IconCopyButton({
+    Key? key,
+    required this.data,
+  }) : super(key: key);
+
+  final String data;
+
+  @override
+  Widget build(BuildContext context) {
+    return SizedBox(
+      height: 26,
+      width: 26,
+      child: RawMaterialButton(
+        fillColor:
+            Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
+        elevation: 0,
+        hoverElevation: 0,
+        shape: RoundedRectangleBorder(
+          borderRadius: BorderRadius.circular(6),
+        ),
+        onPressed: () async {
+          await Clipboard.setData(ClipboardData(text: data));
+          unawaited(
+            showFloatingFlushBar(
+              type: FlushBarType.info,
+              message: "Copied to clipboard",
+              context: context,
+            ),
+          );
+        },
+        child: Padding(
+          padding: const EdgeInsets.all(5),
+          child: CopyIcon(
+            width: 16,
+            height: 16,
+            color: Theme.of(context).extension<StackColors>()!.textDark,
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+class IconPencilButton extends StatelessWidget {
+  const IconPencilButton({
+    Key? key,
+    this.onPressed,
+  }) : super(key: key);
+
+  final VoidCallback? onPressed;
+
+  @override
+  Widget build(BuildContext context) {
+    return SizedBox(
+      height: 26,
+      width: 26,
+      child: RawMaterialButton(
+        fillColor:
+            Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
+        elevation: 0,
+        hoverElevation: 0,
+        shape: RoundedRectangleBorder(
+          borderRadius: BorderRadius.circular(6),
+        ),
+        onPressed: () => onPressed?.call(),
+        child: Padding(
+          padding: const EdgeInsets.all(5),
+          child: PencilIcon(
+            width: 16,
+            height: 16,
+            color: Theme.of(context).extension<StackColors>()!.textDark,
+          ),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/widgets/icon_widgets/copy_icon.dart b/lib/widgets/icon_widgets/copy_icon.dart
new file mode 100644
index 000000000..9f82a8066
--- /dev/null
+++ b/lib/widgets/icon_widgets/copy_icon.dart
@@ -0,0 +1,27 @@
+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';
+
+class CopyIcon extends StatelessWidget {
+  const CopyIcon({
+    Key? key,
+    this.width = 18,
+    this.height = 18,
+    this.color,
+  }) : super(key: key);
+
+  final double width;
+  final double height;
+  final Color? color;
+
+  @override
+  Widget build(BuildContext context) {
+    return SvgPicture.asset(
+      Assets.svg.copy,
+      width: width,
+      height: height,
+      color: color ?? Theme.of(context).extension<StackColors>()!.textDark3,
+    );
+  }
+}
diff --git a/lib/widgets/icon_widgets/pencil_icon.dart b/lib/widgets/icon_widgets/pencil_icon.dart
new file mode 100644
index 000000000..cb14f1cbf
--- /dev/null
+++ b/lib/widgets/icon_widgets/pencil_icon.dart
@@ -0,0 +1,27 @@
+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';
+
+class PencilIcon extends StatelessWidget {
+  const PencilIcon({
+    Key? key,
+    this.width = 18,
+    this.height = 18,
+    this.color,
+  }) : super(key: key);
+
+  final double width;
+  final double height;
+  final Color? color;
+
+  @override
+  Widget build(BuildContext context) {
+    return SvgPicture.asset(
+      Assets.svg.pencil,
+      width: width,
+      height: height,
+      color: color ?? Theme.of(context).extension<StackColors>()!.textDark3,
+    );
+  }
+}
diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart
index de0447684..8867e34f6 100644
--- a/lib/widgets/transaction_card.dart
+++ b/lib/widgets/transaction_card.dart
@@ -14,6 +14,7 @@ import 'package:stackwallet/utilities/format.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/desktop_dialog.dart';
 import 'package:tuple/tuple.dart';
 
 class TransactionCard extends ConsumerStatefulWidget {
@@ -138,16 +139,31 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
               ));
               return;
             }
-            unawaited(
-              Navigator.of(context).pushNamed(
-                TransactionDetailsView.routeName,
-                arguments: Tuple3(
-                  _transaction,
-                  coin,
-                  walletId,
+            if (Util.isDesktop) {
+              await showDialog<void>(
+                context: context,
+                builder: (context) => DesktopDialog(
+                  maxHeight: MediaQuery.of(context).size.height - 64,
+                  maxWidth: 580,
+                  child: TransactionDetailsView(
+                    transaction: _transaction,
+                    coin: coin,
+                    walletId: walletId,
+                  ),
                 ),
-              ),
-            );
+              );
+            } else {
+              unawaited(
+                Navigator.of(context).pushNamed(
+                  TransactionDetailsView.routeName,
+                  arguments: Tuple3(
+                    _transaction,
+                    coin,
+                    walletId,
+                  ),
+                ),
+              );
+            }
           },
           child: Padding(
             padding: const EdgeInsets.all(8),
diff --git a/pubspec.lock b/pubspec.lock
index 4f886e8bb..20992d827 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -42,7 +42,7 @@ packages:
       name: archive
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "3.3.0"
+    version: "3.1.11"
   args:
     dependency: transitive
     description:
@@ -63,7 +63,7 @@ packages:
       name: async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.9.0"
+    version: "2.8.2"
   barcode_scan2:
     dependency: "direct main"
     description:
@@ -190,7 +190,14 @@ packages:
       name: characters
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.2.1"
+    version: "1.2.0"
+  charcode:
+    dependency: transitive
+    description:
+      name: charcode
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.3.1"
   checked_yaml:
     dependency: transitive
     description:
@@ -204,7 +211,7 @@ packages:
       name: clock
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.1"
+    version: "1.1.0"
   code_builder:
     dependency: transitive
     description:
@@ -274,7 +281,7 @@ packages:
       name: coverage
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.5.0"
+    version: "1.2.0"
   cross_file:
     dependency: transitive
     description:
@@ -428,7 +435,7 @@ packages:
       name: fake_async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.1"
+    version: "1.3.0"
   ffi:
     dependency: "direct main"
     description:
@@ -857,21 +864,21 @@ packages:
       name: matcher
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.12.12"
+    version: "0.12.11"
   material_color_utilities:
     dependency: transitive
     description:
       name: material_color_utilities
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.1.5"
+    version: "0.1.4"
   meta:
     dependency: transitive
     description:
       name: meta
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.8.0"
+    version: "1.7.0"
   mime:
     dependency: transitive
     description:
@@ -983,7 +990,7 @@ packages:
       name: path
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.8.2"
+    version: "1.8.1"
   path_drawing:
     dependency: transitive
     description:
@@ -1359,7 +1366,7 @@ packages:
       name: source_span
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.9.0"
+    version: "1.8.2"
   stack_trace:
     dependency: transitive
     description:
@@ -1417,35 +1424,35 @@ packages:
       name: sync_http
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.3.1"
+    version: "0.3.0"
   term_glyph:
     dependency: transitive
     description:
       name: term_glyph
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.2.1"
+    version: "1.2.0"
   test:
     dependency: transitive
     description:
       name: test
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.21.4"
+    version: "1.21.1"
   test_api:
     dependency: transitive
     description:
       name: test_api
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.12"
+    version: "0.4.9"
   test_core:
     dependency: transitive
     description:
       name: test_core
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.16"
+    version: "0.4.13"
   time:
     dependency: transitive
     description:
@@ -1494,7 +1501,7 @@ packages:
       name: typed_data
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.1"
+    version: "1.3.0"
   universal_io:
     dependency: transitive
     description:
@@ -1578,7 +1585,7 @@ packages:
       name: vm_service
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "9.0.0"
+    version: "8.2.2"
   wakelock:
     dependency: "direct main"
     description:

From 32eb9bb9200d16a6160700897cfe3464067a1ad5 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 29 Oct 2022 13:44:37 -0600
Subject: [PATCH 074/426] desktop tx details scroll fix

---
 .../transaction_details_view.dart             | 1659 +++++++++--------
 1 file changed, 845 insertions(+), 814 deletions(-)

diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
index d7f06095d..d1e415b26 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -252,91 +252,438 @@ class _TransactionDetailsViewState
                   const DesktopDialogCloseButton(),
                 ],
               ),
-            Padding(
-              padding: isDesktop
-                  ? const EdgeInsets.only(
-                      right: 32,
-                      bottom: 32,
-                    )
-                  : const EdgeInsets.all(0),
-              child: RoundedWhiteContainer(
-                borderColor: isDesktop
-                    ? Theme.of(context).extension<StackColors>()!.background
-                    : null,
-                padding: const EdgeInsets.all(0),
-                child: SingleChildScrollView(
-                  child: Padding(
-                    padding: isDesktop
-                        ? const EdgeInsets.all(0)
-                        : const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        RoundedWhiteContainer(
-                          padding: isDesktop
-                              ? const EdgeInsets.all(0)
-                              : const EdgeInsets.all(12),
-                          child: Container(
-                            decoration: isDesktop
-                                ? BoxDecoration(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .background,
-                                    borderRadius: BorderRadius.vertical(
-                                      top: Radius.circular(
-                                        Constants.size.circularBorderRadius,
+            Expanded(
+              child: Padding(
+                padding: isDesktop
+                    ? const EdgeInsets.only(
+                        right: 32,
+                        bottom: 32,
+                      )
+                    : const EdgeInsets.all(0),
+                child: RoundedWhiteContainer(
+                  borderColor: isDesktop
+                      ? Theme.of(context).extension<StackColors>()!.background
+                      : null,
+                  padding: const EdgeInsets.all(0),
+                  child: SingleChildScrollView(
+                    primary: isDesktop ? false : null,
+                    child: Padding(
+                      padding: isDesktop
+                          ? const EdgeInsets.all(0)
+                          : const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          RoundedWhiteContainer(
+                            padding: isDesktop
+                                ? const EdgeInsets.all(0)
+                                : const EdgeInsets.all(12),
+                            child: Container(
+                              decoration: isDesktop
+                                  ? BoxDecoration(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .background,
+                                      borderRadius: BorderRadius.vertical(
+                                        top: Radius.circular(
+                                          Constants.size.circularBorderRadius,
+                                        ),
                                       ),
+                                    )
+                                  : null,
+                              child: Padding(
+                                padding: isDesktop
+                                    ? const EdgeInsets.all(12)
+                                    : const EdgeInsets.all(0),
+                                child: Row(
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  children: [
+                                    if (isDesktop)
+                                      Row(
+                                        children: [
+                                          TxIcon(
+                                            transaction: _transaction,
+                                          ),
+                                          const SizedBox(
+                                            width: 16,
+                                          ),
+                                          SelectableText(
+                                            _transaction.isCancelled
+                                                ? "Cancelled"
+                                                : whatIsIt(_transaction.txType),
+                                            style:
+                                                STextStyles.desktopTextMedium(
+                                                    context),
+                                          ),
+                                        ],
+                                      ),
+                                    Column(
+                                      crossAxisAlignment: isDesktop
+                                          ? CrossAxisAlignment.end
+                                          : CrossAxisAlignment.start,
+                                      children: [
+                                        SelectableText(
+                                          "$amountPrefix${Format.localizedStringAsFixed(
+                                            value: coin == Coin.monero
+                                                ? (amount / 10000.toDecimal())
+                                                    .toDecimal()
+                                                : coin == Coin.wownero
+                                                    ? (amount /
+                                                            1000.toDecimal())
+                                                        .toDecimal()
+                                                    : amount,
+                                            locale: ref.watch(
+                                              localeServiceChangeNotifierProvider
+                                                  .select(
+                                                      (value) => value.locale),
+                                            ),
+                                            decimalPlaces:
+                                                Constants.decimalPlaces,
+                                          )} ${coin.ticker}",
+                                          style: isDesktop
+                                              ? STextStyles
+                                                      .desktopTextExtraExtraSmall(
+                                                          context)
+                                                  .copyWith(
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark,
+                                                )
+                                              : STextStyles.titleBold12(
+                                                  context),
+                                        ),
+                                        const SizedBox(
+                                          height: 2,
+                                        ),
+                                        if (ref.watch(
+                                            prefsChangeNotifierProvider.select(
+                                                (value) =>
+                                                    value.externalCalls)))
+                                          SelectableText(
+                                            "$amountPrefix${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch(
+                                                  localeServiceChangeNotifierProvider
+                                                      .select((value) =>
+                                                          value.locale),
+                                                ), decimalPlaces: 2)} ${ref.watch(
+                                              prefsChangeNotifierProvider
+                                                  .select(
+                                                (value) => value.currency,
+                                              ),
+                                            )}",
+                                            style: isDesktop
+                                                ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                : STextStyles.itemSubtitle(
+                                                    context),
+                                          ),
+                                      ],
                                     ),
-                                  )
-                                : null,
-                            child: Padding(
+                                    if (!isDesktop)
+                                      TxIcon(
+                                        transaction: _transaction,
+                                      ),
+                                  ],
+                                ),
+                              ),
+                            ),
+                          ),
+
+                          isDesktop
+                              ? const _Divider()
+                              : const SizedBox(
+                                  height: 12,
+                                ),
+                          RoundedWhiteContainer(
+                            padding: isDesktop
+                                ? const EdgeInsets.all(16)
+                                : const EdgeInsets.all(12),
+                            child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              children: [
+                                Text(
+                                  "Status",
+                                  style: isDesktop
+                                      ? STextStyles.desktopTextExtraExtraSmall(
+                                          context)
+                                      : STextStyles.itemSubtitle(context),
+                                ),
+                                // Flexible(
+                                //   child: FittedBox(
+                                //     fit: BoxFit.scaleDown,
+                                //     child:
+                                SelectableText(
+                                  _transaction.isCancelled
+                                      ? "Cancelled"
+                                      : whatIsIt(_transaction.txType),
+                                  style: isDesktop
+                                      ? STextStyles.desktopTextExtraExtraSmall(
+                                              context)
+                                          .copyWith(
+                                          color: _transaction.txType == "Sent"
+                                              ? Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorOrange
+                                              : Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorGreen,
+                                        )
+                                      : STextStyles.itemSubtitle12(context),
+                                ),
+                                //   ),
+                                // ),
+                              ],
+                            ),
+                          ),
+                          if (!((coin == Coin.monero || coin == Coin.wownero) &&
+                                  _transaction.txType.toLowerCase() ==
+                                      "sent") &&
+                              !((coin == Coin.firo ||
+                                      coin == Coin.firoTestNet) &&
+                                  _transaction.subType == "mint"))
+                            isDesktop
+                                ? const _Divider()
+                                : const SizedBox(
+                                    height: 12,
+                                  ),
+                          if (!((coin == Coin.monero || coin == Coin.wownero) &&
+                                  _transaction.txType.toLowerCase() ==
+                                      "sent") &&
+                              !((coin == Coin.firo ||
+                                      coin == Coin.firoTestNet) &&
+                                  _transaction.subType == "mint"))
+                            RoundedWhiteContainer(
                               padding: isDesktop
-                                  ? const EdgeInsets.all(12)
-                                  : const EdgeInsets.all(0),
+                                  ? const EdgeInsets.all(16)
+                                  : const EdgeInsets.all(12),
                               child: Row(
                                 mainAxisAlignment:
                                     MainAxisAlignment.spaceBetween,
+                                crossAxisAlignment: CrossAxisAlignment.start,
                                 children: [
-                                  if (isDesktop)
-                                    Row(
-                                      children: [
-                                        TxIcon(
-                                          transaction: _transaction,
-                                        ),
-                                        const SizedBox(
-                                          width: 16,
-                                        ),
-                                        SelectableText(
-                                          _transaction.isCancelled
-                                              ? "Cancelled"
-                                              : whatIsIt(_transaction.txType),
-                                          style: STextStyles.desktopTextMedium(
-                                              context),
-                                        ),
-                                      ],
-                                    ),
                                   Column(
-                                    crossAxisAlignment: isDesktop
-                                        ? CrossAxisAlignment.end
-                                        : CrossAxisAlignment.start,
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.start,
                                     children: [
-                                      SelectableText(
-                                        "$amountPrefix${Format.localizedStringAsFixed(
-                                          value: coin == Coin.monero
-                                              ? (amount / 10000.toDecimal())
-                                                  .toDecimal()
-                                              : coin == Coin.wownero
-                                                  ? (amount / 1000.toDecimal())
-                                                      .toDecimal()
-                                                  : amount,
-                                          locale: ref.watch(
-                                            localeServiceChangeNotifierProvider
-                                                .select(
-                                                    (value) => value.locale),
+                                      Text(
+                                        _transaction.txType.toLowerCase() ==
+                                                "sent"
+                                            ? "Sent to"
+                                            : "Receiving address",
+                                        style: isDesktop
+                                            ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            : STextStyles.itemSubtitle(context),
+                                      ),
+                                      const SizedBox(
+                                        height: 8,
+                                      ),
+                                      _transaction.txType.toLowerCase() ==
+                                              "received"
+                                          ? FutureBuilder(
+                                              future: fetchContactNameFor(
+                                                  _transaction.address),
+                                              builder: (builderContext,
+                                                  AsyncSnapshot<String>
+                                                      snapshot) {
+                                                String addressOrContactName =
+                                                    _transaction.address;
+                                                if (snapshot.connectionState ==
+                                                        ConnectionState.done &&
+                                                    snapshot.hasData) {
+                                                  addressOrContactName =
+                                                      snapshot.data!;
+                                                }
+                                                return SelectableText(
+                                                  addressOrContactName,
+                                                  style: isDesktop
+                                                      ? STextStyles
+                                                              .desktopTextExtraExtraSmall(
+                                                                  context)
+                                                          .copyWith(
+                                                          color: Theme.of(
+                                                                  context)
+                                                              .extension<
+                                                                  StackColors>()!
+                                                              .textDark,
+                                                        )
+                                                      : STextStyles
+                                                          .itemSubtitle12(
+                                                              context),
+                                                );
+                                              },
+                                            )
+                                          : SelectableText(
+                                              _transaction.address,
+                                              style: isDesktop
+                                                  ? STextStyles
+                                                          .desktopTextExtraExtraSmall(
+                                                              context)
+                                                      .copyWith(
+                                                      color: Theme.of(context)
+                                                          .extension<
+                                                              StackColors>()!
+                                                          .textDark,
+                                                    )
+                                                  : STextStyles.itemSubtitle12(
+                                                      context),
+                                            ),
+                                    ],
+                                  ),
+                                  if (isDesktop)
+                                    IconCopyButton(
+                                      data: _transaction.address,
+                                    ),
+                                ],
+                              ),
+                            ),
+                          isDesktop
+                              ? const _Divider()
+                              : const SizedBox(
+                                  height: 12,
+                                ),
+
+                          RoundedWhiteContainer(
+                            padding: isDesktop
+                                ? const EdgeInsets.all(16)
+                                : const EdgeInsets.all(12),
+                            child: Column(
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                Row(
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  children: [
+                                    Text(
+                                      "Note",
+                                      style: isDesktop
+                                          ? STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          : STextStyles.itemSubtitle(context),
+                                    ),
+                                    isDesktop
+                                        ? IconPencilButton(
+                                            onPressed: () {
+                                              showDialog<void>(
+                                                context: context,
+                                                builder: (context) {
+                                                  return DesktopDialog(
+                                                    maxWidth: 580,
+                                                    maxHeight: 360,
+                                                    child: EditNoteView(
+                                                      txid: _transaction.txid,
+                                                      walletId: walletId,
+                                                      note: _note,
+                                                    ),
+                                                  );
+                                                },
+                                              );
+                                            },
+                                          )
+                                        : GestureDetector(
+                                            onTap: () {
+                                              Navigator.of(context).pushNamed(
+                                                EditNoteView.routeName,
+                                                arguments: Tuple3(
+                                                  _transaction.txid,
+                                                  walletId,
+                                                  _note,
+                                                ),
+                                              );
+                                            },
+                                            child: Row(
+                                              children: [
+                                                SvgPicture.asset(
+                                                  Assets.svg.pencil,
+                                                  width: 10,
+                                                  height: 10,
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .infoItemIcons,
+                                                ),
+                                                const SizedBox(
+                                                  width: 4,
+                                                ),
+                                                Text(
+                                                  "Edit",
+                                                  style: STextStyles.link2(
+                                                      context),
+                                                ),
+                                              ],
+                                            ),
                                           ),
-                                          decimalPlaces:
-                                              Constants.decimalPlaces,
-                                        )} ${coin.ticker}",
+                                  ],
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                FutureBuilder(
+                                  future: ref.watch(
+                                      notesServiceChangeNotifierProvider(
+                                              walletId)
+                                          .select((value) => value.getNoteFor(
+                                              txid: _transaction.txid))),
+                                  builder: (builderContext,
+                                      AsyncSnapshot<String> snapshot) {
+                                    if (snapshot.connectionState ==
+                                            ConnectionState.done &&
+                                        snapshot.hasData) {
+                                      _note = snapshot.data ?? "";
+                                    }
+                                    return SelectableText(
+                                      _note,
+                                      style: isDesktop
+                                          ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark,
+                                            )
+                                          : STextStyles.itemSubtitle12(context),
+                                    );
+                                  },
+                                ),
+                              ],
+                            ),
+                          ),
+                          isDesktop
+                              ? const _Divider()
+                              : const SizedBox(
+                                  height: 12,
+                                ),
+                          RoundedWhiteContainer(
+                            padding: isDesktop
+                                ? const EdgeInsets.all(16)
+                                : const EdgeInsets.all(12),
+                            child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Date",
+                                      style: isDesktop
+                                          ? STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          : STextStyles.itemSubtitle(context),
+                                    ),
+                                    if (isDesktop)
+                                      const SizedBox(
+                                        height: 2,
+                                      ),
+                                    if (isDesktop)
+                                      SelectableText(
+                                        Format.extractDateFrom(
+                                          _transaction.timestamp,
+                                        ),
                                         style: isDesktop
                                             ? STextStyles
                                                     .desktopTextExtraExtraSmall(
@@ -346,774 +693,319 @@ class _TransactionDetailsViewState
                                                     .extension<StackColors>()!
                                                     .textDark,
                                               )
-                                            : STextStyles.titleBold12(context),
+                                            : STextStyles.itemSubtitle12(
+                                                context),
                                       ),
-                                      const SizedBox(
-                                        height: 2,
+                                  ],
+                                ),
+                                if (!isDesktop)
+                                  SelectableText(
+                                    Format.extractDateFrom(
+                                      _transaction.timestamp,
+                                    ),
+                                    style: isDesktop
+                                        ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            .copyWith(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark,
+                                          )
+                                        : STextStyles.itemSubtitle12(context),
+                                  ),
+                                if (isDesktop)
+                                  IconCopyButton(
+                                    data: Format.extractDateFrom(
+                                      _transaction.timestamp,
+                                    ),
+                                  ),
+                              ],
+                            ),
+                          ),
+                          isDesktop
+                              ? const _Divider()
+                              : const SizedBox(
+                                  height: 12,
+                                ),
+                          RoundedWhiteContainer(
+                            padding: isDesktop
+                                ? const EdgeInsets.all(16)
+                                : const EdgeInsets.all(12),
+                            child: Builder(builder: (context) {
+                              final feeString = showFeePending
+                                  ? _transaction.confirmedStatus
+                                      ? Format.localizedStringAsFixed(
+                                          value: coin == Coin.monero
+                                              ? (fee / 10000.toDecimal())
+                                                  .toDecimal()
+                                              : coin == Coin.wownero
+                                                  ? (fee / 1000.toDecimal())
+                                                      .toDecimal()
+                                                  : fee,
+                                          locale: ref.watch(
+                                              localeServiceChangeNotifierProvider
+                                                  .select(
+                                                      (value) => value.locale)),
+                                          decimalPlaces:
+                                              Constants.decimalPlaces)
+                                      : "Pending"
+                                  : Format.localizedStringAsFixed(
+                                      value: coin == Coin.monero
+                                          ? (fee / 10000.toDecimal())
+                                              .toDecimal()
+                                          : coin == Coin.wownero
+                                              ? (fee / 1000.toDecimal())
+                                                  .toDecimal()
+                                              : fee,
+                                      locale: ref.watch(
+                                          localeServiceChangeNotifierProvider
+                                              .select((value) => value.locale)),
+                                      decimalPlaces: Constants.decimalPlaces);
+
+                              return Row(
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.start,
+                                    children: [
+                                      Text(
+                                        "Transaction fee",
+                                        style: isDesktop
+                                            ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            : STextStyles.itemSubtitle(context),
                                       ),
-                                      if (ref.watch(
-                                          prefsChangeNotifierProvider.select(
-                                              (value) => value.externalCalls)))
+                                      if (isDesktop)
+                                        const SizedBox(
+                                          height: 2,
+                                        ),
+                                      if (isDesktop)
                                         SelectableText(
-                                          "$amountPrefix${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch(
-                                                localeServiceChangeNotifierProvider
-                                                    .select((value) =>
-                                                        value.locale),
-                                              ), decimalPlaces: 2)} ${ref.watch(
-                                            prefsChangeNotifierProvider.select(
-                                              (value) => value.currency,
-                                            ),
-                                          )}",
+                                          feeString,
                                           style: isDesktop
                                               ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              : STextStyles.itemSubtitle(
+                                                      .desktopTextExtraExtraSmall(
+                                                          context)
+                                                  .copyWith(
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark,
+                                                )
+                                              : STextStyles.itemSubtitle12(
                                                   context),
                                         ),
                                     ],
                                   ),
                                   if (!isDesktop)
-                                    TxIcon(
-                                      transaction: _transaction,
+                                    SelectableText(
+                                      feeString,
+                                      style: isDesktop
+                                          ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark,
+                                            )
+                                          : STextStyles.itemSubtitle12(context),
                                     ),
+                                  if (isDesktop) IconCopyButton(data: feeString)
                                 ],
-                              ),
-                            ),
+                              );
+                            }),
+                          ),
+                          isDesktop
+                              ? const _Divider()
+                              : const SizedBox(
+                                  height: 12,
+                                ),
+                          RoundedWhiteContainer(
+                            padding: isDesktop
+                                ? const EdgeInsets.all(16)
+                                : const EdgeInsets.all(12),
+                            child: Builder(builder: (context) {
+                              final height = widget.coin != Coin.epicCash &&
+                                      _transaction.confirmedStatus
+                                  ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
+                                  : _transaction.confirmations > 0
+                                      ? "${_transaction.height}"
+                                      : "Pending";
+
+                              return Row(
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.start,
+                                    children: [
+                                      Text(
+                                        "Block height",
+                                        style: isDesktop
+                                            ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            : STextStyles.itemSubtitle(context),
+                                      ),
+                                      if (isDesktop)
+                                        const SizedBox(
+                                          height: 2,
+                                        ),
+                                      if (isDesktop)
+                                        SelectableText(
+                                          height,
+                                          style: isDesktop
+                                              ? STextStyles
+                                                      .desktopTextExtraExtraSmall(
+                                                          context)
+                                                  .copyWith(
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark,
+                                                )
+                                              : STextStyles.itemSubtitle12(
+                                                  context),
+                                        ),
+                                    ],
+                                  ),
+                                  if (!isDesktop)
+                                    SelectableText(
+                                      height,
+                                      style: isDesktop
+                                          ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark,
+                                            )
+                                          : STextStyles.itemSubtitle12(context),
+                                    ),
+                                  if (isDesktop) IconCopyButton(data: height),
+                                ],
+                              );
+                            }),
                           ),
-                        ),
-
-                        isDesktop
-                            ? const _Divider()
-                            : const SizedBox(
-                                height: 12,
-                              ),
-                        RoundedWhiteContainer(
-                          padding: isDesktop
-                              ? const EdgeInsets.all(16)
-                              : const EdgeInsets.all(12),
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "Status",
-                                style: isDesktop
-                                    ? STextStyles.desktopTextExtraExtraSmall(
-                                        context)
-                                    : STextStyles.itemSubtitle(context),
-                              ),
-                              // Flexible(
-                              //   child: FittedBox(
-                              //     fit: BoxFit.scaleDown,
-                              //     child:
-                              SelectableText(
-                                _transaction.isCancelled
-                                    ? "Cancelled"
-                                    : whatIsIt(_transaction.txType),
-                                style: isDesktop
-                                    ? STextStyles.desktopTextExtraExtraSmall(
-                                            context)
-                                        .copyWith(
-                                        color: _transaction.txType == "Sent"
-                                            ? Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .accentColorOrange
-                                            : Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .accentColorGreen,
-                                      )
-                                    : STextStyles.itemSubtitle12(context),
-                              ),
-                              //   ),
-                              // ),
-                            ],
-                          ),
-                        ),
-                        if (!((coin == Coin.monero || coin == Coin.wownero) &&
-                                _transaction.txType.toLowerCase() == "sent") &&
-                            !((coin == Coin.firo || coin == Coin.firoTestNet) &&
-                                _transaction.subType == "mint"))
                           isDesktop
                               ? const _Divider()
                               : const SizedBox(
                                   height: 12,
                                 ),
-                        if (!((coin == Coin.monero || coin == Coin.wownero) &&
-                                _transaction.txType.toLowerCase() == "sent") &&
-                            !((coin == Coin.firo || coin == Coin.firoTestNet) &&
-                                _transaction.subType == "mint"))
                           RoundedWhiteContainer(
                             padding: isDesktop
                                 ? const EdgeInsets.all(16)
                                 : const EdgeInsets.all(12),
                             child: Row(
-                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                               crossAxisAlignment: CrossAxisAlignment.start,
-                              children: [
-                                Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      _transaction.txType.toLowerCase() ==
-                                              "sent"
-                                          ? "Sent to"
-                                          : "Receiving address",
-                                      style: isDesktop
-                                          ? STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          : STextStyles.itemSubtitle(context),
-                                    ),
-                                    const SizedBox(
-                                      height: 8,
-                                    ),
-                                    _transaction.txType.toLowerCase() ==
-                                            "received"
-                                        ? FutureBuilder(
-                                            future: fetchContactNameFor(
-                                                _transaction.address),
-                                            builder: (builderContext,
-                                                AsyncSnapshot<String>
-                                                    snapshot) {
-                                              String addressOrContactName =
-                                                  _transaction.address;
-                                              if (snapshot.connectionState ==
-                                                      ConnectionState.done &&
-                                                  snapshot.hasData) {
-                                                addressOrContactName =
-                                                    snapshot.data!;
-                                              }
-                                              return SelectableText(
-                                                addressOrContactName,
-                                                style: isDesktop
-                                                    ? STextStyles
-                                                            .desktopTextExtraExtraSmall(
-                                                                context)
-                                                        .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .textDark,
-                                                      )
-                                                    : STextStyles
-                                                        .itemSubtitle12(
-                                                            context),
-                                              );
-                                            },
-                                          )
-                                        : SelectableText(
-                                            _transaction.address,
-                                            style: isDesktop
-                                                ? STextStyles
-                                                        .desktopTextExtraExtraSmall(
-                                                            context)
-                                                    .copyWith(
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark,
-                                                  )
-                                                : STextStyles.itemSubtitle12(
-                                                    context),
-                                          ),
-                                  ],
-                                ),
-                                if (isDesktop)
-                                  IconCopyButton(
-                                    data: _transaction.address,
-                                  ),
-                              ],
-                            ),
-                          ),
-                        isDesktop
-                            ? const _Divider()
-                            : const SizedBox(
-                                height: 12,
-                              ),
-
-                        RoundedWhiteContainer(
-                          padding: isDesktop
-                              ? const EdgeInsets.all(16)
-                              : const EdgeInsets.all(12),
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              Row(
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
-                                children: [
-                                  Text(
-                                    "Note",
-                                    style: isDesktop
-                                        ? STextStyles
-                                            .desktopTextExtraExtraSmall(context)
-                                        : STextStyles.itemSubtitle(context),
-                                  ),
-                                  isDesktop
-                                      ? IconPencilButton(
-                                          onPressed: () {
-                                            showDialog<void>(
-                                              context: context,
-                                              builder: (context) {
-                                                return DesktopDialog(
-                                                  maxWidth: 580,
-                                                  maxHeight: 360,
-                                                  child: EditNoteView(
-                                                    txid: _transaction.txid,
-                                                    walletId: walletId,
-                                                    note: _note,
-                                                  ),
-                                                );
-                                              },
-                                            );
-                                          },
-                                        )
-                                      : GestureDetector(
-                                          onTap: () {
-                                            Navigator.of(context).pushNamed(
-                                              EditNoteView.routeName,
-                                              arguments: Tuple3(
-                                                _transaction.txid,
-                                                walletId,
-                                                _note,
-                                              ),
-                                            );
-                                          },
-                                          child: Row(
-                                            children: [
-                                              SvgPicture.asset(
-                                                Assets.svg.pencil,
-                                                width: 10,
-                                                height: 10,
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .infoItemIcons,
-                                              ),
-                                              const SizedBox(
-                                                width: 4,
-                                              ),
-                                              Text(
-                                                "Edit",
-                                                style:
-                                                    STextStyles.link2(context),
-                                              ),
-                                            ],
-                                          ),
-                                        ),
-                                ],
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              FutureBuilder(
-                                future: ref.watch(
-                                    notesServiceChangeNotifierProvider(walletId)
-                                        .select((value) => value.getNoteFor(
-                                            txid: _transaction.txid))),
-                                builder: (builderContext,
-                                    AsyncSnapshot<String> snapshot) {
-                                  if (snapshot.connectionState ==
-                                          ConnectionState.done &&
-                                      snapshot.hasData) {
-                                    _note = snapshot.data ?? "";
-                                  }
-                                  return SelectableText(
-                                    _note,
-                                    style: isDesktop
-                                        ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            .copyWith(
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textDark,
-                                          )
-                                        : STextStyles.itemSubtitle12(context),
-                                  );
-                                },
-                              ),
-                            ],
-                          ),
-                        ),
-                        isDesktop
-                            ? const _Divider()
-                            : const SizedBox(
-                                height: 12,
-                              ),
-                        RoundedWhiteContainer(
-                          padding: isDesktop
-                              ? const EdgeInsets.all(16)
-                              : const EdgeInsets.all(12),
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              Column(
-                                crossAxisAlignment: CrossAxisAlignment.start,
-                                children: [
-                                  Text(
-                                    "Date",
-                                    style: isDesktop
-                                        ? STextStyles
-                                            .desktopTextExtraExtraSmall(context)
-                                        : STextStyles.itemSubtitle(context),
-                                  ),
-                                  if (isDesktop)
-                                    const SizedBox(
-                                      height: 2,
-                                    ),
-                                  if (isDesktop)
-                                    SelectableText(
-                                      Format.extractDateFrom(
-                                        _transaction.timestamp,
-                                      ),
-                                      style: isDesktop
-                                          ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark,
-                                            )
-                                          : STextStyles.itemSubtitle12(context),
-                                    ),
-                                ],
-                              ),
-                              if (!isDesktop)
-                                SelectableText(
-                                  Format.extractDateFrom(
-                                    _transaction.timestamp,
-                                  ),
-                                  style: isDesktop
-                                      ? STextStyles.desktopTextExtraExtraSmall(
-                                              context)
-                                          .copyWith(
-                                          color: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .textDark,
-                                        )
-                                      : STextStyles.itemSubtitle12(context),
-                                ),
-                              if (isDesktop)
-                                IconCopyButton(
-                                  data: Format.extractDateFrom(
-                                    _transaction.timestamp,
-                                  ),
-                                ),
-                            ],
-                          ),
-                        ),
-                        isDesktop
-                            ? const _Divider()
-                            : const SizedBox(
-                                height: 12,
-                              ),
-                        RoundedWhiteContainer(
-                          padding: isDesktop
-                              ? const EdgeInsets.all(16)
-                              : const EdgeInsets.all(12),
-                          child: Builder(builder: (context) {
-                            final feeString = showFeePending
-                                ? _transaction.confirmedStatus
-                                    ? Format.localizedStringAsFixed(
-                                        value: coin == Coin.monero
-                                            ? (fee / 10000.toDecimal())
-                                                .toDecimal()
-                                            : coin == Coin.wownero
-                                                ? (fee / 1000.toDecimal())
-                                                    .toDecimal()
-                                                : fee,
-                                        locale: ref.watch(
-                                            localeServiceChangeNotifierProvider
-                                                .select(
-                                                    (value) => value.locale)),
-                                        decimalPlaces: Constants.decimalPlaces)
-                                    : "Pending"
-                                : Format.localizedStringAsFixed(
-                                    value: coin == Coin.monero
-                                        ? (fee / 10000.toDecimal()).toDecimal()
-                                        : coin == Coin.wownero
-                                            ? (fee / 1000.toDecimal())
-                                                .toDecimal()
-                                            : fee,
-                                    locale: ref.watch(
-                                        localeServiceChangeNotifierProvider
-                                            .select((value) => value.locale)),
-                                    decimalPlaces: Constants.decimalPlaces);
-
-                            return Row(
                               mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                              crossAxisAlignment: CrossAxisAlignment.start,
                               children: [
-                                Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Transaction fee",
-                                      style: isDesktop
-                                          ? STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          : STextStyles.itemSubtitle(context),
-                                    ),
-                                    if (isDesktop)
-                                      const SizedBox(
-                                        height: 2,
-                                      ),
-                                    if (isDesktop)
-                                      SelectableText(
-                                        feeString,
+                                Expanded(
+                                  child: Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.start,
+                                    children: [
+                                      Text(
+                                        "Transaction ID",
                                         style: isDesktop
                                             ? STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark,
-                                              )
-                                            : STextStyles.itemSubtitle12(
-                                                context),
-                                      ),
-                                  ],
-                                ),
-                                if (!isDesktop)
-                                  SelectableText(
-                                    feeString,
-                                    style: isDesktop
-                                        ? STextStyles
                                                 .desktopTextExtraExtraSmall(
                                                     context)
-                                            .copyWith(
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textDark,
-                                          )
-                                        : STextStyles.itemSubtitle12(context),
-                                  ),
-                                if (isDesktop) IconCopyButton(data: feeString)
-                              ],
-                            );
-                          }),
-                        ),
-                        isDesktop
-                            ? const _Divider()
-                            : const SizedBox(
-                                height: 12,
-                              ),
-                        RoundedWhiteContainer(
-                          padding: isDesktop
-                              ? const EdgeInsets.all(16)
-                              : const EdgeInsets.all(12),
-                          child: Builder(builder: (context) {
-                            final height = widget.coin != Coin.epicCash &&
-                                    _transaction.confirmedStatus
-                                ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
-                                : _transaction.confirmations > 0
-                                    ? "${_transaction.height}"
-                                    : "Pending";
-
-                            return Row(
-                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                              crossAxisAlignment: CrossAxisAlignment.start,
-                              children: [
-                                Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Block height",
-                                      style: isDesktop
-                                          ? STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          : STextStyles.itemSubtitle(context),
-                                    ),
-                                    if (isDesktop)
-                                      const SizedBox(
-                                        height: 2,
+                                            : STextStyles.itemSubtitle(context),
                                       ),
-                                    if (isDesktop)
-                                      SelectableText(
-                                        height,
-                                        style: isDesktop
-                                            ? STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark,
-                                              )
-                                            : STextStyles.itemSubtitle12(
-                                                context),
-                                      ),
-                                  ],
-                                ),
-                                if (!isDesktop)
-                                  SelectableText(
-                                    height,
-                                    style: isDesktop
-                                        ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            .copyWith(
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textDark,
-                                          )
-                                        : STextStyles.itemSubtitle12(context),
-                                  ),
-                                if (isDesktop) IconCopyButton(data: height),
-                              ],
-                            );
-                          }),
-                        ),
-                        isDesktop
-                            ? const _Divider()
-                            : const SizedBox(
-                                height: 12,
-                              ),
-                        RoundedWhiteContainer(
-                          padding: isDesktop
-                              ? const EdgeInsets.all(16)
-                              : const EdgeInsets.all(12),
-                          child: Row(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Expanded(
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Transaction ID",
-                                      style: isDesktop
-                                          ? STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          : STextStyles.itemSubtitle(context),
-                                    ),
-                                    const SizedBox(
-                                      height: 8,
-                                    ),
-                                    // Flexible(
-                                    //   child: FittedBox(
-                                    //     fit: BoxFit.scaleDown,
-                                    //     child:
-                                    SelectableText(
-                                      _transaction.txid,
-                                      style: isDesktop
-                                          ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark,
-                                            )
-                                          : STextStyles.itemSubtitle12(context),
-                                    ),
-                                    if (coin != Coin.epicCash)
                                       const SizedBox(
                                         height: 8,
                                       ),
-                                    if (coin != Coin.epicCash)
-                                      BlueTextButton(
-                                        text: "Open in block explorer",
-                                        onTap: () async {
-                                          final uri =
-                                              getBlockExplorerTransactionUrlFor(
-                                            coin: coin,
-                                            txid: _transaction.txid,
-                                          );
-
-                                          if (ref
-                                                  .read(
-                                                      prefsChangeNotifierProvider)
-                                                  .hideBlockExplorerWarning ==
-                                              false) {
-                                            final shouldContinue =
-                                                await showExplorerWarning(
-                                                    "${uri.scheme}://${uri.host}");
-
-                                            if (!shouldContinue) {
-                                              return;
-                                            }
-                                          }
-
-                                          // ref
-                                          //     .read(
-                                          //         shouldShowLockscreenOnResumeStateProvider
-                                          //             .state)
-                                          //     .state = false;
-                                          try {
-                                            await launchUrl(
-                                              uri,
-                                              mode: LaunchMode
-                                                  .externalApplication,
-                                            );
-                                          } catch (_) {
-                                            unawaited(showDialog<void>(
-                                              context: context,
-                                              builder: (_) => StackOkDialog(
-                                                title:
-                                                    "Could not open in block explorer",
-                                                message:
-                                                    "Failed to open \"${uri.toString()}\"",
-                                              ),
-                                            ));
-                                          } finally {
-                                            // Future<void>.delayed(
-                                            //   const Duration(seconds: 1),
-                                            //   () => ref
-                                            //       .read(
-                                            //           shouldShowLockscreenOnResumeStateProvider
-                                            //               .state)
-                                            //       .state = true,
-                                            // );
-                                          }
-                                        },
+                                      // Flexible(
+                                      //   child: FittedBox(
+                                      //     fit: BoxFit.scaleDown,
+                                      //     child:
+                                      SelectableText(
+                                        _transaction.txid,
+                                        style: isDesktop
+                                            ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark,
+                                              )
+                                            : STextStyles.itemSubtitle12(
+                                                context),
                                       ),
-                                    //   ),
-                                    // ),
-                                  ],
-                                ),
-                              ),
-                              if (isDesktop)
-                                const SizedBox(
-                                  width: 12,
-                                ),
-                              if (isDesktop)
-                                IconCopyButton(
-                                  data: _transaction.txid,
-                                ),
-                            ],
-                          ),
-                        ),
-                        // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
-                        //     _transaction.subType == "mint")
-                        //   const SizedBox(
-                        //     height: 12,
-                        //   ),
-                        // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
-                        //     _transaction.subType == "mint")
-                        //   RoundedWhiteContainer(
-                        //     child: Column(
-                        //       crossAxisAlignment: CrossAxisAlignment.start,
-                        //       children: [
-                        //         Row(
-                        //           mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        //           children: [
-                        //             Text(
-                        //               "Mint Transaction ID",
-                        //               style: STextStyles.itemSubtitle(context),
-                        //             ),
-                        //           ],
-                        //         ),
-                        //         const SizedBox(
-                        //           height: 8,
-                        //         ),
-                        //         // Flexible(
-                        //         //   child: FittedBox(
-                        //         //     fit: BoxFit.scaleDown,
-                        //         //     child:
-                        //         SelectableText(
-                        //           _transaction.otherData ?? "Unknown",
-                        //           style: STextStyles.itemSubtitle12(context),
-                        //         ),
-                        //         //   ),
-                        //         // ),
-                        //         const SizedBox(
-                        //           height: 8,
-                        //         ),
-                        //         BlueTextButton(
-                        //           text: "Open in block explorer",
-                        //           onTap: () async {
-                        //             final uri = getBlockExplorerTransactionUrlFor(
-                        //               coin: coin,
-                        //               txid: _transaction.otherData ?? "Unknown",
-                        //             );
-                        //             // ref
-                        //             //     .read(
-                        //             //         shouldShowLockscreenOnResumeStateProvider
-                        //             //             .state)
-                        //             //     .state = false;
-                        //             try {
-                        //               await launchUrl(
-                        //                 uri,
-                        //                 mode: LaunchMode.externalApplication,
-                        //               );
-                        //             } catch (_) {
-                        //               unawaited(showDialog<void>(
-                        //                 context: context,
-                        //                 builder: (_) => StackOkDialog(
-                        //                   title: "Could not open in block explorer",
-                        //                   message:
-                        //                       "Failed to open \"${uri.toString()}\"",
-                        //                 ),
-                        //               ));
-                        //             } finally {
-                        //               // Future<void>.delayed(
-                        //               //   const Duration(seconds: 1),
-                        //               //   () => ref
-                        //               //       .read(
-                        //               //           shouldShowLockscreenOnResumeStateProvider
-                        //               //               .state)
-                        //               //       .state = true,
-                        //               // );
-                        //             }
-                        //           },
-                        //         ),
-                        //       ],
-                        //     ),
-                        //   ),
-                        if (coin == Coin.epicCash)
-                          isDesktop
-                              ? const _Divider()
-                              : const SizedBox(
-                                  height: 12,
-                                ),
-                        if (coin == Coin.epicCash)
-                          RoundedWhiteContainer(
-                            padding: isDesktop
-                                ? const EdgeInsets.all(16)
-                                : const EdgeInsets.all(12),
-                            child: Row(
-                              crossAxisAlignment: CrossAxisAlignment.start,
-                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                              children: [
-                                Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Slate ID",
-                                      style: isDesktop
-                                          ? STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          : STextStyles.itemSubtitle(context),
-                                    ),
-                                    // Flexible(
-                                    //   child: FittedBox(
-                                    //     fit: BoxFit.scaleDown,
-                                    //     child:
-                                    SelectableText(
-                                      _transaction.slateId ?? "Unknown",
-                                      style: isDesktop
-                                          ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark,
-                                            )
-                                          : STextStyles.itemSubtitle12(context),
-                                    ),
-                                    //   ),
-                                    // ),
-                                  ],
+                                      if (coin != Coin.epicCash)
+                                        const SizedBox(
+                                          height: 8,
+                                        ),
+                                      if (coin != Coin.epicCash)
+                                        BlueTextButton(
+                                          text: "Open in block explorer",
+                                          onTap: () async {
+                                            final uri =
+                                                getBlockExplorerTransactionUrlFor(
+                                              coin: coin,
+                                              txid: _transaction.txid,
+                                            );
+
+                                            if (ref
+                                                    .read(
+                                                        prefsChangeNotifierProvider)
+                                                    .hideBlockExplorerWarning ==
+                                                false) {
+                                              final shouldContinue =
+                                                  await showExplorerWarning(
+                                                      "${uri.scheme}://${uri.host}");
+
+                                              if (!shouldContinue) {
+                                                return;
+                                              }
+                                            }
+
+                                            // ref
+                                            //     .read(
+                                            //         shouldShowLockscreenOnResumeStateProvider
+                                            //             .state)
+                                            //     .state = false;
+                                            try {
+                                              await launchUrl(
+                                                uri,
+                                                mode: LaunchMode
+                                                    .externalApplication,
+                                              );
+                                            } catch (_) {
+                                              unawaited(showDialog<void>(
+                                                context: context,
+                                                builder: (_) => StackOkDialog(
+                                                  title:
+                                                      "Could not open in block explorer",
+                                                  message:
+                                                      "Failed to open \"${uri.toString()}\"",
+                                                ),
+                                              ));
+                                            } finally {
+                                              // Future<void>.delayed(
+                                              //   const Duration(seconds: 1),
+                                              //   () => ref
+                                              //       .read(
+                                              //           shouldShowLockscreenOnResumeStateProvider
+                                              //               .state)
+                                              //       .state = true,
+                                              // );
+                                            }
+                                          },
+                                        ),
+                                      //   ),
+                                      // ),
+                                    ],
+                                  ),
                                 ),
                                 if (isDesktop)
                                   const SizedBox(
@@ -1121,16 +1013,155 @@ class _TransactionDetailsViewState
                                   ),
                                 if (isDesktop)
                                   IconCopyButton(
-                                    data: _transaction.slateId ?? "Unknown",
+                                    data: _transaction.txid,
                                   ),
                               ],
                             ),
                           ),
-                        if (!isDesktop)
-                          const SizedBox(
-                            height: 12,
-                          ),
-                      ],
+                          // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                          //     _transaction.subType == "mint")
+                          //   const SizedBox(
+                          //     height: 12,
+                          //   ),
+                          // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                          //     _transaction.subType == "mint")
+                          //   RoundedWhiteContainer(
+                          //     child: Column(
+                          //       crossAxisAlignment: CrossAxisAlignment.start,
+                          //       children: [
+                          //         Row(
+                          //           mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          //           children: [
+                          //             Text(
+                          //               "Mint Transaction ID",
+                          //               style: STextStyles.itemSubtitle(context),
+                          //             ),
+                          //           ],
+                          //         ),
+                          //         const SizedBox(
+                          //           height: 8,
+                          //         ),
+                          //         // Flexible(
+                          //         //   child: FittedBox(
+                          //         //     fit: BoxFit.scaleDown,
+                          //         //     child:
+                          //         SelectableText(
+                          //           _transaction.otherData ?? "Unknown",
+                          //           style: STextStyles.itemSubtitle12(context),
+                          //         ),
+                          //         //   ),
+                          //         // ),
+                          //         const SizedBox(
+                          //           height: 8,
+                          //         ),
+                          //         BlueTextButton(
+                          //           text: "Open in block explorer",
+                          //           onTap: () async {
+                          //             final uri = getBlockExplorerTransactionUrlFor(
+                          //               coin: coin,
+                          //               txid: _transaction.otherData ?? "Unknown",
+                          //             );
+                          //             // ref
+                          //             //     .read(
+                          //             //         shouldShowLockscreenOnResumeStateProvider
+                          //             //             .state)
+                          //             //     .state = false;
+                          //             try {
+                          //               await launchUrl(
+                          //                 uri,
+                          //                 mode: LaunchMode.externalApplication,
+                          //               );
+                          //             } catch (_) {
+                          //               unawaited(showDialog<void>(
+                          //                 context: context,
+                          //                 builder: (_) => StackOkDialog(
+                          //                   title: "Could not open in block explorer",
+                          //                   message:
+                          //                       "Failed to open \"${uri.toString()}\"",
+                          //                 ),
+                          //               ));
+                          //             } finally {
+                          //               // Future<void>.delayed(
+                          //               //   const Duration(seconds: 1),
+                          //               //   () => ref
+                          //               //       .read(
+                          //               //           shouldShowLockscreenOnResumeStateProvider
+                          //               //               .state)
+                          //               //       .state = true,
+                          //               // );
+                          //             }
+                          //           },
+                          //         ),
+                          //       ],
+                          //     ),
+                          //   ),
+                          if (coin == Coin.epicCash)
+                            isDesktop
+                                ? const _Divider()
+                                : const SizedBox(
+                                    height: 12,
+                                  ),
+                          if (coin == Coin.epicCash)
+                            RoundedWhiteContainer(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(16)
+                                  : const EdgeInsets.all(12),
+                              child: Row(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
+                                children: [
+                                  Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.start,
+                                    children: [
+                                      Text(
+                                        "Slate ID",
+                                        style: isDesktop
+                                            ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            : STextStyles.itemSubtitle(context),
+                                      ),
+                                      // Flexible(
+                                      //   child: FittedBox(
+                                      //     fit: BoxFit.scaleDown,
+                                      //     child:
+                                      SelectableText(
+                                        _transaction.slateId ?? "Unknown",
+                                        style: isDesktop
+                                            ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark,
+                                              )
+                                            : STextStyles.itemSubtitle12(
+                                                context),
+                                      ),
+                                      //   ),
+                                      // ),
+                                    ],
+                                  ),
+                                  if (isDesktop)
+                                    const SizedBox(
+                                      width: 12,
+                                    ),
+                                  if (isDesktop)
+                                    IconCopyButton(
+                                      data: _transaction.slateId ?? "Unknown",
+                                    ),
+                                ],
+                              ),
+                            ),
+                          if (!isDesktop)
+                            const SizedBox(
+                              height: 12,
+                            ),
+                        ],
+                      ),
                     ),
                   ),
                 ),

From c9220c5c11518da877b5736f79dceb98f9744658 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sun, 30 Oct 2022 11:13:32 -0600
Subject: [PATCH 075/426] desktop wallet renaming

---
 .../wallet_view/desktop_wallet_view.dart      | 156 ++++++++++++------
 lib/widgets/desktop/desktop_app_bar.dart      |  10 +-
 lib/widgets/hover_text_field.dart             | 123 ++++++++++++++
 3 files changed, 236 insertions(+), 53 deletions(-)
 create mode 100644 lib/widgets/hover_text_field.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 0e5aa925f..5dadd511c 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -43,6 +43,7 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/hover_text_field.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
@@ -66,6 +67,7 @@ class DesktopWalletView extends ConsumerStatefulWidget {
 }
 
 class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
+  late final TextEditingController controller;
   late final String walletId;
   late final EventBus eventBus;
 
@@ -179,10 +181,13 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
 
   @override
   void initState() {
+    controller = TextEditingController();
     walletId = widget.walletId;
     final managerProvider =
         ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
 
+    controller.text = ref.read(managerProvider).walletName;
+
     eventBus =
         widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
 
@@ -211,61 +216,110 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
     return DesktopScaffold(
       appBar: DesktopAppBar(
         background: Theme.of(context).extension<StackColors>()!.popupBG,
-        leading: Row(
-          children: [
-            const SizedBox(
-              width: 32,
-            ),
-            AppBarIconButton(
-              size: 32,
-              color: Theme.of(context)
-                  .extension<StackColors>()!
-                  .textFieldDefaultBG,
-              shadows: const [],
-              icon: SvgPicture.asset(
-                Assets.svg.arrowLeft,
-                width: 18,
-                height: 18,
+        leading: Expanded(
+          child: Row(
+            children: [
+              const SizedBox(
+                width: 32,
+              ),
+              AppBarIconButton(
+                size: 32,
                 color: Theme.of(context)
                     .extension<StackColors>()!
-                    .topNavIconPrimary,
+                    .textFieldDefaultBG,
+                shadows: const [],
+                icon: SvgPicture.asset(
+                  Assets.svg.arrowLeft,
+                  width: 18,
+                  height: 18,
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .topNavIconPrimary,
+                ),
+                onPressed: onBackPressed,
               ),
-              onPressed: onBackPressed,
-            ),
-            const SizedBox(
-              width: 15,
-            ),
-            SvgPicture.asset(
-              Assets.svg.iconFor(coin: coin),
-              width: 32,
-              height: 32,
-            ),
-            const SizedBox(
-              width: 12,
-            ),
-            Text(
-              manager.walletName,
-              style: STextStyles.desktopH3(context),
-            ),
-          ],
-        ),
-        trailing: Row(
-          children: [
-            NetworkInfoButton(
-              walletId: walletId,
-              eventBus: eventBus,
-            ),
-            const SizedBox(
-              width: 32,
-            ),
-            WalletKeysButton(
-              walletId: walletId,
-            ),
-            const SizedBox(
-              width: 32,
-            ),
-          ],
+              const SizedBox(
+                width: 15,
+              ),
+              SvgPicture.asset(
+                Assets.svg.iconFor(coin: coin),
+                width: 32,
+                height: 32,
+              ),
+              const SizedBox(
+                width: 12,
+              ),
+              ConstrainedBox(
+                constraints: const BoxConstraints(
+                  minWidth: 48,
+                ),
+                child: IntrinsicWidth(
+                  child: HoverTextField(
+                    controller: controller,
+                    style: STextStyles.desktopH3(context),
+                    readOnly: true,
+                    onDone: () async {
+                      final currentWalletName =
+                          ref.read(managerProvider).walletName;
+                      final newName = controller.text;
+                      if (newName != currentWalletName) {
+                        final success = await ref
+                            .read(walletsServiceChangeNotifierProvider)
+                            .renameWallet(
+                              from: currentWalletName,
+                              to: newName,
+                              shouldNotifyListeners: true,
+                            );
+                        if (success) {
+                          ref
+                              .read(walletsChangeNotifierProvider)
+                              .getManager(walletId)
+                              .walletName = newName;
+                          unawaited(
+                            showFloatingFlushBar(
+                              type: FlushBarType.success,
+                              message: "Wallet renamed",
+                              context: context,
+                            ),
+                          );
+                        } else {
+                          unawaited(
+                            showFloatingFlushBar(
+                              type: FlushBarType.warning,
+                              message:
+                                  "Wallet named \"$newName\" already exists",
+                              context: context,
+                            ),
+                          );
+                          controller.text = currentWalletName;
+                        }
+                      }
+                    },
+                  ),
+                ),
+              ),
+              const Spacer(),
+              Row(
+                children: [
+                  NetworkInfoButton(
+                    walletId: walletId,
+                    eventBus: eventBus,
+                  ),
+                  const SizedBox(
+                    width: 32,
+                  ),
+                  WalletKeysButton(
+                    walletId: walletId,
+                  ),
+                  const SizedBox(
+                    width: 32,
+                  ),
+                ],
+              ),
+            ],
+          ),
         ),
+        useSpacers: false,
         isCompactHeight: true,
       ),
       body: Padding(
diff --git a/lib/widgets/desktop/desktop_app_bar.dart b/lib/widgets/desktop/desktop_app_bar.dart
index 1c825382c..bbad0385a 100644
--- a/lib/widgets/desktop/desktop_app_bar.dart
+++ b/lib/widgets/desktop/desktop_app_bar.dart
@@ -11,6 +11,7 @@ class DesktopAppBar extends StatefulWidget {
     this.trailing,
     this.background = Colors.transparent,
     required this.isCompactHeight,
+    this.useSpacers = true,
   }) : super(key: key);
 
   final Widget? leading;
@@ -18,6 +19,7 @@ class DesktopAppBar extends StatefulWidget {
   final Widget? trailing;
   final Color background;
   final bool isCompactHeight;
+  final bool useSpacers;
 
   @override
   State<DesktopAppBar> createState() => _DesktopAppBarState();
@@ -33,11 +35,15 @@ class _DesktopAppBarState extends State<DesktopAppBar> {
       items.add(widget.leading!);
     }
 
-    items.add(const Spacer());
+    if (widget.useSpacers) {
+      items.add(const Spacer());
+    }
 
     if (widget.center != null) {
       items.add(widget.center!);
-      items.add(const Spacer());
+      if (widget.useSpacers) {
+        items.add(const Spacer());
+      }
     }
 
     if (widget.trailing != null) {
diff --git a/lib/widgets/hover_text_field.dart b/lib/widgets/hover_text_field.dart
new file mode 100644
index 000000000..475d6c2ec
--- /dev/null
+++ b/lib/widgets/hover_text_field.dart
@@ -0,0 +1,123 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
+
+class HoverTextField extends StatefulWidget {
+  const HoverTextField({
+    Key? key,
+    this.controller,
+    this.focusNode,
+    this.readOnly = false,
+    this.enabled,
+    this.onTap,
+    this.onChanged,
+    this.onEditingComplete,
+    this.style,
+    this.onDone,
+  }) : super(key: key);
+
+  final TextEditingController? controller;
+  final FocusNode? focusNode;
+  final bool readOnly;
+  final bool? enabled;
+  final GestureTapCallback? onTap;
+  final ValueChanged<String>? onChanged;
+  final VoidCallback? onEditingComplete;
+  final TextStyle? style;
+  final VoidCallback? onDone;
+
+  @override
+  State<HoverTextField> createState() => _HoverTextFieldState();
+}
+
+class _HoverTextFieldState extends State<HoverTextField> {
+  late final TextEditingController? controller;
+  late final FocusNode? focusNode;
+  late bool readOnly;
+  late bool? enabled;
+  late final GestureTapCallback? onTap;
+  late final ValueChanged<String>? onChanged;
+  late final VoidCallback? onEditingComplete;
+  late final TextStyle? style;
+  late final VoidCallback? onDone;
+
+  final InputBorder inputBorder = OutlineInputBorder(
+    borderSide: const BorderSide(
+      width: 0,
+      color: Colors.transparent,
+    ),
+    borderRadius: BorderRadius.circular(Constants.size.circularBorderRadius),
+  );
+
+  @override
+  void initState() {
+    controller = widget.controller;
+    focusNode = widget.focusNode ?? FocusNode();
+    readOnly = widget.readOnly;
+    enabled = widget.enabled;
+    onChanged = widget.onChanged;
+    style = widget.style;
+    onTap = widget.onTap;
+    onEditingComplete = widget.onEditingComplete;
+    onDone = widget.onDone;
+
+    focusNode!.addListener(() {
+      if (!focusNode!.hasPrimaryFocus && !readOnly) {
+        setState(() {
+          readOnly = true;
+        });
+        onDone?.call();
+      }
+    });
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    controller?.dispose();
+    focusNode?.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return TextField(
+      autocorrect: !Util.isDesktop,
+      enableSuggestions: !Util.isDesktop,
+      controller: controller,
+      focusNode: focusNode,
+      readOnly: readOnly,
+      enabled: enabled,
+      onTap: () {
+        setState(() {
+          readOnly = false;
+        });
+        onTap?.call();
+      },
+      onChanged: onChanged,
+      onEditingComplete: () {
+        setState(() {
+          readOnly = true;
+        });
+        onEditingComplete?.call();
+        onDone?.call();
+      },
+      style: style,
+      decoration: InputDecoration(
+        contentPadding: const EdgeInsets.symmetric(
+          vertical: 4,
+          horizontal: 12,
+        ),
+        border: inputBorder,
+        focusedBorder: inputBorder,
+        disabledBorder: inputBorder,
+        enabledBorder: inputBorder,
+        errorBorder: inputBorder,
+        fillColor: readOnly
+            ? Colors.transparent
+            : Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
+      ),
+    );
+  }
+}

From a1f4ec87de975904c8c8f17c7876ff23e209ba4b Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sun, 30 Oct 2022 11:26:58 -0600
Subject: [PATCH 076/426] desktop wallet view refactor

---
 .../wallet_view/desktop_wallet_view.dart      | 873 +-----------------
 .../desktop_receive.dart                      |   0
 .../{send => sub_widgets}/desktop_send.dart   |   0
 .../desktop_wallet_summary.dart               |   0
 .../wallet_view/sub_widgets/my_wallet.dart    |  89 ++
 .../sub_widgets/network_info_button.dart      | 176 ++++
 .../qr_code_desktop_popup_content.dart        |  42 +
 .../recent_desktop_transactions.dart          |  64 ++
 .../sub_widgets/send_receive_tab_menu.dart    | 128 +++
 .../unlock_wallet_keys_desktop.dart           | 228 +++++
 .../sub_widgets/wallet_keys_button.dart       |  52 ++
 .../wallet_keys_desktop_popup.dart            | 146 +++
 lib/route_generator.dart                      |   2 +
 13 files changed, 932 insertions(+), 868 deletions(-)
 rename lib/pages_desktop_specific/home/my_stack_view/wallet_view/{receive => sub_widgets}/desktop_receive.dart (100%)
 rename lib/pages_desktop_specific/home/my_stack_view/wallet_view/{send => sub_widgets}/desktop_send.dart (100%)
 rename lib/pages_desktop_specific/home/my_stack_view/wallet_view/{ => sub_widgets}/desktop_wallet_summary.dart (100%)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/my_wallet.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 5dadd511c..97efb2f68 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -2,33 +2,24 @@ import 'dart:async';
 
 import 'package:event_bus/event_bus.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:qr_flutter/qr_flutter.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
-import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
 import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
-import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
-import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart';
-import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart';
-import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart';
-import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart';
-import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/my_wallet.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart';
 import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
-import 'package:stackwallet/route_generator.dart';
-import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_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/exchange/change_now/change_now_exchange.dart';
 import 'package:stackwallet/services/exchange/exchange_data_loading_service.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/constants.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@@ -36,17 +27,12 @@ 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/custom_buttons/app_bar_icon_button.dart';
-import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
-import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/hover_text_field.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
-import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:tuple/tuple.dart';
 
 /// [eventBus] should only be set during testing
@@ -408,852 +394,3 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
     );
   }
 }
-
-class MyWallet extends StatefulWidget {
-  const MyWallet({
-    Key? key,
-    required this.walletId,
-  }) : super(key: key);
-
-  final String walletId;
-
-  @override
-  State<MyWallet> createState() => _MyWalletState();
-}
-
-class _MyWalletState extends State<MyWallet> {
-  int _selectedIndex = 0;
-
-  @override
-  Widget build(BuildContext context) {
-    return ListView(
-      primary: false,
-      children: [
-        Text(
-          "My wallet",
-          style: STextStyles.desktopTextExtraSmall(context).copyWith(
-            color: Theme.of(context)
-                .extension<StackColors>()!
-                .textFieldActiveSearchIconLeft,
-          ),
-        ),
-        const SizedBox(
-          height: 16,
-        ),
-        Container(
-          decoration: BoxDecoration(
-            color: Theme.of(context).extension<StackColors>()!.popupBG,
-            borderRadius: BorderRadius.vertical(
-              top: Radius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-            ),
-          ),
-          child: SendReceiveTabMenu(
-            onChanged: (index) {
-              setState(() {
-                _selectedIndex = index;
-              });
-            },
-          ),
-        ),
-        Container(
-          decoration: BoxDecoration(
-            color: Theme.of(context).extension<StackColors>()!.popupBG,
-            borderRadius: BorderRadius.vertical(
-              bottom: Radius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-            ),
-          ),
-          child: IndexedStack(
-            index: _selectedIndex,
-            children: [
-              Padding(
-                key: const Key("desktopSendViewPortKey"),
-                padding: const EdgeInsets.all(20),
-                child: DesktopSend(
-                  walletId: widget.walletId,
-                ),
-              ),
-              Padding(
-                key: const Key("desktopReceiveViewPortKey"),
-                padding: const EdgeInsets.all(20),
-                child: DesktopReceive(
-                  walletId: widget.walletId,
-                ),
-              ),
-            ],
-          ),
-        ),
-      ],
-    );
-  }
-}
-
-class SendReceiveTabMenu extends StatefulWidget {
-  const SendReceiveTabMenu({
-    Key? key,
-    this.initialIndex = 0,
-    this.onChanged,
-  }) : super(key: key);
-
-  final int initialIndex;
-  final void Function(int)? onChanged;
-
-  @override
-  State<SendReceiveTabMenu> createState() => _SendReceiveTabMenuState();
-}
-
-class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
-  late int _selectedIndex;
-
-  void _onChanged(int newIndex) {
-    if (_selectedIndex != newIndex) {
-      setState(() {
-        _selectedIndex = newIndex;
-      });
-      widget.onChanged?.call(_selectedIndex);
-    }
-  }
-
-  @override
-  void initState() {
-    _selectedIndex = widget.initialIndex;
-    super.initState();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return Row(
-      children: [
-        Expanded(
-          child: GestureDetector(
-            onTap: () => _onChanged(0),
-            child: Container(
-              color: Colors.transparent,
-              child: Column(
-                children: [
-                  const SizedBox(
-                    height: 16,
-                  ),
-                  Text(
-                    "Send",
-                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                      color: _selectedIndex == 0
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .textSubtitle1,
-                    ),
-                  ),
-                  const SizedBox(
-                    height: 19,
-                  ),
-                  Container(
-                    height: 2,
-                    decoration: BoxDecoration(
-                      color: _selectedIndex == 0
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .background,
-                    ),
-                  ),
-                ],
-              ),
-            ),
-          ),
-        ),
-        Expanded(
-          child: GestureDetector(
-            onTap: () => _onChanged(1),
-            child: Container(
-              color: Colors.transparent,
-              child: Column(
-                children: [
-                  const SizedBox(
-                    height: 16,
-                  ),
-                  Text(
-                    "Receive",
-                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                      color: _selectedIndex == 1
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .textSubtitle1,
-                    ),
-                  ),
-                  const SizedBox(
-                    height: 19,
-                  ),
-                  Container(
-                    height: 2,
-                    decoration: BoxDecoration(
-                      color: _selectedIndex == 1
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .background,
-                    ),
-                  ),
-                ],
-              ),
-            ),
-          ),
-        ),
-      ],
-    );
-  }
-}
-
-class RecentDesktopTransactions extends ConsumerStatefulWidget {
-  const RecentDesktopTransactions({
-    Key? key,
-    required this.walletId,
-  }) : super(key: key);
-
-  final String walletId;
-
-  @override
-  ConsumerState<RecentDesktopTransactions> createState() =>
-      _RecentDesktopTransactionsState();
-}
-
-class _RecentDesktopTransactionsState
-    extends ConsumerState<RecentDesktopTransactions> {
-  @override
-  Widget build(BuildContext context) {
-    return Column(
-      children: [
-        Row(
-          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-          children: [
-            Text(
-              "Recent transactions",
-              style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                color: Theme.of(context)
-                    .extension<StackColors>()!
-                    .textFieldActiveSearchIconLeft,
-              ),
-            ),
-            BlueTextButton(
-              text: "See all",
-              onTap: () {
-                Navigator.of(context).pushNamed(
-                  AllTransactionsView.routeName,
-                  arguments: widget.walletId,
-                );
-              },
-            ),
-          ],
-        ),
-        const SizedBox(
-          height: 16,
-        ),
-        Expanded(
-          child: TransactionsList(
-            managerProvider: ref.watch(walletsChangeNotifierProvider
-                .select((value) => value.getManagerProvider(widget.walletId))),
-            walletId: widget.walletId,
-          ),
-        ),
-      ],
-    );
-  }
-}
-
-class NetworkInfoButton extends ConsumerStatefulWidget {
-  const NetworkInfoButton({
-    Key? key,
-    required this.walletId,
-    this.eventBus,
-  }) : super(key: key);
-
-  final String walletId;
-  final EventBus? eventBus;
-
-  @override
-  ConsumerState<NetworkInfoButton> createState() => _NetworkInfoButtonState();
-}
-
-class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
-  late final String walletId;
-  late final EventBus eventBus;
-
-  late WalletSyncStatus _currentSyncStatus;
-  late NodeConnectionStatus _currentNodeStatus;
-
-  late StreamSubscription<dynamic> _syncStatusSubscription;
-  late StreamSubscription<dynamic> _nodeStatusSubscription;
-
-  @override
-  void initState() {
-    walletId = widget.walletId;
-    final managerProvider =
-        ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
-
-    eventBus =
-        widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
-
-    if (ref.read(managerProvider).isRefreshing) {
-      _currentSyncStatus = WalletSyncStatus.syncing;
-      _currentNodeStatus = NodeConnectionStatus.connected;
-    } else {
-      _currentSyncStatus = WalletSyncStatus.synced;
-      if (ref.read(managerProvider).isConnected) {
-        _currentNodeStatus = NodeConnectionStatus.connected;
-      } else {
-        _currentNodeStatus = NodeConnectionStatus.disconnected;
-        _currentSyncStatus = WalletSyncStatus.unableToSync;
-      }
-    }
-
-    _syncStatusSubscription =
-        eventBus.on<WalletSyncStatusChangedEvent>().listen(
-      (event) async {
-        if (event.walletId == widget.walletId) {
-          setState(() {
-            _currentSyncStatus = event.newStatus;
-          });
-        }
-      },
-    );
-
-    _nodeStatusSubscription =
-        eventBus.on<NodeConnectionStatusChangedEvent>().listen(
-      (event) async {
-        if (event.walletId == widget.walletId) {
-          setState(() {
-            _currentNodeStatus = event.newStatus;
-          });
-        }
-      },
-    );
-
-    super.initState();
-  }
-
-  @override
-  void dispose() {
-    _nodeStatusSubscription.cancel();
-    _syncStatusSubscription.cancel();
-    super.dispose();
-  }
-
-  Widget _buildNetworkIcon(WalletSyncStatus status, BuildContext context) {
-    const size = 24.0;
-    switch (status) {
-      case WalletSyncStatus.unableToSync:
-        return SvgPicture.asset(
-          Assets.svg.radioProblem,
-          color: Theme.of(context).extension<StackColors>()!.accentColorRed,
-          width: size,
-          height: size,
-        );
-      case WalletSyncStatus.synced:
-        return SvgPicture.asset(
-          Assets.svg.radio,
-          color: Theme.of(context).extension<StackColors>()!.accentColorGreen,
-          width: size,
-          height: size,
-        );
-      case WalletSyncStatus.syncing:
-        return SvgPicture.asset(
-          Assets.svg.radioSyncing,
-          color: Theme.of(context).extension<StackColors>()!.accentColorYellow,
-          width: size,
-          height: size,
-        );
-    }
-  }
-
-  Widget _buildText(WalletSyncStatus status, BuildContext context) {
-    String label;
-    Color color;
-
-    switch (status) {
-      case WalletSyncStatus.unableToSync:
-        label = "Unable to sync";
-        color = Theme.of(context).extension<StackColors>()!.accentColorRed;
-        break;
-      case WalletSyncStatus.synced:
-        label = "Synchronised";
-        color = Theme.of(context).extension<StackColors>()!.accentColorGreen;
-        break;
-      case WalletSyncStatus.syncing:
-        label = "Synchronising";
-        color = Theme.of(context).extension<StackColors>()!.accentColorYellow;
-        break;
-    }
-
-    return Text(
-      label,
-      style: STextStyles.desktopMenuItemSelected(context).copyWith(
-        color: color,
-      ),
-    );
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return GestureDetector(
-      onTap: () {
-        Navigator.of(context).pushNamed(
-          WalletNetworkSettingsView.routeName,
-          arguments: Tuple3(
-            walletId,
-            _currentSyncStatus,
-            _currentNodeStatus,
-          ),
-        );
-      },
-      child: Container(
-        color: Colors.transparent,
-        child: Row(
-          children: [
-            _buildNetworkIcon(_currentSyncStatus, context),
-            const SizedBox(
-              width: 6,
-            ),
-            _buildText(_currentSyncStatus, context),
-          ],
-        ),
-      ),
-    );
-  }
-}
-
-class WalletKeysButton extends StatelessWidget {
-  const WalletKeysButton({
-    Key? key,
-    required this.walletId,
-  }) : super(key: key);
-
-  final String walletId;
-
-  @override
-  Widget build(BuildContext context) {
-    return GestureDetector(
-      onTap: () {
-        showDialog<void>(
-          context: context,
-          barrierDismissible: false,
-          builder: (context) => UnlockWalletKeysDesktop(
-            walletId: walletId,
-          ),
-        );
-      },
-      child: Container(
-        color: Colors.transparent,
-        child: Row(
-          children: [
-            SvgPicture.asset(
-              Assets.svg.key,
-              width: 20,
-              height: 20,
-              color: Theme.of(context)
-                  .extension<StackColors>()!
-                  .buttonTextSecondary,
-            ),
-            const SizedBox(
-              width: 6,
-            ),
-            Text(
-              "Wallet keys",
-              style: STextStyles.desktopMenuItemSelected(context),
-            )
-          ],
-        ),
-      ),
-    );
-  }
-}
-
-class UnlockWalletKeysDesktop extends ConsumerStatefulWidget {
-  const UnlockWalletKeysDesktop({
-    Key? key,
-    required this.walletId,
-  }) : super(key: key);
-
-  final String walletId;
-
-  @override
-  ConsumerState<UnlockWalletKeysDesktop> createState() =>
-      _UnlockWalletKeysDesktopState();
-}
-
-class _UnlockWalletKeysDesktopState
-    extends ConsumerState<UnlockWalletKeysDesktop> {
-  late final TextEditingController passwordController;
-
-  late final FocusNode passwordFocusNode;
-
-  bool continueEnabled = false;
-  bool hidePassword = true;
-
-  @override
-  void initState() {
-    passwordController = TextEditingController();
-    passwordFocusNode = FocusNode();
-    super.initState();
-  }
-
-  @override
-  void dispose() {
-    passwordController.dispose();
-    passwordFocusNode.dispose();
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return DesktopDialog(
-      maxWidth: 579,
-      maxHeight: double.infinity,
-      child: Column(
-        children: [
-          Row(
-            mainAxisAlignment: MainAxisAlignment.end,
-            children: const [
-              DesktopDialogCloseButton(),
-            ],
-          ),
-          const SizedBox(
-            height: 12,
-          ),
-          SvgPicture.asset(
-            Assets.svg.keys,
-            width: 100,
-            height: 58,
-          ),
-          const SizedBox(
-            height: 55,
-          ),
-          Text(
-            "Wallet keys",
-            style: STextStyles.desktopH2(context),
-          ),
-          const SizedBox(
-            height: 16,
-          ),
-          Text(
-            "Enter your password",
-            style: STextStyles.desktopTextMedium(context).copyWith(
-              color: Theme.of(context).extension<StackColors>()!.textDark3,
-            ),
-          ),
-          const SizedBox(
-            height: 24,
-          ),
-          Padding(
-            padding: const EdgeInsets.symmetric(
-              horizontal: 32,
-            ),
-            child: ClipRRect(
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-              child: TextField(
-                key: const Key("enterPasswordUnlockWalletKeysDesktopFieldKey"),
-                focusNode: passwordFocusNode,
-                controller: passwordController,
-                style: STextStyles.desktopTextMedium(context).copyWith(
-                  height: 2,
-                ),
-                obscureText: hidePassword,
-                enableSuggestions: false,
-                autocorrect: false,
-                decoration: standardInputDecoration(
-                  "Enter password",
-                  passwordFocusNode,
-                  context,
-                ).copyWith(
-                  suffixIcon: UnconstrainedBox(
-                    child: SizedBox(
-                      height: 70,
-                      child: Row(
-                        children: [
-                          GestureDetector(
-                            key: const Key(
-                                "enterUnlockWalletKeysDesktopFieldShowPasswordButtonKey"),
-                            onTap: () async {
-                              setState(() {
-                                hidePassword = !hidePassword;
-                              });
-                            },
-                            child: Container(
-                              decoration: BoxDecoration(
-                                color: Colors.transparent,
-                                borderRadius: BorderRadius.circular(1000),
-                              ),
-                              height: 32,
-                              width: 32,
-                              child: Center(
-                                child: SvgPicture.asset(
-                                  hidePassword
-                                      ? Assets.svg.eye
-                                      : Assets.svg.eyeSlash,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark3,
-                                  width: 24,
-                                  height: 19,
-                                ),
-                              ),
-                            ),
-                          ),
-                          const SizedBox(
-                            width: 10,
-                          ),
-                        ],
-                      ),
-                    ),
-                  ),
-                ),
-                onChanged: (newValue) {
-                  setState(() {
-                    continueEnabled = newValue.isNotEmpty;
-                  });
-                },
-              ),
-            ),
-          ),
-          const SizedBox(
-            height: 55,
-          ),
-          Padding(
-            padding: const EdgeInsets.symmetric(
-              horizontal: 32,
-            ),
-            child: Row(
-              children: [
-                Expanded(
-                  child: SecondaryButton(
-                    label: "Cancel",
-                    onPressed: Navigator.of(context).pop,
-                  ),
-                ),
-                const SizedBox(
-                  width: 16,
-                ),
-                Expanded(
-                  child: PrimaryButton(
-                    label: "Continue",
-                    enabled: continueEnabled,
-                    onPressed: continueEnabled
-                        ? () async {
-                            // todo: check password
-                            Navigator.of(context).pop();
-                            final words = await ref
-                                .read(walletsChangeNotifierProvider)
-                                .getManager(widget.walletId)
-                                .mnemonic;
-                            await showDialog<void>(
-                              context: context,
-                              barrierDismissible: false,
-                              builder: (context) => Navigator(
-                                initialRoute: WalletKeysDesktopPopup.routeName,
-                                onGenerateRoute: RouteGenerator.generateRoute,
-                                onGenerateInitialRoutes: (_, __) {
-                                  return [
-                                    RouteGenerator.generateRoute(
-                                      RouteSettings(
-                                        name: WalletKeysDesktopPopup.routeName,
-                                        arguments: words,
-                                      ),
-                                    )
-                                  ];
-                                },
-                              ),
-                            );
-                          }
-                        : null,
-                  ),
-                ),
-              ],
-            ),
-          ),
-          const SizedBox(
-            height: 32,
-          ),
-        ],
-      ),
-    );
-  }
-}
-
-class WalletKeysDesktopPopup extends StatelessWidget {
-  const WalletKeysDesktopPopup({
-    Key? key,
-    required this.words,
-    this.clipboardInterface = const ClipboardWrapper(),
-  }) : super(key: key);
-
-  final List<String> words;
-  final ClipboardInterface clipboardInterface;
-
-  static const String routeName = "walletKeysDesktopPopup";
-
-  @override
-  Widget build(BuildContext context) {
-    return DesktopDialog(
-      maxWidth: 614,
-      maxHeight: double.infinity,
-      child: Column(
-        children: [
-          Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            children: [
-              Padding(
-                padding: const EdgeInsets.only(
-                  left: 32,
-                ),
-                child: Text(
-                  "Wallet keys",
-                  style: STextStyles.desktopH3(context),
-                ),
-              ),
-              DesktopDialogCloseButton(
-                onPressedOverride: () {
-                  Navigator.of(context, rootNavigator: true).pop();
-                },
-              ),
-            ],
-          ),
-          const SizedBox(
-            height: 28,
-          ),
-          Text(
-            "Recovery phrase",
-            style: STextStyles.desktopTextMedium(context),
-          ),
-          const SizedBox(
-            height: 8,
-          ),
-          Center(
-            child: Padding(
-              padding: const EdgeInsets.symmetric(
-                horizontal: 32,
-              ),
-              child: Text(
-                "Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
-                style: STextStyles.desktopTextExtraExtraSmall(context),
-                textAlign: TextAlign.center,
-              ),
-            ),
-          ),
-          const SizedBox(
-            height: 24,
-          ),
-          Padding(
-            padding: const EdgeInsets.symmetric(
-              horizontal: 32,
-            ),
-            child: MnemonicTable(
-              words: words,
-              isDesktop: true,
-              itemBorderColor: Theme.of(context)
-                  .extension<StackColors>()!
-                  .buttonBackSecondary,
-            ),
-          ),
-          const SizedBox(
-            height: 24,
-          ),
-          Padding(
-            padding: const EdgeInsets.symmetric(
-              horizontal: 32,
-            ),
-            child: Row(
-              children: [
-                Expanded(
-                  child: SecondaryButton(
-                    label: "Show QR code",
-                    onPressed: () {
-                      final String value = AddressUtils.encodeQRSeedData(words);
-                      Navigator.of(context).pushNamed(
-                        QRCodeDesktopPopupContent.routeName,
-                        arguments: value,
-                      );
-                    },
-                  ),
-                ),
-                const SizedBox(
-                  width: 16,
-                ),
-                Expanded(
-                  child: PrimaryButton(
-                    label: "Copy",
-                    onPressed: () async {
-                      await clipboardInterface.setData(
-                        ClipboardData(text: words.join(" ")),
-                      );
-                      unawaited(
-                        showFloatingFlushBar(
-                          type: FlushBarType.info,
-                          message: "Copied to clipboard",
-                          iconAsset: Assets.svg.copy,
-                          context: context,
-                        ),
-                      );
-                    },
-                  ),
-                ),
-              ],
-            ),
-          ),
-          const SizedBox(
-            height: 32,
-          ),
-        ],
-      ),
-    );
-  }
-}
-
-class QRCodeDesktopPopupContent extends StatelessWidget {
-  const QRCodeDesktopPopupContent({
-    Key? key,
-    required this.value,
-  }) : super(key: key);
-
-  final String value;
-
-  static const String routeName = "qrCodeDesktopPopupContent";
-
-  @override
-  Widget build(BuildContext context) {
-    return DesktopDialog(
-      maxWidth: 614,
-      child: Column(
-        children: [
-          Row(
-            mainAxisAlignment: MainAxisAlignment.end,
-            children: const [
-              DesktopDialogCloseButton(),
-            ],
-          ),
-          const SizedBox(
-            height: 14,
-          ),
-          QrImage(
-            data: value,
-            size: 300,
-            foregroundColor:
-                Theme.of(context).extension<StackColors>()!.accentColorDark,
-          ),
-        ],
-      ),
-    );
-  }
-}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
similarity index 100%
rename from lib/pages_desktop_specific/home/my_stack_view/wallet_view/receive/desktop_receive.dart
rename to lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
similarity index 100%
rename from lib/pages_desktop_specific/home/my_stack_view/wallet_view/send/desktop_send.dart
rename to lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
similarity index 100%
rename from lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_summary.dart
rename to lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/my_wallet.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/my_wallet.dart
new file mode 100644
index 000000000..82b1f6ee7
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/my_wallet.dart
@@ -0,0 +1,89 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+
+class MyWallet extends StatefulWidget {
+  const MyWallet({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  @override
+  State<MyWallet> createState() => _MyWalletState();
+}
+
+class _MyWalletState extends State<MyWallet> {
+  int _selectedIndex = 0;
+
+  @override
+  Widget build(BuildContext context) {
+    return ListView(
+      primary: false,
+      children: [
+        Text(
+          "My wallet",
+          style: STextStyles.desktopTextExtraSmall(context).copyWith(
+            color: Theme.of(context)
+                .extension<StackColors>()!
+                .textFieldActiveSearchIconLeft,
+          ),
+        ),
+        const SizedBox(
+          height: 16,
+        ),
+        Container(
+          decoration: BoxDecoration(
+            color: Theme.of(context).extension<StackColors>()!.popupBG,
+            borderRadius: BorderRadius.vertical(
+              top: Radius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+            ),
+          ),
+          child: SendReceiveTabMenu(
+            onChanged: (index) {
+              setState(() {
+                _selectedIndex = index;
+              });
+            },
+          ),
+        ),
+        Container(
+          decoration: BoxDecoration(
+            color: Theme.of(context).extension<StackColors>()!.popupBG,
+            borderRadius: BorderRadius.vertical(
+              bottom: Radius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+            ),
+          ),
+          child: IndexedStack(
+            index: _selectedIndex,
+            children: [
+              Padding(
+                key: const Key("desktopSendViewPortKey"),
+                padding: const EdgeInsets.all(20),
+                child: DesktopSend(
+                  walletId: widget.walletId,
+                ),
+              ),
+              Padding(
+                key: const Key("desktopReceiveViewPortKey"),
+                padding: const EdgeInsets.all(20),
+                child: DesktopReceive(
+                  walletId: widget.walletId,
+                ),
+              ),
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
new file mode 100644
index 000000000..830b5e667
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
@@ -0,0 +1,176 @@
+import 'dart:async';
+
+import 'package:event_bus/event_bus.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
+import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_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/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:tuple/tuple.dart';
+
+class NetworkInfoButton extends ConsumerStatefulWidget {
+  const NetworkInfoButton({
+    Key? key,
+    required this.walletId,
+    this.eventBus,
+  }) : super(key: key);
+
+  final String walletId;
+  final EventBus? eventBus;
+
+  @override
+  ConsumerState<NetworkInfoButton> createState() => _NetworkInfoButtonState();
+}
+
+class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
+  late final String walletId;
+  late final EventBus eventBus;
+
+  late WalletSyncStatus _currentSyncStatus;
+  late NodeConnectionStatus _currentNodeStatus;
+
+  late StreamSubscription<dynamic> _syncStatusSubscription;
+  late StreamSubscription<dynamic> _nodeStatusSubscription;
+
+  @override
+  void initState() {
+    walletId = widget.walletId;
+    final managerProvider =
+        ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
+
+    eventBus =
+        widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
+
+    if (ref.read(managerProvider).isRefreshing) {
+      _currentSyncStatus = WalletSyncStatus.syncing;
+      _currentNodeStatus = NodeConnectionStatus.connected;
+    } else {
+      _currentSyncStatus = WalletSyncStatus.synced;
+      if (ref.read(managerProvider).isConnected) {
+        _currentNodeStatus = NodeConnectionStatus.connected;
+      } else {
+        _currentNodeStatus = NodeConnectionStatus.disconnected;
+        _currentSyncStatus = WalletSyncStatus.unableToSync;
+      }
+    }
+
+    _syncStatusSubscription =
+        eventBus.on<WalletSyncStatusChangedEvent>().listen(
+      (event) async {
+        if (event.walletId == widget.walletId) {
+          setState(() {
+            _currentSyncStatus = event.newStatus;
+          });
+        }
+      },
+    );
+
+    _nodeStatusSubscription =
+        eventBus.on<NodeConnectionStatusChangedEvent>().listen(
+      (event) async {
+        if (event.walletId == widget.walletId) {
+          setState(() {
+            _currentNodeStatus = event.newStatus;
+          });
+        }
+      },
+    );
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _nodeStatusSubscription.cancel();
+    _syncStatusSubscription.cancel();
+    super.dispose();
+  }
+
+  Widget _buildNetworkIcon(WalletSyncStatus status, BuildContext context) {
+    const size = 24.0;
+    switch (status) {
+      case WalletSyncStatus.unableToSync:
+        return SvgPicture.asset(
+          Assets.svg.radioProblem,
+          color: Theme.of(context).extension<StackColors>()!.accentColorRed,
+          width: size,
+          height: size,
+        );
+      case WalletSyncStatus.synced:
+        return SvgPicture.asset(
+          Assets.svg.radio,
+          color: Theme.of(context).extension<StackColors>()!.accentColorGreen,
+          width: size,
+          height: size,
+        );
+      case WalletSyncStatus.syncing:
+        return SvgPicture.asset(
+          Assets.svg.radioSyncing,
+          color: Theme.of(context).extension<StackColors>()!.accentColorYellow,
+          width: size,
+          height: size,
+        );
+    }
+  }
+
+  Widget _buildText(WalletSyncStatus status, BuildContext context) {
+    String label;
+    Color color;
+
+    switch (status) {
+      case WalletSyncStatus.unableToSync:
+        label = "Unable to sync";
+        color = Theme.of(context).extension<StackColors>()!.accentColorRed;
+        break;
+      case WalletSyncStatus.synced:
+        label = "Synchronised";
+        color = Theme.of(context).extension<StackColors>()!.accentColorGreen;
+        break;
+      case WalletSyncStatus.syncing:
+        label = "Synchronising";
+        color = Theme.of(context).extension<StackColors>()!.accentColorYellow;
+        break;
+    }
+
+    return Text(
+      label,
+      style: STextStyles.desktopMenuItemSelected(context).copyWith(
+        color: color,
+      ),
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return GestureDetector(
+      onTap: () {
+        Navigator.of(context).pushNamed(
+          WalletNetworkSettingsView.routeName,
+          arguments: Tuple3(
+            walletId,
+            _currentSyncStatus,
+            _currentNodeStatus,
+          ),
+        );
+      },
+      child: Container(
+        color: Colors.transparent,
+        child: Row(
+          children: [
+            _buildNetworkIcon(_currentSyncStatus, context),
+            const SizedBox(
+              width: 6,
+            ),
+            _buildText(_currentSyncStatus, context),
+          ],
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart
new file mode 100644
index 000000000..3a7a94885
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart
@@ -0,0 +1,42 @@
+import 'package:flutter/material.dart';
+import 'package:qr_flutter/qr_flutter.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+
+class QRCodeDesktopPopupContent extends StatelessWidget {
+  const QRCodeDesktopPopupContent({
+    Key? key,
+    required this.value,
+  }) : super(key: key);
+
+  final String value;
+
+  static const String routeName = "qrCodeDesktopPopupContent";
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 614,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.end,
+            children: const [
+              DesktopDialogCloseButton(),
+            ],
+          ),
+          const SizedBox(
+            height: 14,
+          ),
+          QrImage(
+            data: value,
+            size: 300,
+            foregroundColor:
+                Theme.of(context).extension<StackColors>()!.accentColorDark,
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart
new file mode 100644
index 000000000..59e01f0b7
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/recent_desktop_transactions.dart
@@ -0,0 +1,64 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart';
+import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart';
+import 'package:stackwallet/providers/providers.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';
+
+class RecentDesktopTransactions extends ConsumerStatefulWidget {
+  const RecentDesktopTransactions({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  @override
+  ConsumerState<RecentDesktopTransactions> createState() =>
+      _RecentDesktopTransactionsState();
+}
+
+class _RecentDesktopTransactionsState
+    extends ConsumerState<RecentDesktopTransactions> {
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: [
+            Text(
+              "Recent transactions",
+              style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldActiveSearchIconLeft,
+              ),
+            ),
+            BlueTextButton(
+              text: "See all",
+              onTap: () {
+                Navigator.of(context).pushNamed(
+                  AllTransactionsView.routeName,
+                  arguments: widget.walletId,
+                );
+              },
+            ),
+          ],
+        ),
+        const SizedBox(
+          height: 16,
+        ),
+        Expanded(
+          child: TransactionsList(
+            managerProvider: ref.watch(walletsChangeNotifierProvider
+                .select((value) => value.getManagerProvider(widget.walletId))),
+            walletId: widget.walletId,
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart
new file mode 100644
index 000000000..54dca9a4c
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart
@@ -0,0 +1,128 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+
+class SendReceiveTabMenu extends StatefulWidget {
+  const SendReceiveTabMenu({
+    Key? key,
+    this.initialIndex = 0,
+    this.onChanged,
+  }) : super(key: key);
+
+  final int initialIndex;
+  final void Function(int)? onChanged;
+
+  @override
+  State<SendReceiveTabMenu> createState() => _SendReceiveTabMenuState();
+}
+
+class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
+  late int _selectedIndex;
+
+  void _onChanged(int newIndex) {
+    if (_selectedIndex != newIndex) {
+      setState(() {
+        _selectedIndex = newIndex;
+      });
+      widget.onChanged?.call(_selectedIndex);
+    }
+  }
+
+  @override
+  void initState() {
+    _selectedIndex = widget.initialIndex;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      children: [
+        Expanded(
+          child: GestureDetector(
+            onTap: () => _onChanged(0),
+            child: Container(
+              color: Colors.transparent,
+              child: Column(
+                children: [
+                  const SizedBox(
+                    height: 16,
+                  ),
+                  Text(
+                    "Send",
+                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color: _selectedIndex == 0
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .textSubtitle1,
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 19,
+                  ),
+                  Container(
+                    height: 2,
+                    decoration: BoxDecoration(
+                      color: _selectedIndex == 0
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                    ),
+                  ),
+                ],
+              ),
+            ),
+          ),
+        ),
+        Expanded(
+          child: GestureDetector(
+            onTap: () => _onChanged(1),
+            child: Container(
+              color: Colors.transparent,
+              child: Column(
+                children: [
+                  const SizedBox(
+                    height: 16,
+                  ),
+                  Text(
+                    "Receive",
+                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color: _selectedIndex == 1
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .textSubtitle1,
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 19,
+                  ),
+                  Container(
+                    height: 2,
+                    decoration: BoxDecoration(
+                      color: _selectedIndex == 1
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorBlue
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                    ),
+                  ),
+                ],
+              ),
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
new file mode 100644
index 000000000..37f047eed
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
@@ -0,0 +1,228 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
+import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/route_generator.dart';
+import 'package:stackwallet/utilities/assets.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/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+
+class UnlockWalletKeysDesktop extends ConsumerStatefulWidget {
+  const UnlockWalletKeysDesktop({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  @override
+  ConsumerState<UnlockWalletKeysDesktop> createState() =>
+      _UnlockWalletKeysDesktopState();
+}
+
+class _UnlockWalletKeysDesktopState
+    extends ConsumerState<UnlockWalletKeysDesktop> {
+  late final TextEditingController passwordController;
+
+  late final FocusNode passwordFocusNode;
+
+  bool continueEnabled = false;
+  bool hidePassword = true;
+
+  @override
+  void initState() {
+    passwordController = TextEditingController();
+    passwordFocusNode = FocusNode();
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    passwordController.dispose();
+    passwordFocusNode.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 579,
+      maxHeight: double.infinity,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.end,
+            children: const [
+              DesktopDialogCloseButton(),
+            ],
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          SvgPicture.asset(
+            Assets.svg.keys,
+            width: 100,
+            height: 58,
+          ),
+          const SizedBox(
+            height: 55,
+          ),
+          Text(
+            "Wallet keys",
+            style: STextStyles.desktopH2(context),
+          ),
+          const SizedBox(
+            height: 16,
+          ),
+          Text(
+            "Enter your password",
+            style: STextStyles.desktopTextMedium(context).copyWith(
+              color: Theme.of(context).extension<StackColors>()!.textDark3,
+            ),
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                key: const Key("enterPasswordUnlockWalletKeysDesktopFieldKey"),
+                focusNode: passwordFocusNode,
+                controller: passwordController,
+                style: STextStyles.desktopTextMedium(context).copyWith(
+                  height: 2,
+                ),
+                obscureText: hidePassword,
+                enableSuggestions: false,
+                autocorrect: false,
+                decoration: standardInputDecoration(
+                  "Enter password",
+                  passwordFocusNode,
+                  context,
+                ).copyWith(
+                  suffixIcon: UnconstrainedBox(
+                    child: SizedBox(
+                      height: 70,
+                      child: Row(
+                        children: [
+                          GestureDetector(
+                            key: const Key(
+                                "enterUnlockWalletKeysDesktopFieldShowPasswordButtonKey"),
+                            onTap: () async {
+                              setState(() {
+                                hidePassword = !hidePassword;
+                              });
+                            },
+                            child: Container(
+                              decoration: BoxDecoration(
+                                color: Colors.transparent,
+                                borderRadius: BorderRadius.circular(1000),
+                              ),
+                              height: 32,
+                              width: 32,
+                              child: Center(
+                                child: SvgPicture.asset(
+                                  hidePassword
+                                      ? Assets.svg.eye
+                                      : Assets.svg.eyeSlash,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark3,
+                                  width: 24,
+                                  height: 19,
+                                ),
+                              ),
+                            ),
+                          ),
+                          const SizedBox(
+                            width: 10,
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                onChanged: (newValue) {
+                  setState(() {
+                    continueEnabled = newValue.isNotEmpty;
+                  });
+                },
+              ),
+            ),
+          ),
+          const SizedBox(
+            height: 55,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    onPressed: Navigator.of(context).pop,
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Continue",
+                    enabled: continueEnabled,
+                    onPressed: continueEnabled
+                        ? () async {
+                            // todo: check password
+                            Navigator.of(context).pop();
+                            final words = await ref
+                                .read(walletsChangeNotifierProvider)
+                                .getManager(widget.walletId)
+                                .mnemonic;
+                            await showDialog<void>(
+                              context: context,
+                              barrierDismissible: false,
+                              builder: (context) => Navigator(
+                                initialRoute: WalletKeysDesktopPopup.routeName,
+                                onGenerateRoute: RouteGenerator.generateRoute,
+                                onGenerateInitialRoutes: (_, __) {
+                                  return [
+                                    RouteGenerator.generateRoute(
+                                      RouteSettings(
+                                        name: WalletKeysDesktopPopup.routeName,
+                                        arguments: words,
+                                      ),
+                                    )
+                                  ];
+                                },
+                              ),
+                            );
+                          }
+                        : null,
+                  ),
+                ),
+              ],
+            ),
+          ),
+          const SizedBox(
+            height: 32,
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
new file mode 100644
index 000000000..d4921276d
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
@@ -0,0 +1,52 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+
+class WalletKeysButton extends StatelessWidget {
+  const WalletKeysButton({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  @override
+  Widget build(BuildContext context) {
+    return GestureDetector(
+      onTap: () {
+        showDialog<void>(
+          context: context,
+          barrierDismissible: false,
+          builder: (context) => UnlockWalletKeysDesktop(
+            walletId: walletId,
+          ),
+        );
+      },
+      child: Container(
+        color: Colors.transparent,
+        child: Row(
+          children: [
+            SvgPicture.asset(
+              Assets.svg.key,
+              width: 20,
+              height: 20,
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .buttonTextSecondary,
+            ),
+            const SizedBox(
+              width: 6,
+            ),
+            Text(
+              "Wallet keys",
+              style: STextStyles.desktopMenuItemSelected(context),
+            )
+          ],
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart
new file mode 100644
index 000000000..1ed646b30
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart
@@ -0,0 +1,146 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.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/flush_bar_type.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+class WalletKeysDesktopPopup extends StatelessWidget {
+  const WalletKeysDesktopPopup({
+    Key? key,
+    required this.words,
+    this.clipboardInterface = const ClipboardWrapper(),
+  }) : super(key: key);
+
+  final List<String> words;
+  final ClipboardInterface clipboardInterface;
+
+  static const String routeName = "walletKeysDesktopPopup";
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 614,
+      maxHeight: double.infinity,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.only(
+                  left: 32,
+                ),
+                child: Text(
+                  "Wallet keys",
+                  style: STextStyles.desktopH3(context),
+                ),
+              ),
+              DesktopDialogCloseButton(
+                onPressedOverride: () {
+                  Navigator.of(context, rootNavigator: true).pop();
+                },
+              ),
+            ],
+          ),
+          const SizedBox(
+            height: 28,
+          ),
+          Text(
+            "Recovery phrase",
+            style: STextStyles.desktopTextMedium(context),
+          ),
+          const SizedBox(
+            height: 8,
+          ),
+          Center(
+            child: Padding(
+              padding: const EdgeInsets.symmetric(
+                horizontal: 32,
+              ),
+              child: Text(
+                "Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
+                style: STextStyles.desktopTextExtraExtraSmall(context),
+                textAlign: TextAlign.center,
+              ),
+            ),
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: MnemonicTable(
+              words: words,
+              isDesktop: true,
+              itemBorderColor: Theme.of(context)
+                  .extension<StackColors>()!
+                  .buttonBackSecondary,
+            ),
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Show QR code",
+                    onPressed: () {
+                      final String value = AddressUtils.encodeQRSeedData(words);
+                      Navigator.of(context).pushNamed(
+                        QRCodeDesktopPopupContent.routeName,
+                        arguments: value,
+                      );
+                    },
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Copy",
+                    onPressed: () async {
+                      await clipboardInterface.setData(
+                        ClipboardData(text: words.join(" ")),
+                      );
+                      unawaited(
+                        showFloatingFlushBar(
+                          type: FlushBarType.info,
+                          message: "Copied to clipboard",
+                          iconAsset: Assets.svg.copy,
+                          context: context,
+                        ),
+                      );
+                    },
+                  ),
+                ),
+              ],
+            ),
+          ),
+          const SizedBox(
+            height: 32,
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 202edd972..5d0f81e20 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -87,6 +87,8 @@ import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';

From bf9eb66cb453314d97bda48bc6302494099d26e8 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 31 Oct 2022 08:28:19 -0600
Subject: [PATCH 077/426] test fixes

---
 test/price_test.dart | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/test/price_test.dart b/test/price_test.dart
index 0dbcdd450..89300122e 100644
--- a/test/price_test.dart
+++ b/test/price_test.dart
@@ -39,7 +39,7 @@ void main() {
     final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
 
     expect(price.toString(),
-        '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
+        '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.litecoin: [0, 0.0], Coin.monero: [0.00717236, -0.77656], Coin.namecoin: [0, 0.0], Coin.wownero: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
     verify(client.get(
         Uri.parse(
             "https://api.coingecko.com/api/v3/coins/markets?vs_currency=btc&ids=monero,bitcoin,litecoin,epic-cash,zcoin,dogecoin,bitcoin-cash,namecoin,wownero&order=market_cap_desc&per_page=10&page=1&sparkline=false"),
@@ -71,7 +71,7 @@ void main() {
         await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
 
     expect(cachedPrice.toString(),
-        '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.monero: [0.00717236, -0.77656], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
+        '{Coin.bitcoin: [1, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0.00000315, -2.68533], Coin.epicCash: [0.00002803, 7.27524], Coin.firo: [0.0001096, -0.89304], Coin.litecoin: [0, 0.0], Coin.monero: [0.00717236, -0.77656], Coin.namecoin: [0, 0.0], Coin.wownero: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
 
     // verify only called once during filling of cache
     verify(client.get(
@@ -100,7 +100,7 @@ void main() {
     final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
 
     expect(price.toString(),
-        '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
+        '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.monero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.wownero: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
   });
 
   test("no internet available", () async {
@@ -120,7 +120,7 @@ void main() {
     final price = await priceAPI.getPricesAnd24hChange(baseCurrency: "btc");
 
     expect(price.toString(),
-        '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.monero: [0, 0.0], Coin.wownero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
+        '{Coin.bitcoin: [0, 0.0], Coin.bitcoincash: [0, 0.0], Coin.dogecoin: [0, 0.0], Coin.epicCash: [0, 0.0], Coin.firo: [0, 0.0], Coin.litecoin: [0, 0.0], Coin.monero: [0, 0.0], Coin.namecoin: [0, 0.0], Coin.wownero: [0, 0.0], Coin.bitcoinTestNet: [0, 0.0], Coin.litecoinTestNet: [0, 0.0], Coin.bitcoincashTestnet: [0, 0.0], Coin.dogecoinTestNet: [0, 0.0], Coin.firoTestNet: [0, 0.0]}');
   });
 
   tearDown(() async {

From b3b8d0b057e97b14fef382bc75c9da0ab91f23e5 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 31 Oct 2022 09:45:42 -0600
Subject: [PATCH 078/426] added more customization options to AppBarBackButton

---
 .../custom_buttons/app_bar_icon_button.dart   | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/lib/widgets/custom_buttons/app_bar_icon_button.dart b/lib/widgets/custom_buttons/app_bar_icon_button.dart
index eb926112a..9edc1ca5f 100644
--- a/lib/widgets/custom_buttons/app_bar_icon_button.dart
+++ b/lib/widgets/custom_buttons/app_bar_icon_button.dart
@@ -51,10 +51,14 @@ class AppBarBackButton extends StatelessWidget {
     Key? key,
     this.onPressed,
     this.isCompact = false,
+    this.size,
+    this.iconSize,
   }) : super(key: key);
 
   final VoidCallback? onPressed;
   final bool isCompact;
+  final double? size;
+  final double? iconSize;
 
   @override
   Widget build(BuildContext context) {
@@ -67,19 +71,20 @@ class AppBarBackButton extends StatelessWidget {
             )
           : const EdgeInsets.all(10),
       child: AppBarIconButton(
-        size: isDesktop
-            ? isCompact
-                ? 42
-                : 56
-            : 32,
+        size: size ??
+            (isDesktop
+                ? isCompact
+                    ? 42
+                    : 56
+                : 32),
         color: isDesktop
             ? Theme.of(context).extension<StackColors>()!.textFieldDefaultBG
             : Theme.of(context).extension<StackColors>()!.background,
         shadows: const [],
         icon: SvgPicture.asset(
           Assets.svg.arrowLeft,
-          width: isCompact ? 18 : 24,
-          height: isCompact ? 18 : 24,
+          width: iconSize ?? (isCompact ? 18 : 24),
+          height: iconSize ?? (isCompact ? 18 : 24),
           color: Theme.of(context).extension<StackColors>()!.topNavIconPrimary,
         ),
         onPressed: onPressed ?? Navigator.of(context).pop,

From 817460b5e1289d5335d28dc09b39a82a3fdafcde Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 31 Oct 2022 11:32:22 -0600
Subject: [PATCH 079/426] proper conditional parent widget class to handle some
 desktop/mobile differences in a cleaner manner

---
 lib/widgets/conditional_parent.dart | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 lib/widgets/conditional_parent.dart

diff --git a/lib/widgets/conditional_parent.dart b/lib/widgets/conditional_parent.dart
new file mode 100644
index 000000000..6db50c6e8
--- /dev/null
+++ b/lib/widgets/conditional_parent.dart
@@ -0,0 +1,23 @@
+import 'package:flutter/material.dart';
+
+class ConditionalParent extends StatelessWidget {
+  const ConditionalParent({
+    Key? key,
+    required this.condition,
+    required this.child,
+    required this.builder,
+  }) : super(key: key);
+
+  final bool condition;
+  final Widget child;
+  final Widget Function(Widget) builder;
+
+  @override
+  Widget build(BuildContext context) {
+    if (condition) {
+      return builder(child);
+    } else {
+      return child;
+    }
+  }
+}

From 3421602ba2c26c67655d1b20ac37b9a4df8b774e Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 31 Oct 2022 11:51:16 -0600
Subject: [PATCH 080/426] manually toggleable expandable mod

---
 lib/widgets/expandable.dart | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/lib/widgets/expandable.dart b/lib/widgets/expandable.dart
index ddae2201d..a0c2be5a4 100644
--- a/lib/widgets/expandable.dart
+++ b/lib/widgets/expandable.dart
@@ -5,6 +5,11 @@ enum ExpandableState {
   collapsed,
 }
 
+class ExpandableController {
+  VoidCallback? toggle;
+  ExpandableState state = ExpandableState.collapsed;
+}
+
 class Expandable extends StatefulWidget {
   const Expandable({
     Key? key,
@@ -14,6 +19,7 @@ class Expandable extends StatefulWidget {
     this.animation,
     this.animationDurationMultiplier = 1.0,
     this.onExpandChanged,
+    this.controller,
   }) : super(key: key);
 
   final Widget header;
@@ -22,6 +28,7 @@ class Expandable extends StatefulWidget {
   final Animation<double>? animation;
   final double animationDurationMultiplier;
   final void Function(ExpandableState)? onExpandChanged;
+  final ExpandableController? controller;
 
   @override
   State<Expandable> createState() => _ExpandableState();
@@ -31,19 +38,28 @@ class _ExpandableState extends State<Expandable> with TickerProviderStateMixin {
   late final AnimationController animationController;
   late final Animation<double> animation;
   late final Duration duration;
+  late final ExpandableController? controller;
+
+  ExpandableState _toggleState = ExpandableState.collapsed;
 
   Future<void> toggle() async {
     if (animation.isDismissed) {
       await animationController.forward();
-      widget.onExpandChanged?.call(ExpandableState.collapsed);
+      _toggleState = ExpandableState.collapsed;
+      widget.onExpandChanged?.call(_toggleState);
     } else if (animation.isCompleted) {
       await animationController.reverse();
-      widget.onExpandChanged?.call(ExpandableState.expanded);
+      _toggleState = ExpandableState.expanded;
+      widget.onExpandChanged?.call(_toggleState);
     }
+    controller?.state = _toggleState;
   }
 
   @override
   void initState() {
+    controller = widget.controller;
+    controller?.toggle = toggle;
+
     duration = Duration(
       milliseconds: (500 * widget.animationDurationMultiplier).toInt(),
     );

From 7540e593a3f9066cab2ab8e0f197c8eccda07d5c Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 31 Oct 2022 12:03:21 -0600
Subject: [PATCH 081/426] desktop receiving popups

---
 assets/svg/arrow-down.svg                     |   4 +
 .../generate_receiving_uri_qr_code_view.dart  | 771 +++++++++++-------
 .../sub_widgets/desktop_receive.dart          |  67 +-
 lib/route_generator.dart                      |  16 +
 lib/utilities/assets.dart                     |   1 +
 pubspec.yaml                                  |   1 +
 6 files changed, 545 insertions(+), 315 deletions(-)
 create mode 100644 assets/svg/arrow-down.svg

diff --git a/assets/svg/arrow-down.svg b/assets/svg/arrow-down.svg
new file mode 100644
index 000000000..c96e43ce3
--- /dev/null
+++ b/assets/svg/arrow-down.svg
@@ -0,0 +1,4 @@
+<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M10.5 4.16602V15.8327" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M16.3327 10L10.4993 15.8333L4.66602 10" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
index 3e29612d1..4c3c4c968 100644
--- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
+++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
@@ -20,7 +20,10 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -51,6 +54,10 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
   late TextEditingController amountController;
   late TextEditingController noteController;
 
+  late final bool isDesktop;
+  late String _uriString;
+  bool didGenerate = false;
+
   final _amountFocusNode = FocusNode();
   final _noteFocusNode = FocusNode();
 
@@ -81,8 +88,151 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
     }
   }
 
+  String? _generateURI() {
+    final amountString = amountController.text;
+    final noteString = noteController.text;
+
+    if (amountString.isNotEmpty && Decimal.tryParse(amountString) == null) {
+      showFloatingFlushBar(
+        type: FlushBarType.warning,
+        message: "Invalid amount",
+        context: context,
+      );
+      return null;
+    }
+
+    String query = "";
+
+    if (amountString.isNotEmpty) {
+      query += "amount=$amountString";
+    }
+    if (noteString.isNotEmpty) {
+      if (query.isNotEmpty) {
+        query += "&";
+      }
+      query += "message=$noteString";
+    }
+
+    final uri = Uri(
+      scheme: widget.coin.uriScheme,
+      host: widget.receivingAddress,
+      query: query.isNotEmpty ? query : null,
+    );
+
+    final uriString = uri.toString().replaceFirst("://", ":");
+
+    Logging.instance.log("Generated receiving QR code for: $uriString",
+        level: LogLevel.Info);
+
+    return uriString;
+  }
+
+  void onGeneratePressed() {
+    final uriString = _generateURI();
+
+    if (uriString == null) {
+      return;
+    }
+
+    showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (_) {
+        final width = MediaQuery.of(context).size.width / 2;
+        return StackDialogBase(
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              Center(
+                child: Text(
+                  "New QR code",
+                  style: STextStyles.pageTitleH2(context),
+                ),
+              ),
+              const SizedBox(
+                height: 12,
+              ),
+              Center(
+                child: RepaintBoundary(
+                  key: _qrKey,
+                  child: SizedBox(
+                    width: width + 20,
+                    height: width + 20,
+                    child: QrImage(
+                        data: uriString,
+                        size: width,
+                        backgroundColor:
+                            Theme.of(context).extension<StackColors>()!.popupBG,
+                        foregroundColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark),
+                  ),
+                ),
+              ),
+              const SizedBox(
+                height: 12,
+              ),
+              Center(
+                child: SizedBox(
+                  width: width,
+                  child: TextButton(
+                    onPressed: () async {
+                      // TODO: add save button as well
+                      await _capturePng(true);
+                    },
+                    style: Theme.of(context)
+                        .extension<StackColors>()!
+                        .getSecondaryEnabledButtonColor(context),
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      crossAxisAlignment: CrossAxisAlignment.center,
+                      children: [
+                        Center(
+                          child: SvgPicture.asset(
+                            Assets.svg.share,
+                            width: 14,
+                            height: 14,
+                          ),
+                        ),
+                        const SizedBox(
+                          width: 4,
+                        ),
+                        Column(
+                          children: [
+                            Text(
+                              "Share",
+                              textAlign: TextAlign.center,
+                              style: STextStyles.button(context).copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .buttonTextSecondary,
+                              ),
+                            ),
+                            const SizedBox(
+                              height: 2,
+                            ),
+                          ],
+                        ),
+                      ],
+                    ),
+                  ),
+                ),
+              ),
+            ],
+          ),
+        );
+      },
+    );
+  }
+
   @override
   void initState() {
+    isDesktop = Util.isDesktop;
+    _uriString = Uri(
+      scheme: widget.coin.uriScheme,
+      host: widget.receivingAddress,
+    ).toString().replaceFirst("://", ":");
     amountController = TextEditingController();
     noteController = TextEditingController();
     super.initState();
@@ -101,315 +251,330 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            if (FocusScope.of(context).hasFocus) {
-              FocusScope.of(context).unfocus();
-              await Future<void>.delayed(const Duration(milliseconds: 70));
-            }
-            if (mounted) {
-              Navigator.of(context).pop();
-            }
-          },
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              if (FocusScope.of(context).hasFocus) {
+                FocusScope.of(context).unfocus();
+                await Future<void>.delayed(const Duration(milliseconds: 70));
+              }
+              if (mounted) {
+                Navigator.of(context).pop();
+              }
+            },
+          ),
+          title: Text(
+            "Generate QR code",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Generate QR code",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (buildContext, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        RoundedWhiteContainer(
-                          child: Text(
-                            "The new QR code with your address, amount and note will appear in the pop up window.",
-                            style: STextStyles.itemSubtitle(context),
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        Text(
-                          "Amount (Optional)",
-                          style: STextStyles.smallMed12(context),
-                          textAlign: TextAlign.left,
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            controller: amountController,
-                            focusNode: _amountFocusNode,
-                            style: STextStyles.field(context),
-                            keyboardType: const TextInputType.numberWithOptions(
-                                decimal: true),
-                            onChanged: (_) => setState(() {}),
-                            decoration: standardInputDecoration(
-                              "Amount",
-                              _amountFocusNode,
-                              context,
-                            ).copyWith(
-                              suffixIcon: amountController.text.isNotEmpty
-                                  ? Padding(
-                                      padding: const EdgeInsets.only(right: 0),
-                                      child: UnconstrainedBox(
-                                        child: Row(
-                                          children: [
-                                            TextFieldIconButton(
-                                              child: const XIcon(),
-                                              onTap: () async {
-                                                setState(() {
-                                                  amountController.text = "";
-                                                });
-                                              },
-                                            ),
-                                          ],
-                                        ),
-                                      ),
-                                    )
-                                  : null,
-                            ),
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        Text(
-                          "Note (Optional)",
-                          style: STextStyles.smallMed12(context),
-                          textAlign: TextAlign.left,
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            controller: noteController,
-                            focusNode: _noteFocusNode,
-                            style: STextStyles.field(context),
-                            onChanged: (_) => setState(() {}),
-                            decoration: standardInputDecoration(
-                              "Note",
-                              _noteFocusNode,
-                              context,
-                            ).copyWith(
-                              suffixIcon: noteController.text.isNotEmpty
-                                  ? Padding(
-                                      padding: const EdgeInsets.only(right: 0),
-                                      child: UnconstrainedBox(
-                                        child: Row(
-                                          children: [
-                                            TextFieldIconButton(
-                                              child: const XIcon(),
-                                              onTap: () async {
-                                                setState(() {
-                                                  noteController.text = "";
-                                                });
-                                              },
-                                            ),
-                                          ],
-                                        ),
-                                      ),
-                                    )
-                                  : null,
-                            ),
-                          ),
-                        ),
-                        // SizedBox()
-                        // Spacer(),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        TextButton(
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context),
-                          onPressed: () {
-                            final amountString = amountController.text;
-                            final noteString = noteController.text;
-
-                            if (amountString.isNotEmpty &&
-                                Decimal.tryParse(amountString) == null) {
-                              showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "Invalid amount",
-                                context: context,
-                              );
-                              return;
-                            }
-
-                            String query = "";
-
-                            if (amountString.isNotEmpty) {
-                              query += "amount=$amountString";
-                            }
-                            if (noteString.isNotEmpty) {
-                              if (query.isNotEmpty) {
-                                query += "&";
-                              }
-                              query += "message=$noteString";
-                            }
-
-                            final uri = Uri(
-                              scheme: widget.coin.uriScheme,
-                              host: widget.receivingAddress,
-                              query: query.isNotEmpty ? query : null,
-                            );
-
-                            final uriString =
-                                uri.toString().replaceFirst("://", ":");
-
-                            Logging.instance.log(
-                                "Generated receiving QR code for: $uriString",
-                                level: LogLevel.Info);
-
-                            showDialog<dynamic>(
-                              context: context,
-                              useSafeArea: false,
-                              barrierDismissible: true,
-                              builder: (_) {
-                                final width =
-                                    MediaQuery.of(context).size.width / 2;
-                                return StackDialogBase(
-                                  child: Column(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.stretch,
-                                    children: [
-                                      Center(
-                                        child: Text(
-                                          "New QR code",
-                                          style:
-                                              STextStyles.pageTitleH2(context),
-                                        ),
-                                      ),
-                                      const SizedBox(
-                                        height: 12,
-                                      ),
-                                      Center(
-                                        child: RepaintBoundary(
-                                          key: _qrKey,
-                                          child: SizedBox(
-                                            width: width + 20,
-                                            height: width + 20,
-                                            child: QrImage(
-                                                data: uriString,
-                                                size: width,
-                                                backgroundColor: Theme.of(
-                                                        context)
-                                                    .extension<StackColors>()!
-                                                    .popupBG,
-                                                foregroundColor: Theme.of(
-                                                        context)
-                                                    .extension<StackColors>()!
-                                                    .accentColorDark),
-                                          ),
-                                        ),
-                                      ),
-                                      const SizedBox(
-                                        height: 12,
-                                      ),
-                                      Center(
-                                        child: SizedBox(
-                                          width: width,
-                                          child: TextButton(
-                                            onPressed: () async {
-                                              // TODO: add save button as well
-                                              await _capturePng(true);
-                                            },
-                                            style: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .getSecondaryEnabledButtonColor(
-                                                    context),
-                                            child: Row(
-                                              mainAxisAlignment:
-                                                  MainAxisAlignment.center,
-                                              crossAxisAlignment:
-                                                  CrossAxisAlignment.center,
-                                              children: [
-                                                Center(
-                                                  child: SvgPicture.asset(
-                                                    Assets.svg.share,
-                                                    width: 14,
-                                                    height: 14,
-                                                  ),
-                                                ),
-                                                const SizedBox(
-                                                  width: 4,
-                                                ),
-                                                Column(
-                                                  children: [
-                                                    Text(
-                                                      "Share",
-                                                      textAlign:
-                                                          TextAlign.center,
-                                                      style: STextStyles.button(
-                                                              context)
-                                                          .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .buttonTextSecondary,
-                                                      ),
-                                                    ),
-                                                    const SizedBox(
-                                                      height: 2,
-                                                    ),
-                                                  ],
-                                                ),
-                                              ],
-                                            ),
-                                          ),
-                                        ),
-                                      ),
-                                    ],
-                                  ),
-                                );
-                              },
-                            );
-                          },
-                          child: Text(
-                            "Generate QR Code",
-                            style: STextStyles.button(context),
-                          ),
-                        ),
-                      ],
+        body: LayoutBuilder(
+          builder: (buildContext, constraints) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: child,
                     ),
                   ),
                 ),
               ),
+            );
+          },
+        ),
+      ),
+      child: Padding(
+        padding: isDesktop
+            ? const EdgeInsets.only(
+                top: 12,
+                left: 32,
+                right: 32,
+                bottom: 32,
+              )
+            : const EdgeInsets.all(0),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          mainAxisSize: isDesktop ? MainAxisSize.min : MainAxisSize.max,
+          children: [
+            if (!isDesktop)
+              RoundedWhiteContainer(
+                child: Text(
+                  "The new QR code with your address, amount and note will appear in the pop up window.",
+                  style: STextStyles.itemSubtitle(context),
+                ),
+              ),
+            if (!isDesktop)
+              const SizedBox(
+                height: 12,
+              ),
+            Text(
+              "Amount (Optional)",
+              style: isDesktop
+                  ? STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldActiveSearchIconRight,
+                    )
+                  : STextStyles.smallMed12(context),
+              textAlign: TextAlign.left,
             ),
-          );
-        },
+            SizedBox(
+              height: isDesktop ? 10 : 8,
+            ),
+            ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
+                controller: amountController,
+                focusNode: _amountFocusNode,
+                style: isDesktop
+                    ? STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultText,
+                        height: 1.8,
+                      )
+                    : STextStyles.field(context),
+                keyboardType:
+                    const TextInputType.numberWithOptions(decimal: true),
+                onChanged: (_) => setState(() {}),
+                decoration: standardInputDecoration(
+                  "Amount",
+                  _amountFocusNode,
+                  context,
+                ).copyWith(
+                  contentPadding: isDesktop
+                      ? const EdgeInsets.only(
+                          left: 16,
+                          top: 11,
+                          bottom: 12,
+                          right: 5,
+                        )
+                      : null,
+                  suffixIcon: amountController.text.isNotEmpty
+                      ? Padding(
+                          padding: const EdgeInsets.only(right: 0),
+                          child: UnconstrainedBox(
+                            child: Row(
+                              children: [
+                                TextFieldIconButton(
+                                  child: const XIcon(),
+                                  onTap: () async {
+                                    setState(() {
+                                      amountController.text = "";
+                                    });
+                                  },
+                                ),
+                              ],
+                            ),
+                          ),
+                        )
+                      : null,
+                ),
+              ),
+            ),
+            SizedBox(
+              height: isDesktop ? 20 : 12,
+            ),
+            Text(
+              "Note (Optional)",
+              style: isDesktop
+                  ? STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldActiveSearchIconRight,
+                    )
+                  : STextStyles.smallMed12(context),
+              textAlign: TextAlign.left,
+            ),
+            SizedBox(
+              height: isDesktop ? 10 : 8,
+            ),
+            ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
+                controller: noteController,
+                focusNode: _noteFocusNode,
+                style: isDesktop
+                    ? STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultText,
+                        height: 1.8,
+                      )
+                    : STextStyles.field(context),
+                onChanged: (_) => setState(() {}),
+                decoration: standardInputDecoration(
+                  "Note",
+                  _noteFocusNode,
+                  context,
+                ).copyWith(
+                  contentPadding: isDesktop
+                      ? const EdgeInsets.only(
+                          left: 16,
+                          top: 11,
+                          bottom: 12,
+                          right: 5,
+                        )
+                      : null,
+                  suffixIcon: noteController.text.isNotEmpty
+                      ? Padding(
+                          padding: const EdgeInsets.only(right: 0),
+                          child: UnconstrainedBox(
+                            child: Row(
+                              children: [
+                                TextFieldIconButton(
+                                  child: const XIcon(),
+                                  onTap: () async {
+                                    setState(() {
+                                      noteController.text = "";
+                                    });
+                                  },
+                                ),
+                              ],
+                            ),
+                          ),
+                        )
+                      : null,
+                ),
+              ),
+            ),
+            SizedBox(
+              height: isDesktop ? 20 : 8,
+            ),
+            PrimaryButton(
+              label: "Generate QR code",
+              onPressed: isDesktop
+                  ? () {
+                      final uriString = _generateURI();
+                      if (uriString == null) {
+                        return;
+                      }
+
+                      setState(() {
+                        didGenerate = true;
+                        _uriString = uriString;
+                      });
+                    }
+                  : onGeneratePressed,
+              desktopMed: true,
+            ),
+            if (isDesktop && didGenerate)
+              Row(
+                mainAxisAlignment: MainAxisAlignment.center,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  Column(
+                    mainAxisSize: MainAxisSize.min,
+                    children: [
+                      const SizedBox(
+                        height: 20,
+                      ),
+                      RoundedWhiteContainer(
+                        borderColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .background,
+                        child: Column(
+                          children: [
+                            Text(
+                              "New QR Code",
+                              style: STextStyles.desktopTextMedium(context),
+                            ),
+                            const SizedBox(
+                              height: 16,
+                            ),
+                            Center(
+                              child: RepaintBoundary(
+                                key: _qrKey,
+                                child: SizedBox(
+                                  width: 234,
+                                  height: 234,
+                                  child: QrImage(
+                                      data: _uriString,
+                                      size: 220,
+                                      backgroundColor: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .popupBG,
+                                      foregroundColor: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .accentColorDark),
+                                ),
+                              ),
+                            ),
+                            const SizedBox(
+                              height: 12,
+                            ),
+                            Row(
+                              children: [
+                                SecondaryButton(
+                                  width: 170,
+                                  desktopMed: true,
+                                  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,
+                                ),
+                                PrimaryButton(
+                                  width: 170,
+                                  desktopMed: true,
+                                  onPressed: () async {
+                                    // TODO: add save functionality instead of share
+                                    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_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
index 46b4cfcfc..9a59c3ec1 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
@@ -16,9 +16,13 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_loading_overlay.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:tuple/tuple.dart';
 
 class DesktopReceive extends ConsumerStatefulWidget {
   const DesktopReceive({
@@ -216,20 +220,59 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
         // TODO: create transparent button class to account for hover
         GestureDetector(
           onTap: () async {
-            unawaited(
-              Navigator.of(context).push(
-                RouteGenerator.getRoute(
-                  shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
-                  builder: (_) => GenerateUriQrCodeView(
-                    coin: coin,
-                    receivingAddress: receivingAddress,
-                  ),
-                  settings: const RouteSettings(
-                    name: GenerateUriQrCodeView.routeName,
+            if (Util.isDesktop) {
+              await showDialog<void>(
+                context: context,
+                builder: (context) => DesktopDialog(
+                  maxHeight: double.infinity,
+                  maxWidth: 580,
+                  child: Column(
+                    children: [
+                      Row(
+                        children: [
+                          const AppBarBackButton(
+                            size: 40,
+                            iconSize: 24,
+                          ),
+                          Text(
+                            "Generate QR code",
+                            style: STextStyles.desktopH3(context),
+                          ),
+                        ],
+                      ),
+                      IntrinsicHeight(
+                        child: Navigator(
+                          onGenerateRoute: RouteGenerator.generateRoute,
+                          onGenerateInitialRoutes: (_, __) => [
+                            RouteGenerator.generateRoute(
+                              RouteSettings(
+                                name: GenerateUriQrCodeView.routeName,
+                                arguments: Tuple2(coin, receivingAddress),
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ],
                   ),
                 ),
-              ),
-            );
+              );
+            } else {
+              unawaited(
+                Navigator.of(context).push(
+                  RouteGenerator.getRoute(
+                    shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
+                    builder: (_) => GenerateUriQrCodeView(
+                      coin: coin,
+                      receivingAddress: receivingAddress,
+                    ),
+                    settings: const RouteSettings(
+                      name: GenerateUriQrCodeView.routeName,
+                    ),
+                  ),
+                ),
+              );
+            }
           },
           child: Container(
             color: Colors.transparent,
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 5d0f81e20..91d1a3768 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -37,6 +37,7 @@ import 'package:stackwallet/pages/intro_view.dart';
 import 'package:stackwallet/pages/manage_favorites_view/manage_favorites_view.dart';
 import 'package:stackwallet/pages/notification_views/notifications_view.dart';
 import 'package:stackwallet/pages/pinpad_views/create_pin_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/send_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/about_view.dart';
@@ -955,6 +956,21 @@ class RouteGenerator {
         }
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
+      case GenerateUriQrCodeView.routeName:
+        if (args is Tuple2<Coin, String>) {
+          return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => GenerateUriQrCodeView(
+              coin: args.item1,
+              receivingAddress: args.item2,
+            ),
+            settings: RouteSettings(
+              name: settings.name,
+            ),
+          );
+        }
+        return _routeError("${settings.name} invalid args: ${args.toString()}");
+
       // == Desktop specific routes ============================================
       case CreatePasswordView.routeName:
         return getRoute(
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index c2d488305..432ebbec9 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -145,6 +145,7 @@ class _SVG {
   String get walletDesktop => "assets/svg/wallet-desktop.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 ellipse1 => "assets/svg/Ellipse-43.svg";
   String get ellipse2 => "assets/svg/Ellipse-42.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index 88951b29b..cc0138b75 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -310,6 +310,7 @@ flutter:
     - assets/svg/wallet-desktop.svg
     - assets/svg/exit-desktop.svg
     - assets/svg/keys.svg
+    - assets/svg/arrow-down.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Litecoin.svg

From 5f28a8cb36dd4cf18e3b10f824b6850cddb72a5b Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 31 Oct 2022 12:21:58 -0600
Subject: [PATCH 082/426] desktop send info message popups

---
 .../wallet_view/sub_widgets/desktop_send.dart | 165 +++++++++++++-----
 1 file changed, 121 insertions(+), 44 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index 116262d23..d482f7ab8 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -32,7 +32,10 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/animated_text.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
@@ -107,23 +110,55 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         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),
+          return DesktopDialog(
+            maxWidth: 400,
+            maxHeight: double.infinity,
+            child: Padding(
+              padding: const EdgeInsets.only(
+                left: 32,
+                bottom: 32,
+              ),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Text(
+                        "Transaction failed",
+                        style: STextStyles.desktopH3(context),
+                      ),
+                      const DesktopDialogCloseButton(),
+                    ],
+                  ),
+                  const SizedBox(
+                    height: 12,
+                  ),
+                  Text(
+                    "Sending to self is currently disabled",
+                    textAlign: TextAlign.left,
+                    style: STextStyles.desktopTextExtraExtraSmall(context)
+                        .copyWith(
+                      fontSize: 18,
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 40,
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      right: 32,
+                    ),
+                    child: SecondaryButton(
+                      desktopMed: true,
+                      label: "Ok",
+                      onPressed: () {
+                        Navigator.of(context).pop();
+                      },
+                    ),
+                  ),
+                ],
               ),
-              onPressed: () {
-                Navigator.of(context).pop();
-              },
             ),
           );
         },
@@ -154,36 +189,78 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         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>()!
-                  .getSecondaryEnabledButtonColor(context),
-              child: Text(
-                "Cancel",
-                style: STextStyles.button(context).copyWith(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .accentColorDark),
+          return DesktopDialog(
+            maxWidth: 450,
+            maxHeight: double.infinity,
+            child: Padding(
+              padding: const EdgeInsets.only(
+                left: 32,
+                bottom: 32,
               ),
-              onPressed: () {
-                Navigator.of(context).pop(false);
-              },
-            ),
-            rightButton: TextButton(
-              style: Theme.of(context)
-                  .extension<StackColors>()!
-                  .getPrimaryEnabledButtonColor(context),
-              child: Text(
-                "Yes",
-                style: STextStyles.button(context),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Text(
+                        "Confirm send all",
+                        style: STextStyles.desktopH3(context),
+                      ),
+                      const DesktopDialogCloseButton(),
+                    ],
+                  ),
+                  const SizedBox(
+                    height: 12,
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      right: 32,
+                    ),
+                    child: Text(
+                      "You are about to send your entire balance. Would you like to continue?",
+                      textAlign: TextAlign.left,
+                      style: STextStyles.desktopTextExtraExtraSmall(context)
+                          .copyWith(
+                        fontSize: 18,
+                      ),
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 40,
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      right: 32,
+                    ),
+                    child: Row(
+                      children: [
+                        Expanded(
+                          child: SecondaryButton(
+                            desktopMed: true,
+                            label: "Cancel",
+                            onPressed: () {
+                              Navigator.of(context).pop(false);
+                            },
+                          ),
+                        ),
+                        const SizedBox(
+                          width: 16,
+                        ),
+                        Expanded(
+                          child: PrimaryButton(
+                            desktopMed: true,
+                            label: "Yes",
+                            onPressed: () {
+                              Navigator.of(context).pop(true);
+                            },
+                          ),
+                        ),
+                      ],
+                    ),
+                  ),
+                ],
               ),
-              onPressed: () {
-                Navigator.of(context).pop(true);
-              },
             ),
           );
         },

From 03f4030d26a17c6d545b41826137f474dbd04164 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 1 Nov 2022 08:37:27 -0600
Subject: [PATCH 083/426] temp disabled erroring calls

---
 .../settings_menu/backup_and_restore/create_auto_backup.dart  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 29be17228..bd7eb9247 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -26,7 +26,7 @@ class CreateAutoBackup extends StatelessWidget {
     chooseFileLocation = FocusNode();
     // passwordRepeatFocusNode = FocusNode();
 
-    super.initState();
+    // super.initState();
   }
 
   @override
@@ -37,7 +37,7 @@ class CreateAutoBackup extends StatelessWidget {
     chooseFileLocation.dispose();
     // passwordRepeatFocusNode.dispose();
 
-    super.dispose();
+    // super.dispose();
   }
 
   @override

From 40390140837287f6033bce6c2c05ca7bd3723bf4 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 1 Nov 2022 08:42:09 -0600
Subject: [PATCH 084/426] WIP: needs drop down menu

---
 .../create_auto_backup.dart                   | 281 ++++++++++++++++--
 1 file changed, 261 insertions(+), 20 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 29be17228..fb22c8e92 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -1,30 +1,54 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.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/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
 
-import '../../../../utilities/assets.dart';
-import '../../../../widgets/custom_buttons/app_bar_icon_button.dart';
-import '../../../../widgets/stack_text_field.dart';
+class CreateAutoBackup extends StatefulWidget {
+  const CreateAutoBackup({Key? key}) : super(key: key);
 
-class CreateAutoBackup extends StatelessWidget {
-  // const CreateAutoBackup({Key? key, required this.chooseFileLocation})
-  //     : super(key: key);
+  @override
+  State<StatefulWidget> createState() => _CreateAutoBackup();
+}
 
+class _CreateAutoBackup extends State<CreateAutoBackup> {
   late final TextEditingController fileLocationController;
+  late final TextEditingController passphraseController;
+  late final TextEditingController passphraseRepeatController;
 
   late final FocusNode chooseFileLocation;
+  late final FocusNode passphraseFocusNode;
+  late final FocusNode passphraseRepeatFocusNode;
+
+  bool shouldShowPasswordHint = true;
+  bool hidePassword = true;
+
+  bool get fieldsMatch =>
+      passphraseController.text == passphraseRepeatController.text;
+
+  List<DropdownMenuItem<String>> get dropdownItems {
+    List<DropdownMenuItem<String>> menuItems = [
+      DropdownMenuItem(
+          child: Text("Every 10 minutes"), value: "Every 10 minutes"),
+    ];
+    return menuItems;
+  }
 
   @override
   void initState() {
     fileLocationController = TextEditingController();
-    // passwordRepeatController = TextEditingController();
+    passphraseController = TextEditingController();
+    passphraseRepeatController = TextEditingController();
 
     chooseFileLocation = FocusNode();
-    // passwordRepeatFocusNode = FocusNode();
+    passphraseFocusNode = FocusNode();
+    passphraseRepeatFocusNode = FocusNode();
 
     super.initState();
   }
@@ -32,18 +56,24 @@ class CreateAutoBackup extends StatelessWidget {
   @override
   void dispose() {
     fileLocationController.dispose();
-    // passwordRepeatController.dispose();
+    passphraseController.dispose();
+    passphraseRepeatController.dispose();
 
     chooseFileLocation.dispose();
-    // passwordRepeatFocusNode.dispose();
+    passphraseFocusNode.dispose();
+    passphraseRepeatFocusNode.dispose();
 
     super.dispose();
   }
 
   @override
   Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType ");
+
+    String? selectedItem = "Every 10 minutes";
+
     return DesktopDialog(
-      maxHeight: 600,
+      maxHeight: 650,
       maxWidth: 600,
       child: Column(
         children: [
@@ -93,16 +123,226 @@ class CreateAutoBackup extends StatelessWidget {
               textAlign: TextAlign.left,
             ),
           ),
-          TextField(
-            key: const Key("backupChooseFileLocation"),
-            style: STextStyles.desktopTextMedium(context).copyWith(
-              height: 2,
-            ),
-            enableSuggestions: false,
-            autocorrect: false,
-            decoration: standardInputDecoration(
-                "Save to...", chooseFileLocation, context),
+          SizedBox(
+            height: 10,
           ),
+          Padding(
+            padding: const EdgeInsets.only(
+              left: 32,
+              right: 32,
+            ),
+            child: ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                key: const Key("backupChooseFileLocation"),
+                focusNode: chooseFileLocation,
+                controller: fileLocationController,
+                style: STextStyles.desktopTextMedium(context).copyWith(
+                  height: 2,
+                ),
+                textAlign: TextAlign.left,
+                enableSuggestions: false,
+                autocorrect: false,
+                decoration: standardInputDecoration(
+                  "Save to...",
+                  chooseFileLocation,
+                  context,
+                ).copyWith(
+                  labelStyle:
+                      STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.textDark3,
+                  ),
+                  suffixIcon: Container(
+                    decoration: BoxDecoration(
+                      color: Colors.transparent,
+                      borderRadius: BorderRadius.circular(1000),
+                    ),
+                    height: 32,
+                    width: 32,
+                    child: Center(
+                      child: SvgPicture.asset(
+                        Assets.svg.folder,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark3,
+                        width: 20,
+                        height: 17.5,
+                      ),
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          ),
+          SizedBox(
+            height: 24,
+          ),
+          Container(
+            alignment: Alignment.centerLeft,
+            padding: EdgeInsets.only(left: 32),
+            child: Text(
+              "Create a passphrase",
+              style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
+              ),
+              textAlign: TextAlign.left,
+            ),
+          ),
+          SizedBox(
+            height: 10,
+          ),
+          Padding(
+            padding: EdgeInsets.only(
+              left: 32,
+              right: 32,
+            ),
+            child: ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                key: const Key("createBackupPassphrase"),
+                focusNode: passphraseFocusNode,
+                controller: passphraseController,
+                style: STextStyles.desktopTextMedium(context).copyWith(
+                  height: 2,
+                ),
+                obscureText: hidePassword,
+                enableSuggestions: false,
+                autocorrect: false,
+                decoration: standardInputDecoration(
+                  "Create passphrase",
+                  passphraseFocusNode,
+                  context,
+                ).copyWith(
+                  labelStyle:
+                      STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.textDark3,
+                  ),
+                  suffixIcon: UnconstrainedBox(
+                    child: GestureDetector(
+                      key: const Key(
+                          "createDesktopAutoBackupShowPassphraseButton1"),
+                      onTap: () async {
+                        setState(() {
+                          hidePassword = !hidePassword;
+                        });
+                      },
+                      child: Container(
+                        decoration: BoxDecoration(
+                          color: Colors.transparent,
+                          borderRadius: BorderRadius.circular(1000),
+                        ),
+                        height: 32,
+                        width: 32,
+                        child: Center(
+                          child: SvgPicture.asset(
+                            hidePassword ? Assets.svg.eye : Assets.svg.eyeSlash,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark3,
+                            width: 20,
+                            height: 17.5,
+                          ),
+                        ),
+                      ),
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          ),
+          const SizedBox(
+            height: 16,
+          ),
+          Padding(
+            padding: const EdgeInsets.only(
+              left: 32,
+              right: 32,
+            ),
+            child: ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                key: const Key("createBackupPassphrase"),
+                focusNode: passphraseRepeatFocusNode,
+                controller: passphraseRepeatController,
+                style: STextStyles.desktopTextMedium(context).copyWith(
+                  height: 2,
+                ),
+                obscureText: hidePassword,
+                enableSuggestions: false,
+                autocorrect: false,
+                decoration: standardInputDecoration(
+                  "Confirm passphrase",
+                  passphraseRepeatFocusNode,
+                  context,
+                ).copyWith(
+                  labelStyle:
+                      STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.textDark3,
+                  ),
+                  suffixIcon: UnconstrainedBox(
+                    child: GestureDetector(
+                      key: const Key(
+                          "createDesktopAutoBackupShowPassphraseButton2"),
+                      onTap: () async {
+                        setState(() {
+                          hidePassword = !hidePassword;
+                        });
+                      },
+                      child: Container(
+                        decoration: BoxDecoration(
+                          color: Colors.transparent,
+                          borderRadius: BorderRadius.circular(1000),
+                        ),
+                        height: 32,
+                        width: 32,
+                        child: Center(
+                          child: SvgPicture.asset(
+                            hidePassword ? Assets.svg.eye : Assets.svg.eyeSlash,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark3,
+                            width: 20,
+                            height: 17.5,
+                          ),
+                        ),
+                      ),
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          Container(
+            alignment: Alignment.centerLeft,
+            padding: const EdgeInsets.only(left: 32),
+            child: Text(
+              "Auto Backup frequency",
+              style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
+              ),
+              textAlign: TextAlign.left,
+            ),
+          ),
+          const SizedBox(
+            height: 10,
+          ),
+          // DropdownButton(
+          //   value: dropdownItems,
+          //   items: dropdownItems,
+          //   onChanged: null,
+          // ),
           const Spacer(),
           Padding(
             padding: const EdgeInsets.all(32),
@@ -123,6 +363,7 @@ class CreateAutoBackup extends StatelessWidget {
                 Expanded(
                   child: PrimaryButton(
                     label: "Enable Auto Backup",
+                    enabled: false,
                     onPressed: () {},
                   ),
                 )

From d9b825b001f6a4e75bb604dd87085c865d8850d8 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 1 Nov 2022 09:36:37 -0600
Subject: [PATCH 085/426] dropdown fix

---
 .../backup_and_restore_settings.dart          |  3 +-
 .../create_auto_backup.dart                   | 67 +++++++++++++------
 2 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 6ab82401b..8b74f8d40 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -2,6 +2,7 @@ import 'package:flutter/gestures.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -9,8 +10,6 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:url_launcher/url_launcher.dart';
 
-import 'enable_backup_dialog.dart';
-
 class BackupRestoreSettings extends ConsumerStatefulWidget {
   const BackupRestoreSettings({Key? key}) : super(key: key);
 
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 39b77cfea..0c8c47c9e 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -32,13 +32,27 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
   bool get fieldsMatch =>
       passphraseController.text == passphraseRepeatController.text;
 
-  List<DropdownMenuItem<String>> get dropdownItems {
-    List<DropdownMenuItem<String>> menuItems = [
-      DropdownMenuItem(
-          child: Text("Every 10 minutes"), value: "Every 10 minutes"),
-    ];
-    return menuItems;
-  }
+  String _currentDropDownValue = "Every 10 minutes";
+
+  final List<String> _dropDOwnItems = [
+    "Every 10 minutes",
+    "Every 20 minutes",
+    "Every 30 minutes",
+  ];
+
+  // List<DropdownMenuItem<String>> get dropdownItems {
+  //   List<DropdownMenuItem<String>> menuItems = [
+  //     const DropdownMenuItem(
+  //       value: "Every 10 minutes",
+  //       child: Text("Every 10 minutes"),
+  //     ),
+  //     const DropdownMenuItem(
+  //       value: "Every 20 minutes",
+  //       child: Text("Every 20 minutes"),
+  //     ),
+  //   ];
+  //   return menuItems;
+  // }
 
   @override
   void initState() {
@@ -50,7 +64,7 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
     passphraseFocusNode = FocusNode();
     passphraseRepeatFocusNode = FocusNode();
 
-    // super.initState();
+    super.initState();
   }
 
   @override
@@ -63,7 +77,7 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
     passphraseFocusNode.dispose();
     passphraseRepeatFocusNode.dispose();
 
-    // super.dispose();
+    super.dispose();
   }
 
   @override
@@ -114,7 +128,7 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
           ),
           Container(
             alignment: Alignment.centerLeft,
-            padding: EdgeInsets.only(left: 32),
+            padding: const EdgeInsets.only(left: 32),
             child: Text(
               "Choose file location",
               style: STextStyles.desktopTextExtraSmall(context).copyWith(
@@ -123,7 +137,7 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
               textAlign: TextAlign.left,
             ),
           ),
-          SizedBox(
+          const SizedBox(
             height: 10,
           ),
           Padding(
@@ -177,12 +191,12 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
               ),
             ),
           ),
-          SizedBox(
+          const SizedBox(
             height: 24,
           ),
           Container(
             alignment: Alignment.centerLeft,
-            padding: EdgeInsets.only(left: 32),
+            padding: const EdgeInsets.only(left: 32),
             child: Text(
               "Create a passphrase",
               style: STextStyles.desktopTextExtraSmall(context).copyWith(
@@ -191,11 +205,11 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
               textAlign: TextAlign.left,
             ),
           ),
-          SizedBox(
+          const SizedBox(
             height: 10,
           ),
           Padding(
-            padding: EdgeInsets.only(
+            padding: const EdgeInsets.only(
               left: 32,
               right: 32,
             ),
@@ -338,11 +352,24 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
           const SizedBox(
             height: 10,
           ),
-          // DropdownButton(
-          //   value: dropdownItems,
-          //   items: dropdownItems,
-          //   onChanged: null,
-          // ),
+          DropdownButton(
+            value: _currentDropDownValue,
+            items: _dropDOwnItems
+                .map(
+                  (e) => DropdownMenuItem(
+                    value: e,
+                    child: Text(e),
+                  ),
+                )
+                .toList(),
+            onChanged: (value) {
+              if (value is String) {
+                setState(() {
+                  _currentDropDownValue = value;
+                });
+              }
+            },
+          ),
           const Spacer(),
           Padding(
             padding: const EdgeInsets.all(32),

From 99883d30ac2838c2867e7026a79ab73647fae0ff Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 1 Nov 2022 11:42:13 -0600
Subject: [PATCH 086/426] satoshi to decimal amount format function modified to
 take optional Coin parameter

---
 lib/utilities/format.dart | 36 +++++++++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 5 deletions(-)

diff --git a/lib/utilities/format.dart b/lib/utilities/format.dart
index f0eafdf94..775780833 100644
--- a/lib/utilities/format.dart
+++ b/lib/utilities/format.dart
@@ -4,13 +4,39 @@ import 'package:decimal/decimal.dart';
 import 'package:intl/number_symbols.dart';
 import 'package:intl/number_symbols_data.dart' show numberFormatSymbols;
 import 'package:stackwallet/utilities/constants.dart';
-
-import 'enums/backup_frequency_type.dart';
+import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 abstract class Format {
-  static Decimal satoshisToAmount(int sats) =>
-      (Decimal.fromInt(sats) / Decimal.fromInt(Constants.satsPerCoin))
-          .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces);
+  static Decimal satoshisToAmount(int sats, {Coin? coin}) {
+    late final int satsPerCoin;
+
+    switch (coin) {
+      case Coin.wownero:
+        satsPerCoin = Constants.satsPerCoinWownero;
+        break;
+      case Coin.monero:
+        satsPerCoin = Constants.satsPerCoinMonero;
+        break;
+      case Coin.bitcoin:
+      case Coin.bitcoincash:
+      case Coin.dogecoin:
+      case Coin.epicCash:
+      case Coin.firo:
+      case Coin.litecoin:
+      case Coin.namecoin:
+      case Coin.bitcoinTestNet:
+      case Coin.litecoinTestNet:
+      case Coin.bitcoincashTestnet:
+      case Coin.dogecoinTestNet:
+      case Coin.firoTestNet:
+      default:
+        satsPerCoin = Constants.satsPerCoin;
+    }
+
+    return (Decimal.fromInt(sats) / Decimal.fromInt(satsPerCoin))
+        .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces);
+  }
 
   ///
   static String satoshiAmountToPrettyString(int sats, String locale) {

From ec3378fec2d0dfee5c2015c36231e0e52ddcf2d8 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 1 Nov 2022 11:42:33 -0600
Subject: [PATCH 087/426] WIP desktop send flow

---
 .../send_view/confirm_transaction_view.dart   | 779 +++++++++++++-----
 .../building_transaction_dialog.dart          |  98 ++-
 .../wallet_view/sub_widgets/desktop_send.dart | 142 +++-
 lib/route_generator.dart                      |  16 +
 4 files changed, 740 insertions(+), 295 deletions(-)

diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index 65537f20e..81d5a3da2 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -1,7 +1,9 @@
 import 'dart:async';
 
+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/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';
@@ -11,12 +13,17 @@ import 'package:stackwallet/providers/wallet/public_private_balance_state_provid
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -45,6 +52,14 @@ class _ConfirmTransactionViewState
   late final Map<String, dynamic> transactionInfo;
   late final String walletId;
   late final String routeOnSuccessName;
+  late final bool isDesktop;
+
+  int _fee = 12;
+  final List<int> _dropDownItems = [
+    12,
+    22,
+    234,
+  ];
 
   Future<void> _attemptSend(BuildContext context) async {
     unawaited(showDialog<dynamic>(
@@ -133,6 +148,7 @@ class _ConfirmTransactionViewState
 
   @override
   void initState() {
+    isDesktop = Util.isDesktop;
     transactionInfo = widget.transactionInfo;
     walletId = widget.walletId;
     routeOnSuccessName = widget.routeOnSuccessName;
@@ -143,234 +159,553 @@ class _ConfirmTransactionViewState
   Widget build(BuildContext context) {
     final managerProvider = ref.watch(walletsChangeNotifierProvider
         .select((value) => value.getManagerProvider(walletId)));
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: 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(Duration(milliseconds: 50));
-            // }
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Confirm transaction",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (builderContext, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        Text(
-                          "Send ${ref.watch(managerProvider.select((value) => value.coin)).ticker}",
-                          style: STextStyles.pageTitleH1(context),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.stretch,
-                            children: [
-                              Text(
-                                "Recipient",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              Text(
-                                "${transactionInfo["address"] ?? "ERROR"}",
-                                style: STextStyles.itemSubtitle12(context),
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "Amount",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              Text(
-                                "${Format.satoshiAmountToPrettyString(
-                                  transactionInfo["recipientAmt"] as int,
-                                  ref.watch(
-                                    localeServiceChangeNotifierProvider
-                                        .select((value) => value.locale),
-                                  ),
-                                )} ${ref.watch(
-                                      managerProvider
-                                          .select((value) => value.coin),
-                                    ).ticker}",
-                                style: STextStyles.itemSubtitle12(context),
-                                textAlign: TextAlign.right,
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "Transaction fee",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              Text(
-                                "${Format.satoshiAmountToPrettyString(
-                                  transactionInfo["fee"] as int,
-                                  ref.watch(
-                                    localeServiceChangeNotifierProvider
-                                        .select((value) => value.locale),
-                                  ),
-                                )} ${ref.watch(
-                                      managerProvider
-                                          .select((value) => value.coin),
-                                    ).ticker}",
-                                style: STextStyles.itemSubtitle12(context),
-                                textAlign: TextAlign.right,
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.stretch,
-                            children: [
-                              Text(
-                                "Note",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              Text(
-                                transactionInfo["note"] as String,
-                                style: STextStyles.itemSubtitle12(context),
-                              ),
-                            ],
-                          ),
-                        ),
-                        const Spacer(),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedContainer(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .snackBarBackSuccess,
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "Total amount",
-                                style:
-                                    STextStyles.titleBold12(context).copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textConfirmTotalAmount,
-                                ),
-                              ),
-                              Text(
-                                "${Format.satoshiAmountToPrettyString(
-                                  (transactionInfo["fee"] as int) +
-                                      (transactionInfo["recipientAmt"] as int),
-                                  ref.watch(
-                                    localeServiceChangeNotifierProvider
-                                        .select((value) => value.locale),
-                                  ),
-                                )} ${ref.watch(
-                                      managerProvider
-                                          .select((value) => value.coin),
-                                    ).ticker}",
-                                style: STextStyles.itemSubtitle12(context)
-                                    .copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textConfirmTotalAmount,
-                                ),
-                                textAlign: TextAlign.right,
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        TextButton(
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context),
-                          onPressed: () async {
-                            final unlocked = await Navigator.push(
-                              context,
-                              RouteGenerator.getRoute(
-                                shouldUseMaterialRoute:
-                                    RouteGenerator.useMaterialPageRoute,
-                                builder: (_) => const LockscreenView(
-                                  showBackButton: true,
-                                  popOnSuccess: true,
-                                  routeOnSuccessArguments: true,
-                                  routeOnSuccess: "",
-                                  biometricsCancelButtonString: "CANCEL",
-                                  biometricsLocalizedReason:
-                                      "Authenticate to send transaction",
-                                  biometricsAuthenticationTitle:
-                                      "Confirm Transaction",
-                                ),
-                                settings: const RouteSettings(
-                                    name: "/confirmsendlockscreen"),
-                              ),
-                            );
 
-                            if (unlocked is bool && unlocked && mounted) {
-                              unawaited(_attemptSend(context));
-                            }
-                          },
-                          child: Text(
-                            "Send",
-                            style: STextStyles.button(context),
-                          ),
-                        ),
-                      ],
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: 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(Duration(milliseconds: 50));
+              // }
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Confirm transaction",
+            style: STextStyles.navBarTitle(context),
+          ),
+        ),
+        body: LayoutBuilder(
+          builder: (builderContext, constraints) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: child,
                     ),
                   ),
                 ),
               ),
+            );
+          },
+        ),
+      ),
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) => Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          mainAxisSize: MainAxisSize.min,
+          children: [
+            Row(
+              children: [
+                AppBarBackButton(
+                  size: 40,
+                  iconSize: 24,
+                  onPressed: () => Navigator.of(
+                    context,
+                    rootNavigator: true,
+                  ).pop(),
+                ),
+                Text(
+                  "Confirm ${ref.watch(managerProvider.select((value) => value.coin.ticker.toUpperCase()))} transaction",
+                  style: STextStyles.desktopH3(context),
+                ),
+              ],
             ),
-          );
-        },
+            child,
+          ],
+        ),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          mainAxisSize: isDesktop ? MainAxisSize.min : MainAxisSize.max,
+          children: [
+            if (!isDesktop)
+              Column(
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: [
+                  Text(
+                    "Send ${ref.watch(managerProvider.select((value) => value.coin)).ticker}",
+                    style: STextStyles.pageTitleH1(context),
+                  ),
+                  const SizedBox(
+                    height: 12,
+                  ),
+                  RoundedWhiteContainer(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        Text(
+                          "Recipient",
+                          style: STextStyles.smallMed12(context),
+                        ),
+                        const SizedBox(
+                          height: 4,
+                        ),
+                        Text(
+                          "${transactionInfo["address"] ?? "ERROR"}",
+                          style: STextStyles.itemSubtitle12(context),
+                        ),
+                      ],
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 12,
+                  ),
+                  RoundedWhiteContainer(
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Text(
+                          "Amount",
+                          style: STextStyles.smallMed12(context),
+                        ),
+                        Text(
+                          "${Format.satoshiAmountToPrettyString(
+                            transactionInfo["recipientAmt"] as int,
+                            ref.watch(
+                              localeServiceChangeNotifierProvider
+                                  .select((value) => value.locale),
+                            ),
+                          )} ${ref.watch(
+                                managerProvider.select((value) => value.coin),
+                              ).ticker}",
+                          style: STextStyles.itemSubtitle12(context),
+                          textAlign: TextAlign.right,
+                        ),
+                      ],
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 12,
+                  ),
+                  RoundedWhiteContainer(
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Text(
+                          "Transaction fee",
+                          style: STextStyles.smallMed12(context),
+                        ),
+                        Text(
+                          "${Format.satoshiAmountToPrettyString(
+                            transactionInfo["fee"] as int,
+                            ref.watch(
+                              localeServiceChangeNotifierProvider
+                                  .select((value) => value.locale),
+                            ),
+                          )} ${ref.watch(
+                                managerProvider.select((value) => value.coin),
+                              ).ticker}",
+                          style: STextStyles.itemSubtitle12(context),
+                          textAlign: TextAlign.right,
+                        ),
+                      ],
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 12,
+                  ),
+                  RoundedWhiteContainer(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        Text(
+                          "Note",
+                          style: STextStyles.smallMed12(context),
+                        ),
+                        const SizedBox(
+                          height: 4,
+                        ),
+                        Text(
+                          transactionInfo["note"] as String,
+                          style: STextStyles.itemSubtitle12(context),
+                        ),
+                      ],
+                    ),
+                  ),
+                ],
+              ),
+            if (isDesktop)
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 16,
+                  left: 32,
+                  right: 32,
+                  bottom: 50,
+                ),
+                child: RoundedWhiteContainer(
+                  padding: const EdgeInsets.all(0),
+                  borderColor:
+                      Theme.of(context).extension<StackColors>()!.background,
+                  child: Column(
+                    mainAxisSize: MainAxisSize.min,
+                    crossAxisAlignment: CrossAxisAlignment.stretch,
+                    children: [
+                      Container(
+                        decoration: BoxDecoration(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                          borderRadius: BorderRadius.only(
+                            topLeft: Radius.circular(
+                              Constants.size.circularBorderRadius,
+                            ),
+                            topRight: Radius.circular(
+                              Constants.size.circularBorderRadius,
+                            ),
+                          ),
+                        ),
+                        child: Padding(
+                          padding: const EdgeInsets.symmetric(
+                            horizontal: 12,
+                            vertical: 22,
+                          ),
+                          child: Row(
+                            children: [
+                              SvgPicture.asset(
+                                Assets.svg.send(context),
+                                width: 32,
+                                height: 32,
+                              ),
+                              const SizedBox(
+                                width: 16,
+                              ),
+                              Text(
+                                "Send ${ref.watch(
+                                      managerProvider
+                                          .select((value) => value.coin),
+                                    ).ticker}",
+                                style: STextStyles.desktopTextMedium(context),
+                              ),
+                            ],
+                          ),
+                        ),
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.all(12),
+                        child: Column(
+                          mainAxisSize: MainAxisSize.min,
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            Text(
+                              "Amount",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                            const SizedBox(
+                              height: 2,
+                            ),
+                            Builder(
+                              builder: (context) {
+                                final amount =
+                                    transactionInfo["recipientAmt"] as int;
+                                final coin = ref.watch(
+                                  managerProvider.select(
+                                    (value) => value.coin,
+                                  ),
+                                );
+                                final externalCalls = ref.watch(
+                                    prefsChangeNotifierProvider.select(
+                                        (value) => value.externalCalls));
+                                String fiatAmount = "N/A";
+
+                                if (externalCalls) {
+                                  final price = ref
+                                      .read(priceAnd24hChangeNotifierProvider)
+                                      .getPrice(coin)
+                                      .item1;
+                                  if (price > Decimal.zero) {
+                                    fiatAmount = Format.localizedStringAsFixed(
+                                      value: Format.satoshisToAmount(amount,
+                                              coin: coin) *
+                                          price,
+                                      locale: ref
+                                          .read(
+                                              localeServiceChangeNotifierProvider)
+                                          .locale,
+                                      decimalPlaces: 2,
+                                    );
+                                  }
+                                }
+
+                                return Row(
+                                  children: [
+                                    Text(
+                                      "${Format.satoshiAmountToPrettyString(
+                                        amount,
+                                        ref.watch(
+                                          localeServiceChangeNotifierProvider
+                                              .select((value) => value.locale),
+                                        ),
+                                      )} ${coin.ticker}",
+                                      style: STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          .copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textDark,
+                                      ),
+                                    ),
+                                    if (externalCalls)
+                                      Text(
+                                        " | ",
+                                        style: STextStyles
+                                            .desktopTextExtraExtraSmall(
+                                                context),
+                                      ),
+                                    if (externalCalls)
+                                      Text(
+                                        "~$fiatAmount ${ref.watch(prefsChangeNotifierProvider.select(
+                                          (value) => value.currency,
+                                        ))}",
+                                        style: STextStyles
+                                            .desktopTextExtraExtraSmall(
+                                                context),
+                                      ),
+                                  ],
+                                );
+                              },
+                            ),
+                          ],
+                        ),
+                      ),
+                      Container(
+                        height: 1,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .background,
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.all(12),
+                        child: Column(
+                          mainAxisSize: MainAxisSize.min,
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            Text(
+                              "Send to",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                            const SizedBox(
+                              height: 2,
+                            ),
+                            Text(
+                              "${transactionInfo["address"] ?? "ERROR"}",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                      context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              ),
+                            )
+                          ],
+                        ),
+                      ),
+                      Container(
+                        height: 1,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .background,
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.all(12),
+                        child: Column(
+                          mainAxisSize: MainAxisSize.min,
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            Text(
+                              "Note",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                            const SizedBox(
+                              height: 2,
+                            ),
+                            Text(
+                              transactionInfo["note"] as String,
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                      context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              ),
+                            )
+                          ],
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+            if (isDesktop)
+              Padding(
+                padding: const EdgeInsets.only(
+                  left: 32,
+                ),
+                child: Text(
+                  "Transaction fee (estimated)",
+                  style: STextStyles.desktopTextExtraExtraSmall(context),
+                ),
+              ),
+            if (isDesktop)
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  left: 32,
+                  right: 32,
+                ),
+                child: DropdownButtonFormField(
+                  value: _fee,
+                  items: _dropDownItems
+                      .map(
+                        (e) => DropdownMenuItem(
+                          value: e,
+                          child: Text(
+                            e.toString(),
+                          ),
+                        ),
+                      )
+                      .toList(),
+                  onChanged: (value) {
+                    if (value is int) {
+                      setState(() {
+                        _fee = value;
+                      });
+                    }
+                  },
+                ),
+              ),
+            if (!isDesktop) const Spacer(),
+            SizedBox(
+              height: isDesktop ? 23 : 12,
+            ),
+            Padding(
+              padding: isDesktop
+                  ? const EdgeInsets.symmetric(
+                      horizontal: 32,
+                    )
+                  : const EdgeInsets.all(0),
+              child: RoundedContainer(
+                padding: isDesktop
+                    ? const EdgeInsets.symmetric(
+                        horizontal: 16,
+                        vertical: 18,
+                      )
+                    : const EdgeInsets.all(12),
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .snackBarBackSuccess,
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Text(
+                      isDesktop ? "Total amount to send" : "Total amount",
+                      style: isDesktop
+                          ? STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textConfirmTotalAmount,
+                            )
+                          : STextStyles.titleBold12(context).copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textConfirmTotalAmount,
+                            ),
+                    ),
+                    Text(
+                      "${Format.satoshiAmountToPrettyString(
+                        (transactionInfo["fee"] as int) +
+                            (transactionInfo["recipientAmt"] as int),
+                        ref.watch(
+                          localeServiceChangeNotifierProvider
+                              .select((value) => value.locale),
+                        ),
+                      )} ${ref.watch(
+                            managerProvider.select((value) => value.coin),
+                          ).ticker}",
+                      style: isDesktop
+                          ? STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textConfirmTotalAmount,
+                            )
+                          : STextStyles.itemSubtitle12(context).copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textConfirmTotalAmount,
+                            ),
+                      textAlign: TextAlign.right,
+                    ),
+                  ],
+                ),
+              ),
+            ),
+            SizedBox(
+              height: isDesktop ? 28 : 16,
+            ),
+            Padding(
+              padding: isDesktop
+                  ? const EdgeInsets.symmetric(
+                      horizontal: 32,
+                    )
+                  : const EdgeInsets.all(0),
+              child: PrimaryButton(
+                label: "Send",
+                desktopMed: true,
+                onPressed: () async {
+                  final unlocked = await Navigator.push(
+                    context,
+                    RouteGenerator.getRoute(
+                      shouldUseMaterialRoute:
+                          RouteGenerator.useMaterialPageRoute,
+                      builder: (_) => const LockscreenView(
+                        showBackButton: true,
+                        popOnSuccess: true,
+                        routeOnSuccessArguments: true,
+                        routeOnSuccess: "",
+                        biometricsCancelButtonString: "CANCEL",
+                        biometricsLocalizedReason:
+                            "Authenticate to send transaction",
+                        biometricsAuthenticationTitle: "Confirm Transaction",
+                      ),
+                      settings:
+                          const RouteSettings(name: "/confirmsendlockscreen"),
+                    ),
+                  );
+
+                  if (unlocked is bool && unlocked && mounted) {
+                    unawaited(_attemptSend(context));
+                  }
+                },
+              ),
+            ),
+            if (isDesktop)
+              const SizedBox(
+                height: 32,
+              ),
+          ],
+        ),
       ),
     );
   }
diff --git a/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart b/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
index 0b6786915..045218e54 100644
--- a/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
+++ b/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
@@ -3,6 +3,8 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/utilities/assets.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/secondary_button.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
 class BuildingTransactionDialog extends StatefulWidget {
@@ -50,37 +52,73 @@ class _RestoringDialogState extends State<BuildingTransactionDialog>
 
   @override
   Widget build(BuildContext context) {
-    return WillPopScope(
-      onWillPop: () async {
-        return false;
-      },
-      child: StackDialog(
-        title: "Generating transaction",
-        // // TODO get message from design team
-        // message: "<PLACEHOLDER>",
-        icon: RotationTransition(
-          turns: _spinAnimation,
-          child: SvgPicture.asset(
-            Assets.svg.arrowRotate,
-            color: Theme.of(context).extension<StackColors>()!.accentColorDark,
-            width: 24,
-            height: 24,
+    if (Util.isDesktop) {
+      return Column(
+        mainAxisSize: MainAxisSize.min,
+        children: [
+          Text(
+            "Generating transaction",
+            style: STextStyles.desktopH3(context),
+          ),
+          const SizedBox(
+            height: 40,
+          ),
+          RotationTransition(
+            turns: _spinAnimation,
+            child: SvgPicture.asset(
+              Assets.svg.arrowRotate,
+              color:
+                  Theme.of(context).extension<StackColors>()!.accentColorDark,
+              width: 24,
+              height: 24,
+            ),
+          ),
+          const SizedBox(
+            height: 40,
+          ),
+          SecondaryButton(
+            desktopMed: true,
+            label: "Cancel",
+            onPressed: () {
+              onCancel.call();
+            },
+          )
+        ],
+      );
+    } else {
+      return WillPopScope(
+        onWillPop: () async {
+          return false;
+        },
+        child: StackDialog(
+          title: "Generating transaction",
+          // // TODO get message from design team
+          // message: "<PLACEHOLDER>",
+          icon: RotationTransition(
+            turns: _spinAnimation,
+            child: SvgPicture.asset(
+              Assets.svg.arrowRotate,
+              color:
+                  Theme.of(context).extension<StackColors>()!.accentColorDark,
+              width: 24,
+              height: 24,
+            ),
+          ),
+          rightButton: TextButton(
+            style: Theme.of(context)
+                .extension<StackColors>()!
+                .getSecondaryEnabledButtonColor(context),
+            child: Text(
+              "Cancel",
+              style: STextStyles.itemSubtitle12(context),
+            ),
+            onPressed: () {
+              Navigator.of(context).pop();
+              onCancel.call();
+            },
           ),
         ),
-        rightButton: TextButton(
-          style: Theme.of(context)
-              .extension<StackColors>()!
-              .getSecondaryEnabledButtonColor(context),
-          child: Text(
-            "Cancel",
-            style: STextStyles.itemSubtitle12(context),
-          ),
-          onPressed: () {
-            Navigator.of(context).pop();
-            onCancel.call();
-          },
-        ),
-      ),
-    );
+      );
+    }
   }
 }
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index d482f7ab8..a47b2b9dd 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -40,9 +40,9 @@ import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
-import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
+import 'package:tuple/tuple.dart';
 
 class DesktopSend extends ConsumerStatefulWidget {
   const DesktopSend({
@@ -280,12 +280,19 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         useSafeArea: false,
         barrierDismissible: false,
         builder: (context) {
-          return BuildingTransactionDialog(
-            onCancel: () {
-              wasCancelled = true;
+          return DesktopDialog(
+            maxWidth: 400,
+            maxHeight: double.infinity,
+            child: Padding(
+              padding: const EdgeInsets.all(32),
+              child: BuildingTransactionDialog(
+                onCancel: () {
+                  wasCancelled = true;
 
-              Navigator.of(context).pop();
-            },
+                  Navigator.of(context).pop();
+                },
+              ),
+            ),
           );
         },
       ));
@@ -310,54 +317,103 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
 
       if (!wasCancelled && mounted) {
         // pop building dialog
-        Navigator.of(context).pop();
+        Navigator.of(
+          context,
+          rootNavigator: true,
+        ).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,
+        unawaited(
+          showDialog(
+            context: context,
+            builder: (context) => DesktopDialog(
+              maxHeight: double.infinity,
+              maxWidth: 580,
+                  child: ConfirmTransactionView(
+                    transactionInfo: txData,
+                    walletId: walletId,
+                  ),
             ),
           ),
-        ));
+        );
       }
     } catch (e) {
       if (mounted) {
         // pop building dialog
-        Navigator.of(context).pop();
+        Navigator.of(
+          context,
+          rootNavigator: true,
+        ).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>()!
-                    .getSecondaryEnabledButtonColor(context),
-                child: Text(
-                  "Ok",
-                  style: STextStyles.button(context).copyWith(
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .accentColorDark),
+        unawaited(
+          showDialog<void>(
+            context: context,
+            builder: (context) {
+              return DesktopDialog(
+                maxWidth: 450,
+                maxHeight: double.infinity,
+                child: Padding(
+                  padding: const EdgeInsets.only(
+                    left: 32,
+                    bottom: 32,
+                  ),
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Text(
+                            "Transaction failed",
+                            style: STextStyles.desktopH3(context),
+                          ),
+                          const DesktopDialogCloseButton(),
+                        ],
+                      ),
+                      const SizedBox(
+                        height: 12,
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.only(
+                          right: 32,
+                        ),
+                        child: Text(
+                          e.toString(),
+                          textAlign: TextAlign.left,
+                          style: STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                            fontSize: 18,
+                          ),
+                        ),
+                      ),
+                      const SizedBox(
+                        height: 40,
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.only(
+                          right: 32,
+                        ),
+                        child: Expanded(
+                          child: SecondaryButton(
+                            desktopMed: true,
+                            label: "Yes",
+                            onPressed: () {
+                              Navigator.of(
+                                context,
+                                rootNavigator: true,
+                              ).pop();
+                            },
+                          ),
+                        ),
+                      ),
+                    ],
+                  ),
                 ),
-                onPressed: () {
-                  Navigator.of(context).pop();
-                },
-              ),
-            );
-          },
-        ));
+              );
+            },
+          ),
+        );
       }
     }
   }
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 91d1a3768..136dc7a34 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -39,6 +39,7 @@ import 'package:stackwallet/pages/notification_views/notifications_view.dart';
 import 'package:stackwallet/pages/pinpad_views/create_pin_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';
 import 'package:stackwallet/pages/send_view/send_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/about_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_views/advanced_settings_view.dart';
@@ -781,6 +782,21 @@ class RouteGenerator {
         }
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
+      case ConfirmTransactionView.routeName:
+        if (args is Tuple2<Map<String, dynamic>, String>) {
+          return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => ConfirmTransactionView(
+              transactionInfo: args.item1,
+              walletId: args.item2,
+            ),
+            settings: RouteSettings(
+              name: settings.name,
+            ),
+          );
+        }
+        return _routeError("${settings.name} invalid args: ${args.toString()}");
+
       case WalletInitiatedExchangeView.routeName:
         if (args is Tuple3<String, Coin, VoidCallback>) {
           return getRoute(

From 38c6af5caa3111ac0c7e732a473371159f75fdfe Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 1 Nov 2022 13:56:18 -0600
Subject: [PATCH 088/426] 'can change later in settings' subtitle removed when
 accessed from settings

---
 lib/pages/stack_privacy_calls.dart | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index 7ca21c494..d271b239f 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -8,7 +8,6 @@ import 'package:stackwallet/pages_desktop_specific/create_password/create_passwo
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
@@ -76,7 +75,7 @@ class _StackPrivacyCalls extends ConsumerState<StackPrivacyCalls> {
                 height: 8,
               ),
               Text(
-                "You can change it later in Settings",
+                !widget.isSettings ? "You can change it later in Settings" : "",
                 style: STextStyles.subtitle(context),
               ),
               const SizedBox(

From 60b332ad8ae135efb36c9a391f6b447d0112ace0 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 1 Nov 2022 14:16:31 -0600
Subject: [PATCH 089/426] auto backup drop down menu

---
 .../create_auto_backup.dart                   | 57 ++++++++++++-------
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 0c8c47c9e..16bda2ff7 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -34,7 +34,7 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
 
   String _currentDropDownValue = "Every 10 minutes";
 
-  final List<String> _dropDOwnItems = [
+  final List<String> _dropDownItems = [
     "Every 10 minutes",
     "Every 20 minutes",
     "Every 30 minutes",
@@ -352,25 +352,44 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
           const SizedBox(
             height: 10,
           ),
-          DropdownButton(
-            value: _currentDropDownValue,
-            items: _dropDOwnItems
-                .map(
-                  (e) => DropdownMenuItem(
-                    value: e,
-                    child: Text(e),
-                  ),
-                )
-                .toList(),
-            onChanged: (value) {
-              if (value is String) {
-                setState(() {
-                  _currentDropDownValue = value;
-                });
-              }
-            },
+          Padding(
+            padding: const EdgeInsets.only(
+              left: 32,
+              right: 32,
+            ),
+            child: DropdownButtonFormField(
+              isExpanded: true,
+              elevation: 0,
+              style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark,
+              ),
+              icon: SvgPicture.asset(
+                Assets.svg.chevronDown,
+                width: 10,
+                height: 5,
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
+              ),
+              dropdownColor:
+                  Theme.of(context).extension<StackColors>()!.textFieldActiveBG,
+              // focusColor: ,
+              value: _currentDropDownValue,
+              items: _dropDownItems
+                  .map(
+                    (e) => DropdownMenuItem(
+                      value: e,
+                      child: Text(e),
+                    ),
+                  )
+                  .toList(),
+              onChanged: (value) {
+                if (value is String) {
+                  setState(() {
+                    _currentDropDownValue = value;
+                  });
+                }
+              },
+            ),
           ),
-          const Spacer(),
           Padding(
             padding: const EdgeInsets.all(32),
             child: Row(

From 4d8804f78b6d5ad40cd38e677063beb886680b73 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 1 Nov 2022 15:58:41 -0600
Subject: [PATCH 090/426] WIP desktop send flow address book address chooser

---
 .../address_book_address_chooser.dart         | 143 +++++++++++++++
 .../sub_widgets/contact_list_item.dart        | 114 ++++++++++++
 .../wallet_view/sub_widgets/desktop_send.dart |  44 +++--
 lib/widgets/address_book_card.dart            | 168 ++++++++++--------
 4 files changed, 385 insertions(+), 84 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
new file mode 100644
index 000000000..372c86e2f
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
@@ -0,0 +1,143 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/models/contact.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart';
+import 'package:stackwallet/providers/global/address_book_service_provider.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+
+class AddressBookAddressChooser extends StatefulWidget {
+  const AddressBookAddressChooser({
+    Key? key,
+    this.coin,
+  }) : super(key: key);
+
+  final Coin? coin;
+
+  @override
+  State<AddressBookAddressChooser> createState() =>
+      _AddressBookAddressChooserState();
+}
+
+class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
+  int _compareContactFavorite(Contact a, Contact b) {
+    if (a.isFavorite && b.isFavorite) {
+      return 0;
+    } else if (a.isFavorite) {
+      return 1;
+    } else {
+      return -1;
+    }
+  }
+
+  List<Contact> pullOutFavorites(List<Contact> contacts) {
+    final List<Contact> favorites = [];
+    contacts.removeWhere((contact) {
+      if (contact.isFavorite) {
+        favorites.add(contact);
+        return true;
+      }
+      return false;
+    });
+
+    return favorites;
+  }
+
+  List<Contact> filter(List<Contact> contacts) {
+    if (widget.coin != null) {
+      contacts.removeWhere(
+          (e) => e.addresses.where((a) => a.coin == widget.coin!).isEmpty);
+    }
+
+    if (contacts.length < 2) {
+      return contacts;
+    }
+
+    contacts.sort(_compareContactFavorite);
+
+    // TODO: other filtering?
+
+    return contacts;
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        // search field
+        const TextField(),
+        const SizedBox(
+          height: 16,
+        ),
+        Expanded(
+          child: Padding(
+            padding: const EdgeInsets.only(
+              left: 32,
+              right: 32,
+              bottom: 32,
+            ),
+            child: Consumer(
+              builder: (context, ref, _) {
+                List<Contact> contacts = ref
+                    .watch(addressBookServiceProvider
+                        .select((value) => value.contacts))
+                    .toList();
+
+                contacts = filter(contacts);
+
+                final favorites = pullOutFavorites(contacts);
+
+                return ListView.builder(
+                  primary: false,
+                  shrinkWrap: true,
+                  itemCount: favorites.length +
+                      contacts.length +
+                      2, // +2 for "fav" and "all" headers
+                  itemBuilder: (context, index) {
+                    if (index == 0) {
+                      return Padding(
+                        padding: const EdgeInsets.only(
+                          bottom: 10,
+                        ),
+                        child: Text(
+                          "Favorites",
+                          style:
+                              STextStyles.desktopTextExtraExtraSmall(context),
+                        ),
+                      );
+                    } else if (index <= favorites.length) {
+                      final id = favorites[index - 1].id;
+                      return ContactListItem(
+                        key: Key("contactCard_${id}_key"),
+                        contactId: id,
+                        filterByCoin: widget.coin,
+                      );
+                    } else if (index == favorites.length + 1) {
+                      return Padding(
+                        padding: const EdgeInsets.symmetric(
+                          vertical: 10,
+                        ),
+                        child: Text(
+                          "All contacts",
+                          style:
+                              STextStyles.desktopTextExtraExtraSmall(context),
+                        ),
+                      );
+                    } else {
+                      final id = contacts[index - favorites.length - 1].id;
+                      return ContactListItem(
+                        key: Key("contactCard_${id}_key"),
+                        contactId: id,
+                        filterByCoin: widget.coin,
+                      );
+                    }
+                  },
+                );
+              },
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
new file mode 100644
index 000000000..593ae2bc4
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
@@ -0,0 +1,114 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/providers/global/address_book_service_provider.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/address_book_card.dart';
+import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/expandable.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
+
+class ContactListItem extends ConsumerWidget {
+  const ContactListItem({
+    Key? key,
+    required this.contactId,
+    this.filterByCoin,
+  }) : super(key: key);
+
+  final String contactId;
+  final Coin? filterByCoin;
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final contact = ref.watch(addressBookServiceProvider
+        .select((value) => value.getContactById(contactId)));
+
+    return RoundedWhiteContainer(
+      padding: const EdgeInsets.all(0),
+      borderColor: Theme.of(context).extension<StackColors>()!.background,
+      child: Expandable(
+        header: Padding(
+          padding: const EdgeInsets.symmetric(
+            horizontal: 20,
+            vertical: 14,
+          ),
+          child: AddressBookCard(
+            contactId: contactId,
+          ),
+        ),
+        body: Column(
+          mainAxisSize: MainAxisSize.min,
+          children: [
+            // filter addresses by coin is provided before building address list
+            ...contact.addresses
+                .where((e) =>
+                    filterByCoin != null ? e.coin == filterByCoin! : true)
+                .map(
+                  (e) => Column(
+                    key: Key("contactAddress_${e.address}_${e.label}_key"),
+                    mainAxisSize: MainAxisSize.min,
+                    children: [
+                      Container(
+                        height: 1,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .background,
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 20,
+                          vertical: 14,
+                        ),
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          children: [
+                            Row(
+                              children: [
+                                WalletInfoCoinIcon(coin: e.coin),
+                                const SizedBox(
+                                  width: 12,
+                                ),
+                                Column(
+                                  mainAxisSize: MainAxisSize.min,
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "${contactId == "default" ? e.other! : e.label} (${e.coin.ticker})",
+                                      style: STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          .copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textDark,
+                                      ),
+                                    ),
+                                    Text(
+                                      e.address,
+                                      style: STextStyles
+                                          .desktopTextExtraExtraSmall(context),
+                                    ),
+                                  ],
+                                ),
+                              ],
+                            ),
+                            BlueTextButton(
+                              text: "Select wallet",
+                              onTap: () {
+                                Navigator.of(context).pop(e);
+                              },
+                            ),
+                          ],
+                        ),
+                      )
+                    ],
+                  ),
+                ),
+          ],
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index a47b2b9dd..26f2f806c 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -5,17 +5,17 @@ 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/contact_address_entry.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';
 import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/firo_balance_selection_sheet.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/ui/fee_rate_type_state_provider.dart';
 import 'package:stackwallet/providers/ui/preview_tx_button_state_provider.dart';
 import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
-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/utilities/address_utils.dart';
@@ -42,7 +42,6 @@ import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.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';
-import 'package:tuple/tuple.dart';
 
 class DesktopSend extends ConsumerStatefulWidget {
   const DesktopSend({
@@ -330,10 +329,10 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             builder: (context) => DesktopDialog(
               maxHeight: double.infinity,
               maxWidth: 580,
-                  child: ConfirmTransactionView(
-                    transactionInfo: txData,
-                    walletId: walletId,
-                  ),
+              child: ConfirmTransactionView(
+                transactionInfo: txData,
+                walletId: walletId,
+              ),
             ),
           ),
         );
@@ -1184,11 +1183,34 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                       if (sendToController.text.isEmpty)
                         TextFieldIconButton(
                           key: const Key("sendViewAddressBookButtonKey"),
-                          onTap: () {
-                            Navigator.of(context).pushNamed(
-                              AddressBookView.routeName,
-                              arguments: coin,
+                          onTap: () async {
+                            final entry =
+                                await showDialog<ContactAddressEntry?>(
+                              context: context,
+                              builder: (context) => DesktopDialog(
+                                maxWidth: 696,
+                                maxHeight: 600,
+                                child: AddressBookAddressChooser(
+                                  coin: coin,
+                                ),
+                              ),
                             );
+
+                            if (entry != null) {
+                              sendToController.text =
+                                  entry.other ?? entry.label;
+
+                              _address = entry.address;
+
+                              _updatePreviewButtonState(
+                                _address,
+                                _amountToSend,
+                              );
+
+                              setState(() {
+                                _addressToggleFlag = true;
+                              });
+                            }
                           },
                           child: const AddressBookIcon(),
                         ),
diff --git a/lib/widgets/address_book_card.dart b/lib/widgets/address_book_card.dart
index 7a2fca19f..6a51edbad 100644
--- a/lib/widgets/address_book_card.dart
+++ b/lib/widgets/address_book_card.dart
@@ -8,6 +8,8 @@ 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';
+import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class AddressBookCard extends ConsumerStatefulWidget {
@@ -21,11 +23,12 @@ class AddressBookCard extends ConsumerStatefulWidget {
 
 class _AddressBookCardState extends ConsumerState<AddressBookCard> {
   late final String contactId;
+  late final bool isDesktop;
 
   @override
   void initState() {
     contactId = widget.contactId;
-
+    isDesktop = Util.isDesktop;
     super.initState();
   }
 
@@ -51,82 +54,101 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
       }
     }
 
-    return RoundedWhiteContainer(
-      padding: const EdgeInsets.all(4),
-      child: RawMaterialButton(
-        // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-        padding: const EdgeInsets.all(0),
-        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-        shape: RoundedRectangleBorder(
-          borderRadius: BorderRadius.circular(
-            Constants.size.circularBorderRadius,
-          ),
-        ),
-        onPressed: () {
-          showDialog<void>(
-            context: context,
-            useSafeArea: true,
-            barrierDismissible: true,
-            builder: (_) => ContactPopUp(
-              contactId: contact.id,
+    return ConditionalParent(
+      condition: !isDesktop,
+      child: Row(
+        children: [
+          Container(
+            width: 32,
+            height: 32,
+            decoration: BoxDecoration(
+              color: contact.id == "default"
+                  ? Theme.of(context)
+                      .extension<StackColors>()!
+                      .myStackContactIconBG
+                  : Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldDefaultBG,
+              borderRadius: BorderRadius.circular(32),
             ),
-          );
-        },
-        child: Padding(
-          padding: const EdgeInsets.all(8.0),
-          child: Row(
-            children: [
-              Container(
-                width: 32,
-                height: 32,
-                decoration: BoxDecoration(
-                  color: contact.id == "default"
-                      ? Theme.of(context)
-                          .extension<StackColors>()!
-                          .myStackContactIconBG
-                      : Theme.of(context)
-                          .extension<StackColors>()!
-                          .textFieldDefaultBG,
-                  borderRadius: BorderRadius.circular(32),
-                ),
-                child: contact.id == "default"
+            child: contact.id == "default"
+                ? Center(
+                    child: SvgPicture.asset(
+                      Assets.svg.stackIcon(context),
+                      width: 20,
+                    ),
+                  )
+                : contact.emojiChar != null
                     ? Center(
-                        child: SvgPicture.asset(
-                          Assets.svg.stackIcon(context),
-                          width: 20,
-                        ),
+                        child: Text(contact.emojiChar!),
                       )
-                    : contact.emojiChar != null
-                        ? Center(
-                            child: Text(contact.emojiChar!),
-                          )
-                        : Center(
-                            child: SvgPicture.asset(
-                              Assets.svg.user,
-                              width: 18,
-                            ),
-                          ),
+                    : Center(
+                        child: SvgPicture.asset(
+                          Assets.svg.user,
+                          width: 18,
+                        ),
+                      ),
+          ),
+          const SizedBox(
+            width: 12,
+          ),
+          if (isDesktop)
+            Text(
+              contact.name,
+              style: STextStyles.itemSubtitle12(context),
+            ),
+          if (isDesktop)
+            const SizedBox(
+              width: 16,
+            ),
+          if (isDesktop)
+            Text(
+              coinsString,
+              style: STextStyles.label(context),
+            ),
+          if (!isDesktop)
+            Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                Text(
+                  contact.name,
+                  style: STextStyles.itemSubtitle12(context),
+                ),
+                const SizedBox(
+                  height: 4,
+                ),
+                Text(
+                  coinsString,
+                  style: STextStyles.label(context),
+                ),
+              ],
+            )
+        ],
+      ),
+      builder: (child) => RoundedWhiteContainer(
+        padding: const EdgeInsets.all(4),
+        child: RawMaterialButton(
+          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+          padding: const EdgeInsets.all(0),
+          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+          ),
+          onPressed: () {
+            showDialog<void>(
+              context: context,
+              useSafeArea: true,
+              barrierDismissible: true,
+              builder: (_) => ContactPopUp(
+                contactId: contact.id,
               ),
-              const SizedBox(
-                width: 12,
-              ),
-              Column(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  Text(
-                    contact.name,
-                    style: STextStyles.itemSubtitle12(context),
-                  ),
-                  const SizedBox(
-                    height: 4,
-                  ),
-                  Text(
-                    coinsString,
-                    style: STextStyles.label(context),
-                  ),
-                ],
-              )
-            ],
+            );
+          },
+          child: Padding(
+            padding: const EdgeInsets.all(8.0),
+            child: child,
           ),
         ),
       ),

From 6d8142d66a71e167431ca09ee6ffd47fcd7ff395 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 1 Nov 2022 16:04:38 -0600
Subject: [PATCH 091/426] code formatting

---
 lib/pages/stack_privacy_calls.dart | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index 3d1a071a0..7e981b91a 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -3,9 +3,12 @@ import 'dart:async';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
 import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/global/price_provider.dart';
+import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -14,13 +17,9 @@ import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import '../hive/db.dart';
-import '../providers/global/price_provider.dart';
-import '../services/exchange/exchange_data_loading_service.dart';
-import '../widgets/desktop/primary_button.dart';
-
 class StackPrivacyCalls extends ConsumerStatefulWidget {
   const StackPrivacyCalls({
     Key? key,
@@ -90,7 +89,9 @@ class _StackPrivacyCalls extends ConsumerState<StackPrivacyCalls> {
                   height: isDesktop ? 16 : 8,
                 ),
                 Text(
-    !widget.isSettings ? "You can change it later in Settings" : "",
+                  !widget.isSettings
+                      ? "You can change it later in Settings"
+                      : "",
                   style: isDesktop
                       ? STextStyles.desktopSubtitleH2(context)
                       : STextStyles.subtitle(context),

From 6ebe33c3129bd4599ee35477b9bcb9d345e2e06c Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 1 Nov 2022 16:13:07 -0600
Subject: [PATCH 092/426] temporarily commented out failing widget tests due to
 platform differences with desktop modifications

---
 test/widget_tests/address_book_card_test.dart |  97 +--
 test/widget_tests/transaction_card_test.dart  | 734 +++++++++---------
 2 files changed, 400 insertions(+), 431 deletions(-)

diff --git a/test/widget_tests/address_book_card_test.dart b/test/widget_tests/address_book_card_test.dart
index ef031eb4e..8c8c44abd 100644
--- a/test/widget_tests/address_book_card_test.dart
+++ b/test/widget_tests/address_book_card_test.dart
@@ -1,19 +1,6 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_test/flutter_test.dart';
 import 'package:mockito/annotations.dart';
 import 'package:mockito/mockito.dart';
-import 'package:stackwallet/models/contact.dart';
-import 'package:stackwallet/models/contact_address_entry.dart';
-import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
-import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/services/address_book_service.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/theme/light_colors.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
-import 'package:stackwallet/widgets/address_book_card.dart';
-
-import 'address_book_card_test.mocks.dart';
 
 class MockedFunctions extends Mock {
   void showDialog();
@@ -21,46 +8,46 @@ class MockedFunctions extends Mock {
 
 @GenerateMocks([AddressBookService])
 void main() {
-  testWidgets('test returns Contact Address Entry', (widgetTester) async {
-    final service = MockAddressBookService();
-
-    when(service.getContactById("default"))
-        .thenAnswer((realInvocation) => Contact(
-            name: "John Doe",
-            addresses: [
-              const ContactAddressEntry(
-                  coin: Coin.bitcoincash,
-                  address: "some bch address",
-                  label: "Bills")
-            ],
-            isFavorite: true));
-
-    await widgetTester.pumpWidget(
-      ProviderScope(
-        overrides: [
-          addressBookServiceProvider.overrideWithValue(
-            service,
-          ),
-        ],
-        child: MaterialApp(
-          theme: ThemeData(
-            extensions: [
-              StackColors.fromStackColorTheme(
-                LightColors(),
-              ),
-            ],
-          ),
-          home: const AddressBookCard(
-            contactId: "default",
-          ),
-        ),
-      ),
-    );
-
-    expect(find.text("John Doe"), findsOneWidget);
-    expect(find.text("BCH"), findsOneWidget);
-    expect(find.text(Coin.bitcoincash.ticker), findsOneWidget);
-
-    await widgetTester.tap(find.byType(RawMaterialButton));
-  });
+  // testWidgets('test returns Contact Address Entry', (widgetTester) async {
+  //   final service = MockAddressBookService();
+  //
+  //   when(service.getContactById("default"))
+  //       .thenAnswer((realInvocation) => Contact(
+  //           name: "John Doe",
+  //           addresses: [
+  //             const ContactAddressEntry(
+  //                 coin: Coin.bitcoincash,
+  //                 address: "some bch address",
+  //                 label: "Bills")
+  //           ],
+  //           isFavorite: true));
+  //
+  //   await widgetTester.pumpWidget(
+  //     ProviderScope(
+  //       overrides: [
+  //         addressBookServiceProvider.overrideWithValue(
+  //           service,
+  //         ),
+  //       ],
+  //       child: MaterialApp(
+  //         theme: ThemeData(
+  //           extensions: [
+  //             StackColors.fromStackColorTheme(
+  //               LightColors(),
+  //             ),
+  //           ],
+  //         ),
+  //         home: const AddressBookCard(
+  //           contactId: "default",
+  //         ),
+  //       ),
+  //     ),
+  //   );
+  //
+  //   expect(find.text("John Doe"), findsOneWidget);
+  //   expect(find.text("BCH"), findsOneWidget);
+  //   expect(find.text(Coin.bitcoincash.ticker), findsOneWidget);
+  //
+  //   await widgetTester.tap(find.byType(RawMaterialButton));
+  // });
 }
diff --git a/test/widget_tests/transaction_card_test.dart b/test/widget_tests/transaction_card_test.dart
index 3f46794bd..6c36fce8d 100644
--- a/test/widget_tests/transaction_card_test.dart
+++ b/test/widget_tests/transaction_card_test.dart
@@ -1,13 +1,4 @@
-import 'package:decimal/decimal.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_feather_icons/flutter_feather_icons.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:mockingjay/mockingjay.dart' as mockingjay;
 import 'package:mockito/annotations.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:mockito/mockito.dart';
-import 'package:stackwallet/models/models.dart';
-import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/coins/coin_service.dart';
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
 import 'package:stackwallet/services/coins/manager.dart';
@@ -15,16 +6,7 @@ import 'package:stackwallet/services/locale_service.dart';
 import 'package:stackwallet/services/notes_service.dart';
 import 'package:stackwallet/services/price_service.dart';
 import 'package:stackwallet/services/wallets.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/listenable_map.dart';
 import 'package:stackwallet/utilities/prefs.dart';
-import 'package:stackwallet/widgets/transaction_card.dart';
-import 'package:stackwallet/utilities/theme/light_colors.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
-import 'package:tuple/tuple.dart';
-
-import 'transaction_card_test.mocks.dart';
 
 @GenerateMocks([
   Wallets,
@@ -37,362 +19,362 @@ import 'transaction_card_test.mocks.dart';
   NotesService
 ], customMocks: [])
 void main() {
-  TestWidgetsFlutterBinding.ensureInitialized();
-  testWidgets("Sent confirmed tx displays correctly", (tester) async {
-    final mockManager = MockManager();
-    final mockLocaleService = MockLocaleService();
-    final wallets = MockWallets();
-    final mockPrefs = MockPrefs();
-    final mockPriceService = MockPriceService();
-
-    final tx = Transaction(
-        txid: "some txid",
-        confirmedStatus: true,
-        timestamp: 1648595998,
-        txType: "Sent",
-        amount: 100000000,
-        aliens: [],
-        worthNow: "0.01",
-        worthAtBlockTimestamp: "0.01",
-        fees: 3794,
-        inputSize: 1,
-        outputSize: 1,
-        inputs: [],
-        outputs: [],
-        address: "",
-        height: 450123,
-        subType: "",
-        confirmations: 10,
-        isCancelled: false);
-
-    final CoinServiceAPI wallet = MockFiroWallet();
-
-    when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
-    when(mockLocaleService.locale).thenAnswer((_) => "en_US");
-    when(mockPrefs.currency).thenAnswer((_) => "USD");
-    when(mockPrefs.externalCalls).thenAnswer((_) => true);
-    when(mockPriceService.getPrice(Coin.firo))
-        .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
-
-    when(wallet.coin).thenAnswer((_) => Coin.firo);
-
-    when(wallets.getManager("wallet-id"))
-        .thenAnswer((realInvocation) => Manager(wallet));
-    //
-    await tester.pumpWidget(
-      ProviderScope(
-        overrides: [
-          walletsChangeNotifierProvider.overrideWithValue(wallets),
-          localeServiceChangeNotifierProvider
-              .overrideWithValue(mockLocaleService),
-          prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
-          priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
-        ],
-        child: MaterialApp(
-          theme: ThemeData(
-            extensions: [
-              StackColors.fromStackColorTheme(
-                LightColors(),
-              ),
-            ],
-          ),
-          home: TransactionCard(transaction: tx, walletId: "wallet-id"),
-        ),
-      ),
-    );
-
-    //
-    final title = find.text("Sent");
-    // final price1 = find.text("0.00 USD");
-    final amount = find.text("1.00000000 FIRO");
-
-    final icon = find.byIcon(FeatherIcons.arrowUp);
-
-    expect(title, findsOneWidget);
-    // expect(price1, findsOneWidget);
-    expect(amount, findsOneWidget);
-    // expect(icon, findsOneWidget);
-    //
-    await tester.pumpAndSettle(Duration(seconds: 2));
-    //
-    // final price2 = find.text("\$10.00");
-    // expect(price2, findsOneWidget);
-    //
-    // verify(mockManager.addListener(any)).called(1);
-    verify(mockLocaleService.addListener(any)).called(1);
-
-    verify(mockPrefs.currency).called(1);
-    verify(mockPriceService.getPrice(Coin.firo)).called(1);
-    verify(wallet.coin.ticker).called(1);
-
-    verify(mockLocaleService.locale).called(1);
-
-    verifyNoMoreInteractions(mockManager);
-    verifyNoMoreInteractions(mockLocaleService);
-  });
-
-  testWidgets("Anonymized confirmed tx displays correctly", (tester) async {
-    final mockManager = MockManager();
-    final mockLocaleService = MockLocaleService();
-    final wallets = MockWallets();
-    final mockPrefs = MockPrefs();
-    final mockPriceService = MockPriceService();
-
-    final tx = Transaction(
-        txid: "some txid",
-        confirmedStatus: true,
-        timestamp: 1648595998,
-        txType: "Anonymized",
-        amount: 100000000,
-        aliens: [],
-        worthNow: "0.01",
-        worthAtBlockTimestamp: "0.01",
-        fees: 3794,
-        inputSize: 1,
-        outputSize: 1,
-        inputs: [],
-        outputs: [],
-        address: "",
-        height: 450123,
-        subType: "mint",
-        confirmations: 10,
-        isCancelled: false);
-
-    final CoinServiceAPI wallet = MockFiroWallet();
-
-    when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
-    when(mockLocaleService.locale).thenAnswer((_) => "en_US");
-    when(mockPrefs.currency).thenAnswer((_) => "USD");
-    when(mockPrefs.externalCalls).thenAnswer((_) => true);
-    when(mockPriceService.getPrice(Coin.firo))
-        .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
-
-    when(wallet.coin).thenAnswer((_) => Coin.firo);
-
-    when(wallets.getManager("wallet-id"))
-        .thenAnswer((realInvocation) => Manager(wallet));
-    //
-    await tester.pumpWidget(
-      ProviderScope(
-        overrides: [
-          walletsChangeNotifierProvider.overrideWithValue(wallets),
-          localeServiceChangeNotifierProvider
-              .overrideWithValue(mockLocaleService),
-          prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
-          priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
-        ],
-        child: MaterialApp(
-          theme: ThemeData(
-            extensions: [
-              StackColors.fromStackColorTheme(
-                LightColors(),
-              ),
-            ],
-          ),
-          home: TransactionCard(transaction: tx, walletId: "wallet-id"),
-        ),
-      ),
-    );
-
-    //
-    final title = find.text("Anonymized");
-    // final price1 = find.text("0.00 USD");
-    final amount = find.text("1.00000000 FIRO");
-
-    final icon = find.byIcon(FeatherIcons.arrowUp);
-
-    expect(title, findsOneWidget);
-    // expect(price1, findsOneWidget);
-    expect(amount, findsOneWidget);
-    // expect(icon, findsOneWidget);
-    //
-    await tester.pumpAndSettle(Duration(seconds: 2));
-    //
-    // final price2 = find.text("\$10.00");
-    // expect(price2, findsOneWidget);
-    //
-    // verify(mockManager.addListener(any)).called(1);
-    verify(mockLocaleService.addListener(any)).called(1);
-
-    verify(mockPrefs.currency).called(1);
-    verify(mockPriceService.getPrice(Coin.firo)).called(1);
-    verify(wallet.coin.ticker).called(1);
-
-    verify(mockLocaleService.locale).called(1);
-
-    verifyNoMoreInteractions(mockManager);
-    verifyNoMoreInteractions(mockLocaleService);
-  });
-
-  testWidgets("Received unconfirmed tx displays correctly", (tester) async {
-    final mockManager = MockManager();
-    final mockLocaleService = MockLocaleService();
-    final wallets = MockWallets();
-    final mockPrefs = MockPrefs();
-    final mockPriceService = MockPriceService();
-
-    final tx = Transaction(
-      txid: "some txid",
-      confirmedStatus: false,
-      timestamp: 1648595998,
-      txType: "Received",
-      amount: 100000000,
-      aliens: [],
-      worthNow: "0.01",
-      worthAtBlockTimestamp: "0.01",
-      fees: 3794,
-      inputSize: 1,
-      outputSize: 1,
-      inputs: [],
-      outputs: [],
-      address: "",
-      height: 0,
-      subType: "",
-      confirmations: 0,
-    );
-
-    final CoinServiceAPI wallet = MockFiroWallet();
-
-    when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
-    when(mockLocaleService.locale).thenAnswer((_) => "en_US");
-    when(mockPrefs.currency).thenAnswer((_) => "USD");
-    when(mockPrefs.externalCalls).thenAnswer((_) => true);
-    when(mockPriceService.getPrice(Coin.firo))
-        .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
-
-    when(wallet.coin).thenAnswer((_) => Coin.firo);
-
-    when(wallets.getManager("wallet-id"))
-        .thenAnswer((realInvocation) => Manager(wallet));
-
-    await tester.pumpWidget(
-      ProviderScope(
-        overrides: [
-          walletsChangeNotifierProvider.overrideWithValue(wallets),
-          localeServiceChangeNotifierProvider
-              .overrideWithValue(mockLocaleService),
-          prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
-          priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
-        ],
-        child: MaterialApp(
-          theme: ThemeData(
-            extensions: [
-              StackColors.fromStackColorTheme(
-                LightColors(),
-              ),
-            ],
-          ),
-          home: TransactionCard(transaction: tx, walletId: "wallet-id"),
-        ),
-      ),
-    );
-
-    final title = find.text("Receiving");
-    final amount = find.text("1.00000000 FIRO");
-
-    expect(title, findsOneWidget);
-    expect(amount, findsOneWidget);
-
-    await tester.pumpAndSettle(Duration(seconds: 2));
-
-    verify(mockLocaleService.addListener(any)).called(1);
-
-    verify(mockPrefs.currency).called(1);
-    verify(mockPriceService.getPrice(Coin.firo)).called(1);
-    verify(wallet.coin.ticker).called(1);
-
-    verify(mockLocaleService.locale).called(1);
-
-    verifyNoMoreInteractions(mockManager);
-    verifyNoMoreInteractions(mockLocaleService);
-  });
-
-  testWidgets("Tap gesture", (tester) async {
-    final mockManager = MockManager();
-    final mockLocaleService = MockLocaleService();
-    final wallets = MockWallets();
-    final mockPrefs = MockPrefs();
-    final mockPriceService = MockPriceService();
-    final navigator = mockingjay.MockNavigator();
-
-    final tx = Transaction(
-      txid: "some txid",
-      confirmedStatus: false,
-      timestamp: 1648595998,
-      txType: "Received",
-      amount: 100000000,
-      aliens: [],
-      worthNow: "0.01",
-      worthAtBlockTimestamp: "0.01",
-      fees: 3794,
-      inputSize: 1,
-      outputSize: 1,
-      inputs: [],
-      outputs: [],
-      address: "",
-      height: 250,
-      subType: "",
-      confirmations: 10,
-    );
-
-    final CoinServiceAPI wallet = MockFiroWallet();
-
-    when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
-    when(mockLocaleService.locale).thenAnswer((_) => "en_US");
-    when(mockPrefs.currency).thenAnswer((_) => "USD");
-    when(mockPrefs.externalCalls).thenAnswer((_) => true);
-    when(mockPriceService.getPrice(Coin.firo))
-        .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
-
-    when(wallet.coin).thenAnswer((_) => Coin.firo);
-
-    when(wallets.getManager("wallet id"))
-        .thenAnswer((realInvocation) => Manager(wallet));
-
-    mockingjay
-        .when(() => navigator.pushNamed("/transactionDetails",
-            arguments: Tuple3(tx, Coin.firo, "wallet id")))
-        .thenAnswer((_) async => {});
-
-    await tester.pumpWidget(
-      ProviderScope(
-        overrides: [
-          walletsChangeNotifierProvider.overrideWithValue(wallets),
-          localeServiceChangeNotifierProvider
-              .overrideWithValue(mockLocaleService),
-          prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
-          priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
-        ],
-        child: MaterialApp(
-          theme: ThemeData(
-            extensions: [
-              StackColors.fromStackColorTheme(LightColors()),
-            ],
-          ),
-          home: mockingjay.MockNavigatorProvider(
-              navigator: navigator,
-              child: TransactionCard(transaction: tx, walletId: "wallet id")),
-        ),
-      ),
-    );
-
-    expect(find.byType(GestureDetector), findsOneWidget);
-
-    await tester.tap(find.byType(GestureDetector));
-    await tester.pump();
-
-    verify(mockLocaleService.addListener(any)).called(1);
-
-    verify(mockPrefs.currency).called(1);
-    verify(mockLocaleService.locale).called(1);
-    verify(wallet.coin.ticker).called(1);
-
-    verifyNoMoreInteractions(wallet);
-    verifyNoMoreInteractions(mockLocaleService);
-
-    mockingjay
-        .verify(() => navigator.pushNamed("/transactionDetails",
-            arguments: Tuple3(tx, Coin.firo, "wallet id")))
-        .called(1);
-  });
+  // TestWidgetsFlutterBinding.ensureInitialized();
+  // testWidgets("Sent confirmed tx displays correctly", (tester) async {
+  //   final mockManager = MockManager();
+  //   final mockLocaleService = MockLocaleService();
+  //   final wallets = MockWallets();
+  //   final mockPrefs = MockPrefs();
+  //   final mockPriceService = MockPriceService();
+  //
+  //   final tx = Transaction(
+  //       txid: "some txid",
+  //       confirmedStatus: true,
+  //       timestamp: 1648595998,
+  //       txType: "Sent",
+  //       amount: 100000000,
+  //       aliens: [],
+  //       worthNow: "0.01",
+  //       worthAtBlockTimestamp: "0.01",
+  //       fees: 3794,
+  //       inputSize: 1,
+  //       outputSize: 1,
+  //       inputs: [],
+  //       outputs: [],
+  //       address: "",
+  //       height: 450123,
+  //       subType: "",
+  //       confirmations: 10,
+  //       isCancelled: false);
+  //
+  //   final CoinServiceAPI wallet = MockFiroWallet();
+  //
+  //   when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
+  //   when(mockLocaleService.locale).thenAnswer((_) => "en_US");
+  //   when(mockPrefs.currency).thenAnswer((_) => "USD");
+  //   when(mockPrefs.externalCalls).thenAnswer((_) => true);
+  //   when(mockPriceService.getPrice(Coin.firo))
+  //       .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
+  //
+  //   when(wallet.coin).thenAnswer((_) => Coin.firo);
+  //
+  //   when(wallets.getManager("wallet-id"))
+  //       .thenAnswer((realInvocation) => Manager(wallet));
+  //   //
+  //   await tester.pumpWidget(
+  //     ProviderScope(
+  //       overrides: [
+  //         walletsChangeNotifierProvider.overrideWithValue(wallets),
+  //         localeServiceChangeNotifierProvider
+  //             .overrideWithValue(mockLocaleService),
+  //         prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
+  //         priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
+  //       ],
+  //       child: MaterialApp(
+  //         theme: ThemeData(
+  //           extensions: [
+  //             StackColors.fromStackColorTheme(
+  //               LightColors(),
+  //             ),
+  //           ],
+  //         ),
+  //         home: TransactionCard(transaction: tx, walletId: "wallet-id"),
+  //       ),
+  //     ),
+  //   );
+  //
+  //   //
+  //   final title = find.text("Sent");
+  //   // final price1 = find.text("0.00 USD");
+  //   final amount = find.text("1.00000000 FIRO");
+  //
+  //   final icon = find.byIcon(FeatherIcons.arrowUp);
+  //
+  //   expect(title, findsOneWidget);
+  //   // expect(price1, findsOneWidget);
+  //   expect(amount, findsOneWidget);
+  //   // expect(icon, findsOneWidget);
+  //   //
+  //   await tester.pumpAndSettle(Duration(seconds: 2));
+  //   //
+  //   // final price2 = find.text("\$10.00");
+  //   // expect(price2, findsOneWidget);
+  //   //
+  //   // verify(mockManager.addListener(any)).called(1);
+  //   verify(mockLocaleService.addListener(any)).called(1);
+  //
+  //   verify(mockPrefs.currency).called(1);
+  //   verify(mockPriceService.getPrice(Coin.firo)).called(1);
+  //   verify(wallet.coin.ticker).called(1);
+  //
+  //   verify(mockLocaleService.locale).called(1);
+  //
+  //   verifyNoMoreInteractions(mockManager);
+  //   verifyNoMoreInteractions(mockLocaleService);
+  // });
+  //
+  // testWidgets("Anonymized confirmed tx displays correctly", (tester) async {
+  //   final mockManager = MockManager();
+  //   final mockLocaleService = MockLocaleService();
+  //   final wallets = MockWallets();
+  //   final mockPrefs = MockPrefs();
+  //   final mockPriceService = MockPriceService();
+  //
+  //   final tx = Transaction(
+  //       txid: "some txid",
+  //       confirmedStatus: true,
+  //       timestamp: 1648595998,
+  //       txType: "Anonymized",
+  //       amount: 100000000,
+  //       aliens: [],
+  //       worthNow: "0.01",
+  //       worthAtBlockTimestamp: "0.01",
+  //       fees: 3794,
+  //       inputSize: 1,
+  //       outputSize: 1,
+  //       inputs: [],
+  //       outputs: [],
+  //       address: "",
+  //       height: 450123,
+  //       subType: "mint",
+  //       confirmations: 10,
+  //       isCancelled: false);
+  //
+  //   final CoinServiceAPI wallet = MockFiroWallet();
+  //
+  //   when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
+  //   when(mockLocaleService.locale).thenAnswer((_) => "en_US");
+  //   when(mockPrefs.currency).thenAnswer((_) => "USD");
+  //   when(mockPrefs.externalCalls).thenAnswer((_) => true);
+  //   when(mockPriceService.getPrice(Coin.firo))
+  //       .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
+  //
+  //   when(wallet.coin).thenAnswer((_) => Coin.firo);
+  //
+  //   when(wallets.getManager("wallet-id"))
+  //       .thenAnswer((realInvocation) => Manager(wallet));
+  //   //
+  //   await tester.pumpWidget(
+  //     ProviderScope(
+  //       overrides: [
+  //         walletsChangeNotifierProvider.overrideWithValue(wallets),
+  //         localeServiceChangeNotifierProvider
+  //             .overrideWithValue(mockLocaleService),
+  //         prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
+  //         priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
+  //       ],
+  //       child: MaterialApp(
+  //         theme: ThemeData(
+  //           extensions: [
+  //             StackColors.fromStackColorTheme(
+  //               LightColors(),
+  //             ),
+  //           ],
+  //         ),
+  //         home: TransactionCard(transaction: tx, walletId: "wallet-id"),
+  //       ),
+  //     ),
+  //   );
+  //
+  //   //
+  //   final title = find.text("Anonymized");
+  //   // final price1 = find.text("0.00 USD");
+  //   final amount = find.text("1.00000000 FIRO");
+  //
+  //   final icon = find.byIcon(FeatherIcons.arrowUp);
+  //
+  //   expect(title, findsOneWidget);
+  //   // expect(price1, findsOneWidget);
+  //   expect(amount, findsOneWidget);
+  //   // expect(icon, findsOneWidget);
+  //   //
+  //   await tester.pumpAndSettle(Duration(seconds: 2));
+  //   //
+  //   // final price2 = find.text("\$10.00");
+  //   // expect(price2, findsOneWidget);
+  //   //
+  //   // verify(mockManager.addListener(any)).called(1);
+  //   verify(mockLocaleService.addListener(any)).called(1);
+  //
+  //   verify(mockPrefs.currency).called(1);
+  //   verify(mockPriceService.getPrice(Coin.firo)).called(1);
+  //   verify(wallet.coin.ticker).called(1);
+  //
+  //   verify(mockLocaleService.locale).called(1);
+  //
+  //   verifyNoMoreInteractions(mockManager);
+  //   verifyNoMoreInteractions(mockLocaleService);
+  // });
+  //
+  // testWidgets("Received unconfirmed tx displays correctly", (tester) async {
+  //   final mockManager = MockManager();
+  //   final mockLocaleService = MockLocaleService();
+  //   final wallets = MockWallets();
+  //   final mockPrefs = MockPrefs();
+  //   final mockPriceService = MockPriceService();
+  //
+  //   final tx = Transaction(
+  //     txid: "some txid",
+  //     confirmedStatus: false,
+  //     timestamp: 1648595998,
+  //     txType: "Received",
+  //     amount: 100000000,
+  //     aliens: [],
+  //     worthNow: "0.01",
+  //     worthAtBlockTimestamp: "0.01",
+  //     fees: 3794,
+  //     inputSize: 1,
+  //     outputSize: 1,
+  //     inputs: [],
+  //     outputs: [],
+  //     address: "",
+  //     height: 0,
+  //     subType: "",
+  //     confirmations: 0,
+  //   );
+  //
+  //   final CoinServiceAPI wallet = MockFiroWallet();
+  //
+  //   when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
+  //   when(mockLocaleService.locale).thenAnswer((_) => "en_US");
+  //   when(mockPrefs.currency).thenAnswer((_) => "USD");
+  //   when(mockPrefs.externalCalls).thenAnswer((_) => true);
+  //   when(mockPriceService.getPrice(Coin.firo))
+  //       .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
+  //
+  //   when(wallet.coin).thenAnswer((_) => Coin.firo);
+  //
+  //   when(wallets.getManager("wallet-id"))
+  //       .thenAnswer((realInvocation) => Manager(wallet));
+  //
+  //   await tester.pumpWidget(
+  //     ProviderScope(
+  //       overrides: [
+  //         walletsChangeNotifierProvider.overrideWithValue(wallets),
+  //         localeServiceChangeNotifierProvider
+  //             .overrideWithValue(mockLocaleService),
+  //         prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
+  //         priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
+  //       ],
+  //       child: MaterialApp(
+  //         theme: ThemeData(
+  //           extensions: [
+  //             StackColors.fromStackColorTheme(
+  //               LightColors(),
+  //             ),
+  //           ],
+  //         ),
+  //         home: TransactionCard(transaction: tx, walletId: "wallet-id"),
+  //       ),
+  //     ),
+  //   );
+  //
+  //   final title = find.text("Receiving");
+  //   final amount = find.text("1.00000000 FIRO");
+  //
+  //   expect(title, findsOneWidget);
+  //   expect(amount, findsOneWidget);
+  //
+  //   await tester.pumpAndSettle(Duration(seconds: 2));
+  //
+  //   verify(mockLocaleService.addListener(any)).called(1);
+  //
+  //   verify(mockPrefs.currency).called(1);
+  //   verify(mockPriceService.getPrice(Coin.firo)).called(1);
+  //   verify(wallet.coin.ticker).called(1);
+  //
+  //   verify(mockLocaleService.locale).called(1);
+  //
+  //   verifyNoMoreInteractions(mockManager);
+  //   verifyNoMoreInteractions(mockLocaleService);
+  // });
+  //
+  // testWidgets("Tap gesture", (tester) async {
+  //   final mockManager = MockManager();
+  //   final mockLocaleService = MockLocaleService();
+  //   final wallets = MockWallets();
+  //   final mockPrefs = MockPrefs();
+  //   final mockPriceService = MockPriceService();
+  //   final navigator = mockingjay.MockNavigator();
+  //
+  //   final tx = Transaction(
+  //     txid: "some txid",
+  //     confirmedStatus: false,
+  //     timestamp: 1648595998,
+  //     txType: "Received",
+  //     amount: 100000000,
+  //     aliens: [],
+  //     worthNow: "0.01",
+  //     worthAtBlockTimestamp: "0.01",
+  //     fees: 3794,
+  //     inputSize: 1,
+  //     outputSize: 1,
+  //     inputs: [],
+  //     outputs: [],
+  //     address: "",
+  //     height: 250,
+  //     subType: "",
+  //     confirmations: 10,
+  //   );
+  //
+  //   final CoinServiceAPI wallet = MockFiroWallet();
+  //
+  //   when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
+  //   when(mockLocaleService.locale).thenAnswer((_) => "en_US");
+  //   when(mockPrefs.currency).thenAnswer((_) => "USD");
+  //   when(mockPrefs.externalCalls).thenAnswer((_) => true);
+  //   when(mockPriceService.getPrice(Coin.firo))
+  //       .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
+  //
+  //   when(wallet.coin).thenAnswer((_) => Coin.firo);
+  //
+  //   when(wallets.getManager("wallet id"))
+  //       .thenAnswer((realInvocation) => Manager(wallet));
+  //
+  //   mockingjay
+  //       .when(() => navigator.pushNamed("/transactionDetails",
+  //           arguments: Tuple3(tx, Coin.firo, "wallet id")))
+  //       .thenAnswer((_) async => {});
+  //
+  //   await tester.pumpWidget(
+  //     ProviderScope(
+  //       overrides: [
+  //         walletsChangeNotifierProvider.overrideWithValue(wallets),
+  //         localeServiceChangeNotifierProvider
+  //             .overrideWithValue(mockLocaleService),
+  //         prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
+  //         priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
+  //       ],
+  //       child: MaterialApp(
+  //         theme: ThemeData(
+  //           extensions: [
+  //             StackColors.fromStackColorTheme(LightColors()),
+  //           ],
+  //         ),
+  //         home: mockingjay.MockNavigatorProvider(
+  //             navigator: navigator,
+  //             child: TransactionCard(transaction: tx, walletId: "wallet id")),
+  //       ),
+  //     ),
+  //   );
+  //
+  //   expect(find.byType(GestureDetector), findsOneWidget);
+  //
+  //   await tester.tap(find.byType(GestureDetector));
+  //   await tester.pump();
+  //
+  //   verify(mockLocaleService.addListener(any)).called(1);
+  //
+  //   verify(mockPrefs.currency).called(1);
+  //   verify(mockLocaleService.locale).called(1);
+  //   verify(wallet.coin.ticker).called(1);
+  //
+  //   verifyNoMoreInteractions(wallet);
+  //   verifyNoMoreInteractions(mockLocaleService);
+  //
+  //   mockingjay
+  //       .verify(() => navigator.pushNamed("/transactionDetails",
+  //           arguments: Tuple3(tx, Coin.firo, "wallet id")))
+  //       .called(1);
+  // });
 }

From 1d47832718addb4621cbabeb3fe53a70a26348c6 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 1 Nov 2022 16:39:47 -0600
Subject: [PATCH 093/426] WIP: needs popup for stack experience and debug info

---
 .../home/settings_menu/advanced_settings.dart | 153 ++++++++++++++++--
 1 file changed, 140 insertions(+), 13 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart
index e470a73aa..e55326527 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart
@@ -2,11 +2,16 @@ import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages/stack_privacy_calls.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
+import '../../../pages/settings_views/global_settings_view/advanced_views/debug_view.dart';
+import '../../../providers/global/prefs_provider.dart';
+import '../../../widgets/custom_buttons/draggable_switch_button.dart';
+
 class AdvancedSettings extends ConsumerStatefulWidget {
   const AdvancedSettings({Key? key}) : super(key: key);
 
@@ -58,16 +63,106 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
                         ),
                       ),
                     ),
-                  ],
-                ),
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
-                    Padding(
-                      padding: EdgeInsets.all(
-                        10,
+                    const Padding(
+                      padding: EdgeInsets.all(10.0),
+                      child: Divider(
+                        thickness: 0.5,
+                      ),
+                    ),
+                    Padding(
+                      padding: const EdgeInsets.all(10),
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Text(
+                            "Toggle testnet coins",
+                            style: STextStyles.desktopTextExtraSmall(context)
+                                .copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark),
+                            textAlign: TextAlign.left,
+                          ),
+                          SizedBox(
+                            height: 20,
+                            width: 40,
+                            child: DraggableSwitchButton(
+                              isOn: ref.watch(
+                                prefsChangeNotifierProvider
+                                    .select((value) => value.showTestNetCoins),
+                              ),
+                              onValueChanged: (newValue) {
+                                ref
+                                    .read(prefsChangeNotifierProvider)
+                                    .showTestNetCoins = newValue;
+                              },
+                            ),
+                          ),
+                        ],
+                      ),
+                    ),
+                    const Padding(
+                      padding: EdgeInsets.all(10.0),
+                      child: Divider(
+                        thickness: 0.5,
+                      ),
+                    ),
+
+                    /// TODO: Make a dialog popup
+                    Padding(
+                      padding: const EdgeInsets.all(10),
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              Text(
+                                "Stack Experience",
+                                style:
+                                    STextStyles.desktopTextExtraSmall(context)
+                                        .copyWith(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark),
+                                textAlign: TextAlign.left,
+                              ),
+                              Text(
+                                "Easy Crypto",
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                    context),
+                              ),
+                            ],
+                          ),
+                          const StackPrivacyButton(),
+                        ],
+                      ),
+                    ),
+                    const Padding(
+                      padding: EdgeInsets.all(10.0),
+                      child: Divider(
+                        thickness: 0.5,
+                      ),
+                    ),
+
+                    /// TODO: Make a dialog popup
+                    Padding(
+                      padding: const EdgeInsets.all(10),
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Text(
+                            "Debug info",
+                            style: STextStyles.desktopTextExtraSmall(context)
+                                .copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark),
+                            textAlign: TextAlign.left,
+                          ),
+                          ShowLogsButton(),
+                        ],
                       ),
-                      child: ShowLogsButton(),
                     ),
                   ],
                 ),
@@ -80,6 +175,35 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
   }
 }
 
+class StackPrivacyButton extends ConsumerWidget {
+  const StackPrivacyButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      width: 84,
+      height: 37,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {
+          Navigator.of(context).pushNamed(
+            StackPrivacyCalls.routeName,
+            arguments: false,
+          );
+        },
+        child: Text(
+          "Change",
+          style: STextStyles.desktopTextExtraExtraSmall(context)
+              .copyWith(color: Colors.white),
+        ),
+      ),
+    );
+  }
+}
+
 class ShowLogsButton extends ConsumerWidget {
   const ShowLogsButton({
     Key? key,
@@ -87,16 +211,19 @@ class ShowLogsButton extends ConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     return SizedBox(
-      width: 200,
-      height: 48,
+      width: 101,
+      height: 37,
       child: TextButton(
         style: Theme.of(context)
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
+        onPressed: () {
+          Navigator.of(context).pushNamed(DebugView.routeName);
+        },
         child: Text(
           "Show logs",
-          style: STextStyles.button(context),
+          style: STextStyles.desktopTextExtraExtraSmall(context)
+              .copyWith(color: Colors.white),
         ),
       ),
     );

From f9eda14752affdc2856a57f0bff139ce922e46be Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 1 Nov 2022 16:59:37 -0600
Subject: [PATCH 094/426] v1.5.12 build 84

---
 pubspec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index ea2fbaa6d..c0aec3eaf 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.11+83
+version: 1.5.12+84
 
 environment:
   sdk: ">=2.17.0 <3.0.0"

From fc25ea2a244cd633f3ad31e96f24e3631cf452c7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 08:49:19 -0600
Subject: [PATCH 095/426] fix previous failing widget tests

---
 lib/widgets/transaction_card.dart             |   4 +-
 test/widget_tests/address_book_card_test.dart | 107 ++-
 test/widget_tests/transaction_card_test.dart  | 742 +++++++++---------
 3 files changed, 450 insertions(+), 403 deletions(-)

diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart
index 8867e34f6..15dcf2b4d 100644
--- a/lib/widgets/transaction_card.dart
+++ b/lib/widgets/transaction_card.dart
@@ -102,15 +102,13 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
             .select((value) => value.getPrice(coin)))
         .item1;
 
-    late final String prefix;
+    String prefix = "";
     if (Util.isDesktop) {
       if (_transaction.txType == "Sent") {
         prefix = "-";
       } else if (_transaction.txType == "Received") {
         prefix = "+";
       }
-    } else {
-      prefix = "";
     }
 
     return Material(
diff --git a/test/widget_tests/address_book_card_test.dart b/test/widget_tests/address_book_card_test.dart
index 8c8c44abd..07b1387df 100644
--- a/test/widget_tests/address_book_card_test.dart
+++ b/test/widget_tests/address_book_card_test.dart
@@ -1,6 +1,22 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_test/flutter_test.dart';
 import 'package:mockito/annotations.dart';
 import 'package:mockito/mockito.dart';
+import 'package:stackwallet/models/contact.dart';
+import 'package:stackwallet/models/contact_address_entry.dart';
+import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
+import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/services/address_book_service.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/theme/light_colors.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/address_book_card.dart';
+
+import 'address_book_card_test.mocks.dart';
 
 class MockedFunctions extends Mock {
   void showDialog();
@@ -8,46 +24,53 @@ class MockedFunctions extends Mock {
 
 @GenerateMocks([AddressBookService])
 void main() {
-  // testWidgets('test returns Contact Address Entry', (widgetTester) async {
-  //   final service = MockAddressBookService();
-  //
-  //   when(service.getContactById("default"))
-  //       .thenAnswer((realInvocation) => Contact(
-  //           name: "John Doe",
-  //           addresses: [
-  //             const ContactAddressEntry(
-  //                 coin: Coin.bitcoincash,
-  //                 address: "some bch address",
-  //                 label: "Bills")
-  //           ],
-  //           isFavorite: true));
-  //
-  //   await widgetTester.pumpWidget(
-  //     ProviderScope(
-  //       overrides: [
-  //         addressBookServiceProvider.overrideWithValue(
-  //           service,
-  //         ),
-  //       ],
-  //       child: MaterialApp(
-  //         theme: ThemeData(
-  //           extensions: [
-  //             StackColors.fromStackColorTheme(
-  //               LightColors(),
-  //             ),
-  //           ],
-  //         ),
-  //         home: const AddressBookCard(
-  //           contactId: "default",
-  //         ),
-  //       ),
-  //     ),
-  //   );
-  //
-  //   expect(find.text("John Doe"), findsOneWidget);
-  //   expect(find.text("BCH"), findsOneWidget);
-  //   expect(find.text(Coin.bitcoincash.ticker), findsOneWidget);
-  //
-  //   await widgetTester.tap(find.byType(RawMaterialButton));
-  // });
+  testWidgets('test returns Contact Address Entry', (widgetTester) async {
+    final service = MockAddressBookService();
+
+    when(service.getContactById("default")).thenAnswer(
+      (realInvocation) => Contact(
+        name: "John Doe",
+        addresses: [
+          const ContactAddressEntry(
+              coin: Coin.bitcoincash,
+              address: "some bch address",
+              label: "Bills")
+        ],
+        isFavorite: true,
+      ),
+    );
+
+    await widgetTester.pumpWidget(
+      ProviderScope(
+        overrides: [
+          addressBookServiceProvider.overrideWithValue(
+            service,
+          ),
+        ],
+        child: MaterialApp(
+          theme: ThemeData(
+            extensions: [
+              StackColors.fromStackColorTheme(
+                LightColors(),
+              ),
+            ],
+          ),
+          home: const AddressBookCard(
+            contactId: "default",
+          ),
+        ),
+      ),
+    );
+
+    expect(find.text("John Doe"), findsOneWidget);
+    expect(find.text("BCH"), findsOneWidget);
+    expect(find.text(Coin.bitcoincash.ticker), findsOneWidget);
+
+    if (Platform.isIOS || Platform.isAndroid) {
+      await widgetTester.tap(find.byType(RawMaterialButton));
+      expect(find.byType(ContactPopUp), findsOneWidget);
+    } else if (Util.isDesktop) {
+      expect(find.byType(RawMaterialButton), findsNothing);
+    }
+  });
 }
diff --git a/test/widget_tests/transaction_card_test.dart b/test/widget_tests/transaction_card_test.dart
index 6c36fce8d..f28c5f81d 100644
--- a/test/widget_tests/transaction_card_test.dart
+++ b/test/widget_tests/transaction_card_test.dart
@@ -1,4 +1,14 @@
+import 'package:decimal/decimal.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_feather_icons/flutter_feather_icons.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:mockingjay/mockingjay.dart' as mockingjay;
 import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
+import 'package:stackwallet/models/models.dart';
+import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
+import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/coins/coin_service.dart';
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
 import 'package:stackwallet/services/coins/manager.dart';
@@ -6,7 +16,15 @@ import 'package:stackwallet/services/locale_service.dart';
 import 'package:stackwallet/services/notes_service.dart';
 import 'package:stackwallet/services/price_service.dart';
 import 'package:stackwallet/services/wallets.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/utilities/theme/light_colors.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/transaction_card.dart';
+import 'package:tuple/tuple.dart';
+
+import 'transaction_card_test.mocks.dart';
 
 @GenerateMocks([
   Wallets,
@@ -19,362 +37,370 @@ import 'package:stackwallet/utilities/prefs.dart';
   NotesService
 ], customMocks: [])
 void main() {
-  // TestWidgetsFlutterBinding.ensureInitialized();
-  // testWidgets("Sent confirmed tx displays correctly", (tester) async {
-  //   final mockManager = MockManager();
-  //   final mockLocaleService = MockLocaleService();
-  //   final wallets = MockWallets();
-  //   final mockPrefs = MockPrefs();
-  //   final mockPriceService = MockPriceService();
-  //
-  //   final tx = Transaction(
-  //       txid: "some txid",
-  //       confirmedStatus: true,
-  //       timestamp: 1648595998,
-  //       txType: "Sent",
-  //       amount: 100000000,
-  //       aliens: [],
-  //       worthNow: "0.01",
-  //       worthAtBlockTimestamp: "0.01",
-  //       fees: 3794,
-  //       inputSize: 1,
-  //       outputSize: 1,
-  //       inputs: [],
-  //       outputs: [],
-  //       address: "",
-  //       height: 450123,
-  //       subType: "",
-  //       confirmations: 10,
-  //       isCancelled: false);
-  //
-  //   final CoinServiceAPI wallet = MockFiroWallet();
-  //
-  //   when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
-  //   when(mockLocaleService.locale).thenAnswer((_) => "en_US");
-  //   when(mockPrefs.currency).thenAnswer((_) => "USD");
-  //   when(mockPrefs.externalCalls).thenAnswer((_) => true);
-  //   when(mockPriceService.getPrice(Coin.firo))
-  //       .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
-  //
-  //   when(wallet.coin).thenAnswer((_) => Coin.firo);
-  //
-  //   when(wallets.getManager("wallet-id"))
-  //       .thenAnswer((realInvocation) => Manager(wallet));
-  //   //
-  //   await tester.pumpWidget(
-  //     ProviderScope(
-  //       overrides: [
-  //         walletsChangeNotifierProvider.overrideWithValue(wallets),
-  //         localeServiceChangeNotifierProvider
-  //             .overrideWithValue(mockLocaleService),
-  //         prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
-  //         priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
-  //       ],
-  //       child: MaterialApp(
-  //         theme: ThemeData(
-  //           extensions: [
-  //             StackColors.fromStackColorTheme(
-  //               LightColors(),
-  //             ),
-  //           ],
-  //         ),
-  //         home: TransactionCard(transaction: tx, walletId: "wallet-id"),
-  //       ),
-  //     ),
-  //   );
-  //
-  //   //
-  //   final title = find.text("Sent");
-  //   // final price1 = find.text("0.00 USD");
-  //   final amount = find.text("1.00000000 FIRO");
-  //
-  //   final icon = find.byIcon(FeatherIcons.arrowUp);
-  //
-  //   expect(title, findsOneWidget);
-  //   // expect(price1, findsOneWidget);
-  //   expect(amount, findsOneWidget);
-  //   // expect(icon, findsOneWidget);
-  //   //
-  //   await tester.pumpAndSettle(Duration(seconds: 2));
-  //   //
-  //   // final price2 = find.text("\$10.00");
-  //   // expect(price2, findsOneWidget);
-  //   //
-  //   // verify(mockManager.addListener(any)).called(1);
-  //   verify(mockLocaleService.addListener(any)).called(1);
-  //
-  //   verify(mockPrefs.currency).called(1);
-  //   verify(mockPriceService.getPrice(Coin.firo)).called(1);
-  //   verify(wallet.coin.ticker).called(1);
-  //
-  //   verify(mockLocaleService.locale).called(1);
-  //
-  //   verifyNoMoreInteractions(mockManager);
-  //   verifyNoMoreInteractions(mockLocaleService);
-  // });
-  //
-  // testWidgets("Anonymized confirmed tx displays correctly", (tester) async {
-  //   final mockManager = MockManager();
-  //   final mockLocaleService = MockLocaleService();
-  //   final wallets = MockWallets();
-  //   final mockPrefs = MockPrefs();
-  //   final mockPriceService = MockPriceService();
-  //
-  //   final tx = Transaction(
-  //       txid: "some txid",
-  //       confirmedStatus: true,
-  //       timestamp: 1648595998,
-  //       txType: "Anonymized",
-  //       amount: 100000000,
-  //       aliens: [],
-  //       worthNow: "0.01",
-  //       worthAtBlockTimestamp: "0.01",
-  //       fees: 3794,
-  //       inputSize: 1,
-  //       outputSize: 1,
-  //       inputs: [],
-  //       outputs: [],
-  //       address: "",
-  //       height: 450123,
-  //       subType: "mint",
-  //       confirmations: 10,
-  //       isCancelled: false);
-  //
-  //   final CoinServiceAPI wallet = MockFiroWallet();
-  //
-  //   when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
-  //   when(mockLocaleService.locale).thenAnswer((_) => "en_US");
-  //   when(mockPrefs.currency).thenAnswer((_) => "USD");
-  //   when(mockPrefs.externalCalls).thenAnswer((_) => true);
-  //   when(mockPriceService.getPrice(Coin.firo))
-  //       .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
-  //
-  //   when(wallet.coin).thenAnswer((_) => Coin.firo);
-  //
-  //   when(wallets.getManager("wallet-id"))
-  //       .thenAnswer((realInvocation) => Manager(wallet));
-  //   //
-  //   await tester.pumpWidget(
-  //     ProviderScope(
-  //       overrides: [
-  //         walletsChangeNotifierProvider.overrideWithValue(wallets),
-  //         localeServiceChangeNotifierProvider
-  //             .overrideWithValue(mockLocaleService),
-  //         prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
-  //         priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
-  //       ],
-  //       child: MaterialApp(
-  //         theme: ThemeData(
-  //           extensions: [
-  //             StackColors.fromStackColorTheme(
-  //               LightColors(),
-  //             ),
-  //           ],
-  //         ),
-  //         home: TransactionCard(transaction: tx, walletId: "wallet-id"),
-  //       ),
-  //     ),
-  //   );
-  //
-  //   //
-  //   final title = find.text("Anonymized");
-  //   // final price1 = find.text("0.00 USD");
-  //   final amount = find.text("1.00000000 FIRO");
-  //
-  //   final icon = find.byIcon(FeatherIcons.arrowUp);
-  //
-  //   expect(title, findsOneWidget);
-  //   // expect(price1, findsOneWidget);
-  //   expect(amount, findsOneWidget);
-  //   // expect(icon, findsOneWidget);
-  //   //
-  //   await tester.pumpAndSettle(Duration(seconds: 2));
-  //   //
-  //   // final price2 = find.text("\$10.00");
-  //   // expect(price2, findsOneWidget);
-  //   //
-  //   // verify(mockManager.addListener(any)).called(1);
-  //   verify(mockLocaleService.addListener(any)).called(1);
-  //
-  //   verify(mockPrefs.currency).called(1);
-  //   verify(mockPriceService.getPrice(Coin.firo)).called(1);
-  //   verify(wallet.coin.ticker).called(1);
-  //
-  //   verify(mockLocaleService.locale).called(1);
-  //
-  //   verifyNoMoreInteractions(mockManager);
-  //   verifyNoMoreInteractions(mockLocaleService);
-  // });
-  //
-  // testWidgets("Received unconfirmed tx displays correctly", (tester) async {
-  //   final mockManager = MockManager();
-  //   final mockLocaleService = MockLocaleService();
-  //   final wallets = MockWallets();
-  //   final mockPrefs = MockPrefs();
-  //   final mockPriceService = MockPriceService();
-  //
-  //   final tx = Transaction(
-  //     txid: "some txid",
-  //     confirmedStatus: false,
-  //     timestamp: 1648595998,
-  //     txType: "Received",
-  //     amount: 100000000,
-  //     aliens: [],
-  //     worthNow: "0.01",
-  //     worthAtBlockTimestamp: "0.01",
-  //     fees: 3794,
-  //     inputSize: 1,
-  //     outputSize: 1,
-  //     inputs: [],
-  //     outputs: [],
-  //     address: "",
-  //     height: 0,
-  //     subType: "",
-  //     confirmations: 0,
-  //   );
-  //
-  //   final CoinServiceAPI wallet = MockFiroWallet();
-  //
-  //   when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
-  //   when(mockLocaleService.locale).thenAnswer((_) => "en_US");
-  //   when(mockPrefs.currency).thenAnswer((_) => "USD");
-  //   when(mockPrefs.externalCalls).thenAnswer((_) => true);
-  //   when(mockPriceService.getPrice(Coin.firo))
-  //       .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
-  //
-  //   when(wallet.coin).thenAnswer((_) => Coin.firo);
-  //
-  //   when(wallets.getManager("wallet-id"))
-  //       .thenAnswer((realInvocation) => Manager(wallet));
-  //
-  //   await tester.pumpWidget(
-  //     ProviderScope(
-  //       overrides: [
-  //         walletsChangeNotifierProvider.overrideWithValue(wallets),
-  //         localeServiceChangeNotifierProvider
-  //             .overrideWithValue(mockLocaleService),
-  //         prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
-  //         priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
-  //       ],
-  //       child: MaterialApp(
-  //         theme: ThemeData(
-  //           extensions: [
-  //             StackColors.fromStackColorTheme(
-  //               LightColors(),
-  //             ),
-  //           ],
-  //         ),
-  //         home: TransactionCard(transaction: tx, walletId: "wallet-id"),
-  //       ),
-  //     ),
-  //   );
-  //
-  //   final title = find.text("Receiving");
-  //   final amount = find.text("1.00000000 FIRO");
-  //
-  //   expect(title, findsOneWidget);
-  //   expect(amount, findsOneWidget);
-  //
-  //   await tester.pumpAndSettle(Duration(seconds: 2));
-  //
-  //   verify(mockLocaleService.addListener(any)).called(1);
-  //
-  //   verify(mockPrefs.currency).called(1);
-  //   verify(mockPriceService.getPrice(Coin.firo)).called(1);
-  //   verify(wallet.coin.ticker).called(1);
-  //
-  //   verify(mockLocaleService.locale).called(1);
-  //
-  //   verifyNoMoreInteractions(mockManager);
-  //   verifyNoMoreInteractions(mockLocaleService);
-  // });
-  //
-  // testWidgets("Tap gesture", (tester) async {
-  //   final mockManager = MockManager();
-  //   final mockLocaleService = MockLocaleService();
-  //   final wallets = MockWallets();
-  //   final mockPrefs = MockPrefs();
-  //   final mockPriceService = MockPriceService();
-  //   final navigator = mockingjay.MockNavigator();
-  //
-  //   final tx = Transaction(
-  //     txid: "some txid",
-  //     confirmedStatus: false,
-  //     timestamp: 1648595998,
-  //     txType: "Received",
-  //     amount: 100000000,
-  //     aliens: [],
-  //     worthNow: "0.01",
-  //     worthAtBlockTimestamp: "0.01",
-  //     fees: 3794,
-  //     inputSize: 1,
-  //     outputSize: 1,
-  //     inputs: [],
-  //     outputs: [],
-  //     address: "",
-  //     height: 250,
-  //     subType: "",
-  //     confirmations: 10,
-  //   );
-  //
-  //   final CoinServiceAPI wallet = MockFiroWallet();
-  //
-  //   when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
-  //   when(mockLocaleService.locale).thenAnswer((_) => "en_US");
-  //   when(mockPrefs.currency).thenAnswer((_) => "USD");
-  //   when(mockPrefs.externalCalls).thenAnswer((_) => true);
-  //   when(mockPriceService.getPrice(Coin.firo))
-  //       .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
-  //
-  //   when(wallet.coin).thenAnswer((_) => Coin.firo);
-  //
-  //   when(wallets.getManager("wallet id"))
-  //       .thenAnswer((realInvocation) => Manager(wallet));
-  //
-  //   mockingjay
-  //       .when(() => navigator.pushNamed("/transactionDetails",
-  //           arguments: Tuple3(tx, Coin.firo, "wallet id")))
-  //       .thenAnswer((_) async => {});
-  //
-  //   await tester.pumpWidget(
-  //     ProviderScope(
-  //       overrides: [
-  //         walletsChangeNotifierProvider.overrideWithValue(wallets),
-  //         localeServiceChangeNotifierProvider
-  //             .overrideWithValue(mockLocaleService),
-  //         prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
-  //         priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
-  //       ],
-  //       child: MaterialApp(
-  //         theme: ThemeData(
-  //           extensions: [
-  //             StackColors.fromStackColorTheme(LightColors()),
-  //           ],
-  //         ),
-  //         home: mockingjay.MockNavigatorProvider(
-  //             navigator: navigator,
-  //             child: TransactionCard(transaction: tx, walletId: "wallet id")),
-  //       ),
-  //     ),
-  //   );
-  //
-  //   expect(find.byType(GestureDetector), findsOneWidget);
-  //
-  //   await tester.tap(find.byType(GestureDetector));
-  //   await tester.pump();
-  //
-  //   verify(mockLocaleService.addListener(any)).called(1);
-  //
-  //   verify(mockPrefs.currency).called(1);
-  //   verify(mockLocaleService.locale).called(1);
-  //   verify(wallet.coin.ticker).called(1);
-  //
-  //   verifyNoMoreInteractions(wallet);
-  //   verifyNoMoreInteractions(mockLocaleService);
-  //
-  //   mockingjay
-  //       .verify(() => navigator.pushNamed("/transactionDetails",
-  //           arguments: Tuple3(tx, Coin.firo, "wallet id")))
-  //       .called(1);
-  // });
+  TestWidgetsFlutterBinding.ensureInitialized();
+  testWidgets("Sent confirmed tx displays correctly", (tester) async {
+    final mockManager = MockManager();
+    final mockLocaleService = MockLocaleService();
+    final wallets = MockWallets();
+    final mockPrefs = MockPrefs();
+    final mockPriceService = MockPriceService();
+
+    final tx = Transaction(
+        txid: "some txid",
+        confirmedStatus: true,
+        timestamp: 1648595998,
+        txType: "Sent",
+        amount: 100000000,
+        aliens: [],
+        worthNow: "0.01",
+        worthAtBlockTimestamp: "0.01",
+        fees: 3794,
+        inputSize: 1,
+        outputSize: 1,
+        inputs: [],
+        outputs: [],
+        address: "",
+        height: 450123,
+        subType: "",
+        confirmations: 10,
+        isCancelled: false);
+
+    final CoinServiceAPI wallet = MockFiroWallet();
+
+    when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
+    when(mockLocaleService.locale).thenAnswer((_) => "en_US");
+    when(mockPrefs.currency).thenAnswer((_) => "USD");
+    when(mockPrefs.externalCalls).thenAnswer((_) => true);
+    when(mockPriceService.getPrice(Coin.firo))
+        .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
+
+    when(wallet.coin).thenAnswer((_) => Coin.firo);
+
+    when(wallets.getManager("wallet-id"))
+        .thenAnswer((realInvocation) => Manager(wallet));
+    //
+    await tester.pumpWidget(
+      ProviderScope(
+        overrides: [
+          walletsChangeNotifierProvider.overrideWithValue(wallets),
+          localeServiceChangeNotifierProvider
+              .overrideWithValue(mockLocaleService),
+          prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
+          priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
+        ],
+        child: MaterialApp(
+          theme: ThemeData(
+            extensions: [
+              StackColors.fromStackColorTheme(
+                LightColors(),
+              ),
+            ],
+          ),
+          home: TransactionCard(transaction: tx, walletId: "wallet-id"),
+        ),
+      ),
+    );
+
+    //
+    final title = find.text("Sent");
+    // final price1 = find.text("0.00 USD");
+    final amount = Util.isDesktop
+        ? find.text("-1.00000000 FIRO")
+        : find.text("1.00000000 FIRO");
+
+    final icon = find.byIcon(FeatherIcons.arrowUp);
+
+    expect(title, findsOneWidget);
+    // expect(price1, findsOneWidget);
+    expect(amount, findsOneWidget);
+    // expect(icon, findsOneWidget);
+    //
+    await tester.pumpAndSettle(const Duration(seconds: 2));
+    //
+    // final price2 = find.text("\$10.00");
+    // expect(price2, findsOneWidget);
+    //
+    // verify(mockManager.addListener(any)).called(1);
+    verify(mockLocaleService.addListener(any)).called(1);
+
+    verify(mockPrefs.currency).called(1);
+    verify(mockPriceService.getPrice(Coin.firo)).called(1);
+    verify(wallet.coin.ticker).called(1);
+
+    verify(mockLocaleService.locale).called(1);
+
+    verifyNoMoreInteractions(mockManager);
+    verifyNoMoreInteractions(mockLocaleService);
+  });
+
+  testWidgets("Anonymized confirmed tx displays correctly", (tester) async {
+    final mockManager = MockManager();
+    final mockLocaleService = MockLocaleService();
+    final wallets = MockWallets();
+    final mockPrefs = MockPrefs();
+    final mockPriceService = MockPriceService();
+
+    final tx = Transaction(
+        txid: "some txid",
+        confirmedStatus: true,
+        timestamp: 1648595998,
+        txType: "Anonymized",
+        amount: 100000000,
+        aliens: [],
+        worthNow: "0.01",
+        worthAtBlockTimestamp: "0.01",
+        fees: 3794,
+        inputSize: 1,
+        outputSize: 1,
+        inputs: [],
+        outputs: [],
+        address: "",
+        height: 450123,
+        subType: "mint",
+        confirmations: 10,
+        isCancelled: false);
+
+    final CoinServiceAPI wallet = MockFiroWallet();
+
+    when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
+    when(mockLocaleService.locale).thenAnswer((_) => "en_US");
+    when(mockPrefs.currency).thenAnswer((_) => "USD");
+    when(mockPrefs.externalCalls).thenAnswer((_) => true);
+    when(mockPriceService.getPrice(Coin.firo))
+        .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
+
+    when(wallet.coin).thenAnswer((_) => Coin.firo);
+
+    when(wallets.getManager("wallet-id"))
+        .thenAnswer((realInvocation) => Manager(wallet));
+    //
+    await tester.pumpWidget(
+      ProviderScope(
+        overrides: [
+          walletsChangeNotifierProvider.overrideWithValue(wallets),
+          localeServiceChangeNotifierProvider
+              .overrideWithValue(mockLocaleService),
+          prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
+          priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
+        ],
+        child: MaterialApp(
+          theme: ThemeData(
+            extensions: [
+              StackColors.fromStackColorTheme(
+                LightColors(),
+              ),
+            ],
+          ),
+          home: TransactionCard(transaction: tx, walletId: "wallet-id"),
+        ),
+      ),
+    );
+
+    //
+    final title = find.text("Anonymized");
+    // final price1 = find.text("0.00 USD");
+    final amount = find.text("1.00000000 FIRO");
+
+    final icon = find.byIcon(FeatherIcons.arrowUp);
+
+    expect(title, findsOneWidget);
+    // expect(price1, findsOneWidget);
+    expect(amount, findsOneWidget);
+    // expect(icon, findsOneWidget);
+    //
+    await tester.pumpAndSettle(const Duration(seconds: 2));
+    //
+    // final price2 = find.text("\$10.00");
+    // expect(price2, findsOneWidget);
+    //
+    // verify(mockManager.addListener(any)).called(1);
+    verify(mockLocaleService.addListener(any)).called(1);
+
+    verify(mockPrefs.currency).called(1);
+    verify(mockPriceService.getPrice(Coin.firo)).called(1);
+    verify(wallet.coin.ticker).called(1);
+
+    verify(mockLocaleService.locale).called(1);
+
+    verifyNoMoreInteractions(mockManager);
+    verifyNoMoreInteractions(mockLocaleService);
+  });
+
+  testWidgets("Received unconfirmed tx displays correctly", (tester) async {
+    final mockManager = MockManager();
+    final mockLocaleService = MockLocaleService();
+    final wallets = MockWallets();
+    final mockPrefs = MockPrefs();
+    final mockPriceService = MockPriceService();
+
+    final tx = Transaction(
+      txid: "some txid",
+      confirmedStatus: false,
+      timestamp: 1648595998,
+      txType: "Received",
+      amount: 100000000,
+      aliens: [],
+      worthNow: "0.01",
+      worthAtBlockTimestamp: "0.01",
+      fees: 3794,
+      inputSize: 1,
+      outputSize: 1,
+      inputs: [],
+      outputs: [],
+      address: "",
+      height: 0,
+      subType: "",
+      confirmations: 0,
+    );
+
+    final CoinServiceAPI wallet = MockFiroWallet();
+
+    when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
+    when(mockLocaleService.locale).thenAnswer((_) => "en_US");
+    when(mockPrefs.currency).thenAnswer((_) => "USD");
+    when(mockPrefs.externalCalls).thenAnswer((_) => true);
+    when(mockPriceService.getPrice(Coin.firo))
+        .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
+
+    when(wallet.coin).thenAnswer((_) => Coin.firo);
+
+    when(wallets.getManager("wallet-id"))
+        .thenAnswer((realInvocation) => Manager(wallet));
+
+    await tester.pumpWidget(
+      ProviderScope(
+        overrides: [
+          walletsChangeNotifierProvider.overrideWithValue(wallets),
+          localeServiceChangeNotifierProvider
+              .overrideWithValue(mockLocaleService),
+          prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
+          priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
+        ],
+        child: MaterialApp(
+          theme: ThemeData(
+            extensions: [
+              StackColors.fromStackColorTheme(
+                LightColors(),
+              ),
+            ],
+          ),
+          home: TransactionCard(transaction: tx, walletId: "wallet-id"),
+        ),
+      ),
+    );
+
+    final title = find.text("Receiving");
+    final amount = Util.isDesktop
+        ? find.text("+1.00000000 FIRO")
+        : find.text("1.00000000 FIRO");
+
+    expect(title, findsOneWidget);
+    expect(amount, findsOneWidget);
+
+    await tester.pumpAndSettle(const Duration(seconds: 2));
+
+    verify(mockLocaleService.addListener(any)).called(1);
+
+    verify(mockPrefs.currency).called(1);
+    verify(mockPriceService.getPrice(Coin.firo)).called(1);
+    verify(wallet.coin.ticker).called(1);
+
+    verify(mockLocaleService.locale).called(1);
+
+    verifyNoMoreInteractions(mockManager);
+    verifyNoMoreInteractions(mockLocaleService);
+  });
+
+  testWidgets("Tap gesture", (tester) async {
+    final mockManager = MockManager();
+    final mockLocaleService = MockLocaleService();
+    final wallets = MockWallets();
+    final mockPrefs = MockPrefs();
+    final mockPriceService = MockPriceService();
+    final navigator = mockingjay.MockNavigator();
+
+    final tx = Transaction(
+      txid: "some txid",
+      confirmedStatus: false,
+      timestamp: 1648595998,
+      txType: "Received",
+      amount: 100000000,
+      aliens: [],
+      worthNow: "0.01",
+      worthAtBlockTimestamp: "0.01",
+      fees: 3794,
+      inputSize: 1,
+      outputSize: 1,
+      inputs: [],
+      outputs: [],
+      address: "",
+      height: 250,
+      subType: "",
+      confirmations: 10,
+    );
+
+    final CoinServiceAPI wallet = MockFiroWallet();
+
+    when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
+    when(mockLocaleService.locale).thenAnswer((_) => "en_US");
+    when(mockPrefs.currency).thenAnswer((_) => "USD");
+    when(mockPrefs.externalCalls).thenAnswer((_) => true);
+    when(mockPriceService.getPrice(Coin.firo))
+        .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
+
+    when(wallet.coin).thenAnswer((_) => Coin.firo);
+
+    when(wallets.getManager("wallet id"))
+        .thenAnswer((realInvocation) => Manager(wallet));
+
+    mockingjay
+        .when(() => navigator.pushNamed("/transactionDetails",
+            arguments: Tuple3(tx, Coin.firo, "wallet id")))
+        .thenAnswer((_) async => {});
+
+    await tester.pumpWidget(
+      ProviderScope(
+        overrides: [
+          walletsChangeNotifierProvider.overrideWithValue(wallets),
+          localeServiceChangeNotifierProvider
+              .overrideWithValue(mockLocaleService),
+          prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
+          priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
+        ],
+        child: MaterialApp(
+          theme: ThemeData(
+            extensions: [
+              StackColors.fromStackColorTheme(LightColors()),
+            ],
+          ),
+          home: mockingjay.MockNavigatorProvider(
+              navigator: navigator,
+              child: TransactionCard(transaction: tx, walletId: "wallet id")),
+        ),
+      ),
+    );
+
+    expect(find.byType(GestureDetector), findsOneWidget);
+
+    await tester.tap(find.byType(GestureDetector));
+    await tester.pump();
+
+    verify(mockLocaleService.addListener(any)).called(1);
+
+    verify(mockPrefs.currency).called(2);
+    verify(mockLocaleService.locale).called(4);
+    verify(wallet.coin.ticker).called(1);
+
+    verifyNoMoreInteractions(wallet);
+    verifyNoMoreInteractions(mockLocaleService);
+
+    if (Util.isDesktop) {
+      expect(find.byType(TransactionDetailsView), findsOneWidget);
+    } else {
+      mockingjay
+          .verify(() => navigator.pushNamed("/transactionDetails",
+              arguments: Tuple3(tx, Coin.firo, "wallet id")))
+          .called(1);
+    }
+  });
 }

From 712b33833b39fe603bd11b9f333549ca2f9283a2 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 09:02:53 -0600
Subject: [PATCH 096/426] stack experience dialog for desktop advanced settings

---
 .../advanced_settings.dart                    | 159 ++++---
 .../advanced_settings/debug_info_dialog.dart  |   0
 .../stack_privacy_dialog.dart                 | 437 ++++++++++++++++++
 3 files changed, 531 insertions(+), 65 deletions(-)
 rename lib/pages_desktop_specific/home/{settings_menu => advanced_settings}/advanced_settings.dart (59%)
 create mode 100644 lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart
 create mode 100644 lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart

diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart b/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart
similarity index 59%
rename from lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart
rename to lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart
index e55326527..85eca20c0 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart
+++ b/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart
@@ -2,16 +2,15 @@ import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/pages/stack_privacy_calls.dart';
+import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart';
+import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import '../../../pages/settings_views/global_settings_view/advanced_views/debug_view.dart';
-import '../../../providers/global/prefs_provider.dart';
-import '../../../widgets/custom_buttons/draggable_switch_button.dart';
-
 class AdvancedSettings extends ConsumerStatefulWidget {
   const AdvancedSettings({Key? key}) : super(key: key);
 
@@ -109,63 +108,69 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
                     ),
 
                     /// TODO: Make a dialog popup
-                    Padding(
-                      padding: const EdgeInsets.all(10),
-                      child: Row(
-                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        children: [
-                          Column(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              Text(
-                                "Stack Experience",
-                                style:
-                                    STextStyles.desktopTextExtraSmall(context)
-                                        .copyWith(
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textDark),
-                                textAlign: TextAlign.left,
-                              ),
-                              Text(
-                                "Easy Crypto",
-                                style: STextStyles.desktopTextExtraExtraSmall(
-                                    context),
-                              ),
-                            ],
-                          ),
-                          const StackPrivacyButton(),
-                        ],
-                      ),
-                    ),
-                    const Padding(
-                      padding: EdgeInsets.all(10.0),
-                      child: Divider(
-                        thickness: 0.5,
-                      ),
-                    ),
-
-                    /// TODO: Make a dialog popup
-                    Padding(
-                      padding: const EdgeInsets.all(10),
-                      child: Row(
-                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        children: [
-                          Text(
-                            "Debug info",
-                            style: STextStyles.desktopTextExtraSmall(context)
-                                .copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textDark),
-                            textAlign: TextAlign.left,
-                          ),
-                          ShowLogsButton(),
-                        ],
-                      ),
-                    ),
+                    Consumer(builder: (_, ref, __) {
+                      final externalCalls = ref.watch(
+                        prefsChangeNotifierProvider
+                            .select((value) => value.externalCalls),
+                      );
+                      return Padding(
+                        padding: const EdgeInsets.all(10),
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          children: [
+                            Column(
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                Text(
+                                  "Stack Experience",
+                                  style:
+                                      STextStyles.desktopTextExtraSmall(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark),
+                                  textAlign: TextAlign.left,
+                                ),
+                                Text(
+                                  externalCalls ? "Easy crypto" : "Incognito",
+                                  style: STextStyles.desktopTextExtraExtraSmall(
+                                      context),
+                                ),
+                              ],
+                            ),
+                            const StackPrivacyButton(),
+                          ],
+                        ),
+                      );
+                    }),
                   ],
                 ),
+                const Padding(
+                  padding: EdgeInsets.all(10.0),
+                  child: Divider(
+                    thickness: 0.5,
+                  ),
+                ),
+
+                /// TODO: Make a dialog popup
+                Padding(
+                  padding: const EdgeInsets.all(10),
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Text(
+                        "Debug info",
+                        style: STextStyles.desktopTextExtraSmall(context)
+                            .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark),
+                        textAlign: TextAlign.left,
+                      ),
+                      ShowLogsButton(),
+                    ],
+                  ),
+                ),
               ],
             ),
           ),
@@ -181,6 +186,17 @@ class StackPrivacyButton extends ConsumerWidget {
   }) : super(key: key);
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    Future<void> changePrivacySettings() async {
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: true,
+        builder: (context) {
+          return StackPrivacyDialog();
+        },
+      );
+    }
+
     return SizedBox(
       width: 84,
       height: 37,
@@ -189,10 +205,11 @@ class StackPrivacyButton extends ConsumerWidget {
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {
-          Navigator.of(context).pushNamed(
-            StackPrivacyCalls.routeName,
-            arguments: false,
-          );
+          // Navigator.of(context).pushNamed(
+          //   StackPrivacyCalls.routeName,
+          //   arguments: false,
+          // );
+          changePrivacySettings();
         },
         child: Text(
           "Change",
@@ -210,6 +227,17 @@ class ShowLogsButton extends ConsumerWidget {
   }) : super(key: key);
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    Future<void> viewDebugLogs() async {
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: true,
+        builder: (context) {
+          return const DebugInfoDialog();
+        },
+      );
+    }
+
     return SizedBox(
       width: 101,
       height: 37,
@@ -218,7 +246,8 @@ class ShowLogsButton extends ConsumerWidget {
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {
-          Navigator.of(context).pushNamed(DebugView.routeName);
+          //
+          viewDebugLogs();
         },
         child: Text(
           "Show logs",
diff --git a/lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart b/lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart
new file mode 100644
index 000000000..e69de29bb
diff --git a/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart b/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart
new file mode 100644
index 000000000..8e385fd37
--- /dev/null
+++ b/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart
@@ -0,0 +1,437 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+import '../../../hive/db.dart';
+import '../../../providers/global/prefs_provider.dart';
+import '../../../providers/global/price_provider.dart';
+import '../../../services/exchange/exchange_data_loading_service.dart';
+import '../../../utilities/assets.dart';
+import '../../../utilities/constants.dart';
+import '../../../utilities/theme/stack_colors.dart';
+import '../../../utilities/util.dart';
+import '../../../widgets/rounded_white_container.dart';
+
+class StackPrivacyDialog extends ConsumerStatefulWidget {
+  const StackPrivacyDialog({Key? key}) : super(key: key);
+
+  @override
+  ConsumerState<StackPrivacyDialog> createState() => _StackPrivacyDialog();
+}
+
+class _StackPrivacyDialog extends ConsumerState<StackPrivacyDialog> {
+  late final bool isDesktop;
+  late bool isEasy;
+  late bool infoToggle;
+
+  @override
+  void initState() {
+    isDesktop = Util.isDesktop;
+    isEasy = ref.read(prefsChangeNotifierProvider).externalCalls;
+    infoToggle = isEasy;
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxHeight: 650,
+      maxWidth: 600,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.all(32),
+                child: Text(
+                  "Choose Your Stack Experience",
+                  style: STextStyles.desktopH3(context),
+                  textAlign: TextAlign.center,
+                ),
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+          const SizedBox(
+            height: 35,
+          ),
+          Padding(
+            padding: EdgeInsets.symmetric(horizontal: 32),
+            child: PrivacyToggle(
+              externalCallsEnabled: isEasy,
+              onChanged: (externalCalls) {
+                isEasy = externalCalls;
+                setState(() {
+                  infoToggle = isEasy;
+                });
+              },
+            ),
+          ),
+          Padding(
+            padding: const EdgeInsets.all(32.0),
+            child: RoundedWhiteContainer(
+              borderColor: Theme.of(context)
+                  .extension<StackColors>()!
+                  .textFieldDefaultBG,
+              child: Center(
+                child: RichText(
+                  textAlign: TextAlign.left,
+                  text: TextSpan(
+                    style: isDesktop
+                        ? STextStyles.desktopTextExtraExtraSmall(context)
+                        : STextStyles.label(context).copyWith(
+                            fontSize: 12.0,
+                          ),
+                    children: infoToggle
+                        ? [
+                            const TextSpan(
+                                text:
+                                    "Exchange data preloaded for a seamless experience."),
+                            const TextSpan(
+                                text:
+                                    "\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."),
+                            TextSpan(
+                              text: "\n\nRecommended for most crypto users.",
+                              style: isDesktop
+                                  ? STextStyles.desktopTextExtraExtraSmall600(
+                                      context)
+                                  : TextStyle(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textDark,
+                                      fontWeight: FontWeight.w600,
+                                    ),
+                            ),
+                          ]
+                        : [
+                            const TextSpan(
+                                text:
+                                    "Exchange data not preloaded (slower experience)."),
+                            const TextSpan(
+                                text:
+                                    "\n\nCoinGecko disabled (price changes not shown, no wallet value shown in other currencies)."),
+                            TextSpan(
+                              text:
+                                  "\n\nRecommended for the privacy conscious.",
+                              style: isDesktop
+                                  ? STextStyles.desktopTextExtraExtraSmall600(
+                                      context)
+                                  : TextStyle(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textDark,
+                                      fontWeight: FontWeight.w600,
+                                    ),
+                            ),
+                          ],
+                  ),
+                ),
+              ),
+            ),
+          ),
+          // const Spacer(),
+          Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 32),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    onPressed: () {},
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Save",
+                    onPressed: () {
+                      ref.read(prefsChangeNotifierProvider).externalCalls =
+                          isEasy;
+
+                      DB.instance
+                          .put<dynamic>(
+                              boxName: DB.boxNamePrefs,
+                              key: "externalCalls",
+                              value: isEasy)
+                          .then((_) {
+                        if (isEasy) {
+                          unawaited(ExchangeDataLoadingService().loadAll(ref));
+                          ref
+                              .read(priceAnd24hChangeNotifierProvider)
+                              .start(true);
+                        }
+                      });
+                      if (isDesktop) {
+                        Navigator.pop(context);
+                      }
+                    },
+                  ),
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class PrivacyToggle extends StatefulWidget {
+  const PrivacyToggle({
+    Key? key,
+    required this.externalCallsEnabled,
+    this.onChanged,
+  }) : super(key: key);
+
+  final bool externalCallsEnabled;
+  final void Function(bool)? onChanged;
+
+  @override
+  State<PrivacyToggle> createState() => _PrivacyToggleState();
+}
+
+class _PrivacyToggleState extends State<PrivacyToggle> {
+  late bool externalCallsEnabled;
+
+  late final bool isDesktop;
+
+  @override
+  void initState() {
+    isDesktop = Util.isDesktop;
+    // initial toggle state
+    externalCallsEnabled = widget.externalCallsEnabled;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      children: [
+        Expanded(
+          child: RawMaterialButton(
+            elevation: 0,
+            hoverElevation: 0,
+            fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
+            shape: RoundedRectangleBorder(
+              side: !externalCallsEnabled
+                  ? BorderSide.none
+                  : BorderSide(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .infoItemIcons,
+                      width: 2,
+                    ),
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius * 2,
+              ),
+            ),
+            onPressed: () {
+              setState(() {
+                // update toggle state
+                externalCallsEnabled = true;
+              });
+              // call callback with newly set value
+              widget.onChanged?.call(externalCallsEnabled);
+            },
+            child: Padding(
+              padding: const EdgeInsets.all(
+                12,
+              ),
+              child: Stack(
+                children: [
+                  Column(
+                    crossAxisAlignment: CrossAxisAlignment.stretch,
+                    children: [
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 10,
+                        ),
+                      SvgPicture.asset(
+                        Assets.svg.personaEasy,
+                        width: 120,
+                        height: 120,
+                      ),
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 12,
+                        ),
+                      Center(
+                        child: Text(
+                          "Easy Crypto",
+                          style: isDesktop
+                              ? STextStyles.desktopTextSmall(context)
+                              : STextStyles.label700(context),
+                        ),
+                      ),
+                      Center(
+                        child: Text(
+                          "Recommended",
+                          style: isDesktop
+                              ? STextStyles.desktopTextExtraExtraSmall(context)
+                              : STextStyles.label(context),
+                        ),
+                      ),
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 12,
+                        ),
+                    ],
+                  ),
+                  if (externalCallsEnabled)
+                    Positioned(
+                      top: 4,
+                      right: 4,
+                      child: SvgPicture.asset(
+                        Assets.svg.checkCircle,
+                        width: 20,
+                        height: 20,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .infoItemIcons,
+                      ),
+                    ),
+                  if (!externalCallsEnabled)
+                    Positioned(
+                      top: 4,
+                      right: 4,
+                      child: Container(
+                        width: 20,
+                        height: 20,
+                        decoration: BoxDecoration(
+                          borderRadius: BorderRadius.circular(1000),
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textFieldDefaultBG,
+                        ),
+                      ),
+                    ),
+                ],
+              ),
+            ),
+          ),
+        ),
+        const SizedBox(
+          width: 16,
+        ),
+        Expanded(
+          child: RawMaterialButton(
+            elevation: 0,
+            hoverElevation: 0,
+            fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
+            shape: RoundedRectangleBorder(
+              side: externalCallsEnabled
+                  ? BorderSide.none
+                  : BorderSide(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .infoItemIcons,
+                      width: 2,
+                    ),
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius * 2,
+              ),
+            ),
+            onPressed: () {
+              setState(() {
+                // update toggle state
+                externalCallsEnabled = false;
+              });
+              // call callback with newly set value
+              widget.onChanged?.call(externalCallsEnabled);
+            },
+            child: Padding(
+              padding: const EdgeInsets.all(
+                12,
+              ),
+              child: Stack(
+                children: [
+                  Column(
+                    crossAxisAlignment: CrossAxisAlignment.stretch,
+                    children: [
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 10,
+                        ),
+                      SvgPicture.asset(
+                        Assets.svg.personaIncognito,
+                        width: 120,
+                        height: 120,
+                      ),
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 12,
+                        ),
+                      Center(
+                        child: Text(
+                          "Incognito",
+                          style: isDesktop
+                              ? STextStyles.desktopTextSmall(context)
+                              : STextStyles.label700(context),
+                        ),
+                      ),
+                      Center(
+                        child: Text(
+                          "Privacy conscious",
+                          style: isDesktop
+                              ? STextStyles.desktopTextExtraExtraSmall(context)
+                              : STextStyles.label(context),
+                        ),
+                      ),
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 12,
+                        ),
+                    ],
+                  ),
+                  if (!externalCallsEnabled)
+                    Positioned(
+                      top: 4,
+                      right: 4,
+                      child: SvgPicture.asset(
+                        Assets.svg.checkCircle,
+                        width: 20,
+                        height: 20,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .infoItemIcons,
+                      ),
+                    ),
+                  if (externalCallsEnabled)
+                    Positioned(
+                      top: 4,
+                      right: 4,
+                      child: Container(
+                        width: 20,
+                        height: 20,
+                        decoration: BoxDecoration(
+                          borderRadius: BorderRadius.circular(1000),
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textFieldDefaultBG,
+                        ),
+                      ),
+                    ),
+                ],
+              ),
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}

From fc981ef6e01a1db71823818070207dbecdfc9e23 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 10:01:03 -0600
Subject: [PATCH 097/426] AddressBookAddressChooser search and ui tweaks

---
 assets/svg/chevron-up.svg                     |   3 +
 .../address_book_address_chooser.dart         | 131 +++++++++++++++++-
 .../sub_widgets/contact_list_item.dart        |  27 +++-
 .../wallet_view/sub_widgets/desktop_send.dart |  28 +++-
 lib/utilities/assets.dart                     |   1 +
 lib/widgets/address_book_card.dart            |  19 ++-
 pubspec.yaml                                  |   1 +
 7 files changed, 197 insertions(+), 13 deletions(-)
 create mode 100644 assets/svg/chevron-up.svg

diff --git a/assets/svg/chevron-up.svg b/assets/svg/chevron-up.svg
new file mode 100644
index 000000000..630f8df69
--- /dev/null
+++ b/assets/svg/chevron-up.svg
@@ -0,0 +1,3 @@
+<svg width="12" height="7" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M11 6L6 1L1 6" stroke="#8E9192" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
index 372c86e2f..9f309a08e 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
@@ -1,10 +1,18 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.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 AddressBookAddressChooser extends StatefulWidget {
   const AddressBookAddressChooser({
@@ -20,6 +28,12 @@ class AddressBookAddressChooser extends StatefulWidget {
 }
 
 class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
+  late final bool isDesktop;
+  late final TextEditingController _searchController;
+  late final FocusNode searchFieldFocusNode;
+
+  String _searchTerm = "";
+
   int _compareContactFavorite(Contact a, Contact b) {
     if (a.isFavorite && b.isFavorite) {
       return 0;
@@ -43,29 +57,128 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
     return favorites;
   }
 
-  List<Contact> filter(List<Contact> contacts) {
+  List<Contact> filter(List<Contact> contacts, String searchTerm) {
     if (widget.coin != null) {
       contacts.removeWhere(
           (e) => e.addresses.where((a) => a.coin == widget.coin!).isEmpty);
     }
 
+    contacts.retainWhere((e) => _matches(searchTerm, e));
+
     if (contacts.length < 2) {
       return contacts;
     }
 
+    // redundant due to pullOutFavorites?
     contacts.sort(_compareContactFavorite);
 
-    // TODO: other filtering?
-
     return contacts;
   }
 
+  bool _matches(String term, Contact contact) {
+    final text = term.toLowerCase();
+    if (contact.name.toLowerCase().contains(text)) {
+      return true;
+    }
+    for (int i = 0; i < contact.addresses.length; i++) {
+      if (contact.addresses[i].label.toLowerCase().contains(text) ||
+          contact.addresses[i].coin.name.toLowerCase().contains(text) ||
+          contact.addresses[i].coin.prettyName.toLowerCase().contains(text) ||
+          contact.addresses[i].coin.ticker.toLowerCase().contains(text) ||
+          contact.addresses[i].address.toLowerCase().contains(text)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  void initState() {
+    isDesktop = Util.isDesktop;
+    searchFieldFocusNode = FocusNode();
+    _searchController = TextEditingController();
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _searchController.dispose();
+    searchFieldFocusNode.dispose();
+    super.dispose();
+  }
+
   @override
   Widget build(BuildContext context) {
     return Column(
       children: [
         // search field
-        const TextField(),
+        Padding(
+          padding: const EdgeInsets.symmetric(
+            horizontal: 32,
+          ),
+          child: ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              autocorrect: !isDesktop,
+              enableSuggestions: !isDesktop,
+              controller: _searchController,
+              focusNode: searchFieldFocusNode,
+              onChanged: (value) {
+                setState(() {
+                  _searchTerm = value;
+                });
+              },
+              style: isDesktop
+                  ? STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldActiveText,
+                      height: 1.8,
+                    )
+                  : STextStyles.field(context),
+              decoration: standardInputDecoration(
+                "Search",
+                searchFieldFocusNode,
+                context,
+                desktopMed: isDesktop,
+              ).copyWith(
+                prefixIcon: Padding(
+                  padding: EdgeInsets.symmetric(
+                    horizontal: isDesktop ? 12 : 10,
+                    vertical: isDesktop ? 18 : 16,
+                  ),
+                  child: SvgPicture.asset(
+                    Assets.svg.search,
+                    width: isDesktop ? 20 : 16,
+                    height: isDesktop ? 20 : 16,
+                  ),
+                ),
+                suffixIcon: _searchController.text.isNotEmpty
+                    ? Padding(
+                        padding: const EdgeInsets.only(right: 0),
+                        child: UnconstrainedBox(
+                          child: Row(
+                            children: [
+                              TextFieldIconButton(
+                                child: const XIcon(),
+                                onTap: () async {
+                                  setState(() {
+                                    _searchController.text = "";
+                                    _searchTerm = "";
+                                  });
+                                },
+                              ),
+                            ],
+                          ),
+                        ),
+                      )
+                    : null,
+              ),
+            ),
+          ),
+        ),
         const SizedBox(
           height: 16,
         ),
@@ -83,7 +196,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
                         .select((value) => value.contacts))
                     .toList();
 
-                contacts = filter(contacts);
+                contacts = filter(contacts, _searchTerm);
 
                 final favorites = pullOutFavorites(contacts);
 
@@ -96,6 +209,8 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
                   itemBuilder: (context, index) {
                     if (index == 0) {
                       return Padding(
+                        key: const Key(
+                            "addressBookCAddressChooserFavoritesHeaderItemKey"),
                         padding: const EdgeInsets.only(
                           bottom: 10,
                         ),
@@ -108,12 +223,14 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
                     } else if (index <= favorites.length) {
                       final id = favorites[index - 1].id;
                       return ContactListItem(
-                        key: Key("contactCard_${id}_key"),
+                        key: Key("contactContactListItem_${id}_key"),
                         contactId: id,
                         filterByCoin: widget.coin,
                       );
                     } else if (index == favorites.length + 1) {
                       return Padding(
+                        key: const Key(
+                            "addressBookCAddressChooserAllContactsHeaderItemKey"),
                         padding: const EdgeInsets.symmetric(
                           vertical: 10,
                         ),
@@ -126,7 +243,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
                     } else {
                       final id = contacts[index - favorites.length - 1].id;
                       return ContactListItem(
-                        key: Key("contactCard_${id}_key"),
+                        key: Key("contactContactListItem_${id}_key"),
                         contactId: id,
                         filterByCoin: widget.coin,
                       );
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
index 593ae2bc4..e030f9882 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
@@ -10,7 +10,7 @@ import 'package:stackwallet/widgets/expandable.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
 
-class ContactListItem extends ConsumerWidget {
+class ContactListItem extends ConsumerStatefulWidget {
   const ContactListItem({
     Key? key,
     required this.contactId,
@@ -21,7 +21,24 @@ class ContactListItem extends ConsumerWidget {
   final Coin? filterByCoin;
 
   @override
-  Widget build(BuildContext context, WidgetRef ref) {
+  ConsumerState<ContactListItem> createState() => _ContactListItemState();
+}
+
+class _ContactListItemState extends ConsumerState<ContactListItem> {
+  late final String contactId;
+  late final Coin? filterByCoin;
+
+  ExpandableState _state = ExpandableState.collapsed;
+
+  @override
+  void initState() {
+    contactId = widget.contactId;
+    filterByCoin = widget.filterByCoin;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
     final contact = ref.watch(addressBookServiceProvider
         .select((value) => value.getContactById(contactId)));
 
@@ -29,6 +46,11 @@ class ContactListItem extends ConsumerWidget {
       padding: const EdgeInsets.all(0),
       borderColor: Theme.of(context).extension<StackColors>()!.background,
       child: Expandable(
+        onExpandChanged: (state) {
+          setState(() {
+            _state = state;
+          });
+        },
         header: Padding(
           padding: const EdgeInsets.symmetric(
             horizontal: 20,
@@ -36,6 +58,7 @@ class ContactListItem extends ConsumerWidget {
           ),
           child: AddressBookCard(
             contactId: contactId,
+            indicatorDown: _state == ExpandableState.expanded,
           ),
         ),
         body: Column(
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index 26f2f806c..710bc8685 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -1190,8 +1190,32 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                               builder: (context) => DesktopDialog(
                                 maxWidth: 696,
                                 maxHeight: 600,
-                                child: AddressBookAddressChooser(
-                                  coin: coin,
+                                child: Column(
+                                  mainAxisSize: MainAxisSize.min,
+                                  children: [
+                                    Row(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceBetween,
+                                      children: [
+                                        Padding(
+                                          padding: const EdgeInsets.only(
+                                            left: 32,
+                                          ),
+                                          child: Text(
+                                            "Address book",
+                                            style:
+                                                STextStyles.desktopH3(context),
+                                          ),
+                                        ),
+                                        const DesktopDialogCloseButton(),
+                                      ],
+                                    ),
+                                    Expanded(
+                                      child: AddressBookAddressChooser(
+                                        coin: coin,
+                                      ),
+                                    ),
+                                  ],
                                 ),
                               ),
                             );
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 432ebbec9..78535c19b 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -96,6 +96,7 @@ class _SVG {
   String get qrcode => "assets/svg/qrcode1.svg";
   String get ellipsis => "assets/svg/gear-3.svg";
   String get chevronDown => "assets/svg/chevron-down.svg";
+  String get chevronUp => "assets/svg/chevron-up.svg";
   String get swap => "assets/svg/swap.svg";
   String get downloadFolder => "assets/svg/folder-down.svg";
   String get lock => "assets/svg/lock-keyhole.svg";
diff --git a/lib/widgets/address_book_card.dart b/lib/widgets/address_book_card.dart
index 6a51edbad..cebcf166f 100644
--- a/lib/widgets/address_book_card.dart
+++ b/lib/widgets/address_book_card.dart
@@ -13,9 +13,14 @@ import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class AddressBookCard extends ConsumerStatefulWidget {
-  const AddressBookCard({Key? key, required this.contactId}) : super(key: key);
+  const AddressBookCard({
+    Key? key,
+    required this.contactId,
+    this.indicatorDown,
+  }) : super(key: key);
 
   final String contactId;
+  final bool? indicatorDown;
 
   @override
   ConsumerState<AddressBookCard> createState() => _AddressBookCardState();
@@ -122,7 +127,17 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
                   style: STextStyles.label(context),
                 ),
               ],
-            )
+            ),
+          if (isDesktop) const Spacer(),
+          if (isDesktop)
+            SvgPicture.asset(
+              widget.indicatorDown == true
+                  ? Assets.svg.chevronDown
+                  : Assets.svg.chevronUp,
+              width: 10,
+              height: 5,
+              color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
+            ),
         ],
       ),
       builder: (child) => RoundedWhiteContainer(
diff --git a/pubspec.yaml b/pubspec.yaml
index 7bd53de06..29d25cb84 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -232,6 +232,7 @@ flutter:
     - assets/svg/gear-3.svg
     - assets/svg/swap.svg
     - assets/svg/chevron-down.svg
+    - assets/svg/chevron-up.svg
     - assets/svg/lock-keyhole.svg
     - assets/svg/rotate-exclamation.svg
     - assets/svg/folder-down.svg

From b915b266ae515bcdbc587c2cb337d594c032b0a5 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 10:09:42 -0600
Subject: [PATCH 098/426] imports fix

---
 .../advanced_settings/advanced_settings.dart  | 29 +++++++++----------
 .../home/desktop_settings_view.dart           |  2 +-
 lib/route_generator.dart                      |  2 +-
 3 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart b/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart
index 85eca20c0..7361d9773 100644
--- a/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart
+++ b/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart
@@ -1,8 +1,6 @@
 import 'package:flutter/material.dart';
-import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart';
 import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -167,7 +165,7 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
                                     .textDark),
                         textAlign: TextAlign.left,
                       ),
-                      ShowLogsButton(),
+                      const ShowLogsButton(),
                     ],
                   ),
                 ),
@@ -192,7 +190,7 @@ class StackPrivacyButton extends ConsumerWidget {
         useSafeArea: false,
         barrierDismissible: true,
         builder: (context) {
-          return StackPrivacyDialog();
+          return const StackPrivacyDialog();
         },
       );
     }
@@ -225,19 +223,20 @@ class ShowLogsButton extends ConsumerWidget {
   const ShowLogsButton({
     Key? key,
   }) : super(key: key);
+
+  Future<void> viewDebugLogs() async {
+    // await showDialog<dynamic>(
+    //   context: context,
+    //   useSafeArea: false,
+    //   barrierDismissible: true,
+    //   builder: (context) {
+    //     return const DebugInfoDialog();
+    //   },
+    // );
+  }
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    Future<void> viewDebugLogs() async {
-      await showDialog<dynamic>(
-        context: context,
-        useSafeArea: false,
-        barrierDismissible: true,
-        builder: (context) {
-          return const DebugInfoDialog();
-        },
-      );
-    }
-
     return SizedBox(
       width: 101,
       height: 37,
diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index 719a37a3a..34cb07f27 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -1,6 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 136dc7a34..613e0d509 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -85,13 +85,13 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_sear
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
 import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
 import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';

From 2e5a5e35a0c57455831225a1c2bd186a46f66535 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 10:27:07 -0600
Subject: [PATCH 099/426] import changes

---
 .../advanced_settings/debug_info_dialog.dart  |   0
 .../advanced_settings/advanced_settings.dart  |   0
 .../advanced_settings/debug_info_dialog.dart  | 188 ++++++++++++++++++
 .../stack_privacy_dialog.dart                 |  19 +-
 4 files changed, 197 insertions(+), 10 deletions(-)
 delete mode 100644 lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart
 rename lib/pages_desktop_specific/home/{ => settings_menu}/advanced_settings/advanced_settings.dart (100%)
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
 rename lib/pages_desktop_specific/home/{ => settings_menu}/advanced_settings/stack_privacy_dialog.dart (96%)

diff --git a/lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart b/lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart
deleted file mode 100644
index e69de29bb..000000000
diff --git a/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
similarity index 100%
rename from lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart
rename to lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
new file mode 100644
index 000000000..342d9180a
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
@@ -0,0 +1,188 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/models/isar/models/log.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+// import '../../../utilities/assets.dart';
+// import '../../../utilities/util.dart';
+// import '../../../widgets/icon_widgets/x_icon.dart';
+// import '../../../widgets/stack_text_field.dart';
+// import '../../../widgets/textfield_icon_button.dart';
+
+class DebugInfoDialog extends StatefulWidget {
+  const DebugInfoDialog({Key? key}) : super(key: key);
+
+  @override
+  State<StatefulWidget> createState() => _DebugInfoDialog();
+}
+
+class _DebugInfoDialog extends State<DebugInfoDialog> {
+  final _searchController = TextEditingController();
+  final _searchFocusNode = FocusNode();
+
+  final scrollController = ScrollController();
+
+  String _searchTerm = "";
+
+  List<Log> filtered(List<Log> unfiltered, String filter) {
+    if (filter == "") {
+      return unfiltered;
+    }
+    return unfiltered
+        .where(
+            (e) => (e.toString().toLowerCase().contains(filter.toLowerCase())))
+        .toList();
+  }
+
+  BorderRadius? _borderRadius(int index, int listLength) {
+    if (index == 0 && listLength == 1) {
+      return BorderRadius.circular(
+        Constants.size.circularBorderRadius,
+      );
+    } else if (index == 0) {
+      return BorderRadius.vertical(
+        bottom: Radius.circular(
+          Constants.size.circularBorderRadius,
+        ),
+      );
+    } else if (index == listLength - 1) {
+      return BorderRadius.vertical(
+        top: Radius.circular(
+          Constants.size.circularBorderRadius,
+        ),
+      );
+    }
+    return null;
+  }
+
+  @override
+  void initState() {
+    // ref.read(debugServiceProvider).updateRecentLogs();
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _searchController.dispose();
+    scrollController.dispose();
+    _searchFocusNode.dispose();
+
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxHeight: 800,
+      maxWidth: 600,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.all(32),
+                child: Text(
+                  "Debug info",
+                  style: STextStyles.desktopH3(context),
+                  textAlign: TextAlign.center,
+                ),
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+          Row(
+            children: [
+              // ClipRRect(
+              //   borderRadius: BorderRadius.circular(
+              //     Constants.size.circularBorderRadius,
+              //   ),
+              //   child: TextField(
+              //     key: const Key("desktopSettingDebugInfo"),
+              //     autocorrect: Util.isDesktop ? false : true,
+              //     enableSuggestions: Util.isDesktop ? false : true,
+              //     controller: _searchController,
+              //     focusNode: _searchFocusNode,
+              //     // onChanged: (newString) {
+              //     //   setState(() => _searchTerm = newString);
+              //     // },
+              //     style: STextStyles.field(context),
+              //     decoration: standardInputDecoration(
+              //       "Search",
+              //       _searchFocusNode,
+              //       context,
+              //     ).copyWith(
+              //       prefixIcon: Padding(
+              //         padding: const EdgeInsets.symmetric(
+              //           horizontal: 10,
+              //           vertical: 16,
+              //         ),
+              //         child: SvgPicture.asset(
+              //           Assets.svg.search,
+              //           width: 16,
+              //           height: 16,
+              //         ),
+              //       ),
+              //       suffixIcon: _searchController.text.isNotEmpty
+              //           ? Padding(
+              //               padding: const EdgeInsets.only(right: 0),
+              //               child: UnconstrainedBox(
+              //                 child: Row(
+              //                   children: [
+              //                     TextFieldIconButton(
+              //                       child: const XIcon(),
+              //                       onTap: () async {
+              //                         setState(() {
+              //                           _searchController.text = "";
+              //                           _searchTerm = "";
+              //                         });
+              //                       },
+              //                     ),
+              //                   ],
+              //                 ),
+              //               ),
+              //             )
+              //           : null,
+              //     ),
+              //   ),
+              // ),
+            ],
+          ),
+          // Column(
+          //   children: [
+          //
+          //   ],
+          // ),
+          const Spacer(),
+          Padding(
+            padding: const EdgeInsets.all(32),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Clear logs",
+                    onPressed: () {},
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Save logs to file",
+                    onPressed: () {},
+                  ),
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/stack_privacy_dialog.dart
similarity index 96%
rename from lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart
rename to lib/pages_desktop_specific/home/settings_menu/advanced_settings/stack_privacy_dialog.dart
index 8e385fd37..32c20c010 100644
--- a/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/stack_privacy_dialog.dart
@@ -3,21 +3,20 @@ import 'dart:async';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/hive/db.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/global/price_provider.dart';
+import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
+import 'package:stackwallet/utilities/assets.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/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
-
-import '../../../hive/db.dart';
-import '../../../providers/global/prefs_provider.dart';
-import '../../../providers/global/price_provider.dart';
-import '../../../services/exchange/exchange_data_loading_service.dart';
-import '../../../utilities/assets.dart';
-import '../../../utilities/constants.dart';
-import '../../../utilities/theme/stack_colors.dart';
-import '../../../utilities/util.dart';
-import '../../../widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class StackPrivacyDialog extends ConsumerStatefulWidget {
   const StackPrivacyDialog({Key? key}) : super(key: key);

From 8fff27523ab5e4105dfac12d6f18d99e0fa6db61 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 10:27:50 -0600
Subject: [PATCH 100/426] import change

---
 lib/route_generator.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 613e0d509..edc677946 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -85,13 +85,13 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_sear
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
 import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
 import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
-import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
+import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';

From cb39ff62b813251cec130601cde7d684ba7dbae5 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 10:28:34 -0600
Subject: [PATCH 101/426] easy crypto elevation fix

---
 lib/pages/stack_privacy_calls.dart | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index 7e981b91a..fd6f60def 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -285,6 +285,7 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
       children: [
         Expanded(
           child: RawMaterialButton(
+            elevation: 0,
             fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
             shape: RoundedRectangleBorder(
               side: !externalCallsEnabled

From bf0f0bc48cfbf78f34c97f9a5f59a12a62c0d80e Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 14:14:18 -0600
Subject: [PATCH 102/426] language dialog ui

---
 .../language_settings/language_dialog.dart    | 362 ++++++++++++++++++
 .../language_settings.dart                    |  16 +-
 2 files changed, 377 insertions(+), 1 deletion(-)
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
 rename lib/pages_desktop_specific/home/settings_menu/{ => language_settings}/language_settings.dart (88%)

diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
new file mode 100644
index 000000000..0bf5d0fcd
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
@@ -0,0 +1,362 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/languages_enum.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+
+import '../../../../utilities/assets.dart';
+
+class LanguageDialog extends ConsumerStatefulWidget {
+  const LanguageDialog({Key? key}) : super(key: key);
+
+  @override
+  ConsumerState<LanguageDialog> createState() => _LanguageDialog();
+}
+
+class _LanguageDialog extends ConsumerState<LanguageDialog> {
+  late final TextEditingController searchLanguageController;
+
+  late final FocusNode searchLanguageFocusNode;
+
+  final languages = Language.values.map((e) => e.description).toList();
+
+  late String current;
+  late List<String> listWithoutSelected;
+
+  void onTap(int index) {
+    if (index == 0 || current.isEmpty) {
+      // ignore if already selected language
+      return;
+    }
+    current = listWithoutSelected[index];
+    listWithoutSelected.remove(current);
+    listWithoutSelected.insert(0, current);
+    ref.read(prefsChangeNotifierProvider).language = current;
+  }
+
+  BorderRadius? _borderRadius(int index) {
+    if (index == 0 && listWithoutSelected.length == 1) {
+      return BorderRadius.circular(
+        Constants.size.circularBorderRadius,
+      );
+    } else if (index == 0) {
+      return BorderRadius.vertical(
+        top: Radius.circular(
+          Constants.size.circularBorderRadius,
+        ),
+      );
+    } else if (index == listWithoutSelected.length - 1) {
+      return BorderRadius.vertical(
+        bottom: Radius.circular(
+          Constants.size.circularBorderRadius,
+        ),
+      );
+    }
+    return null;
+  }
+
+  String filter = "";
+
+  List<String> _filtered() {
+    return listWithoutSelected
+        .where(
+            (element) => element.toLowerCase().contains(filter.toLowerCase()))
+        .toList();
+  }
+
+  @override
+  void initState() {
+    searchLanguageController = TextEditingController();
+
+    searchLanguageFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    searchLanguageController.dispose();
+
+    searchLanguageFocusNode.dispose();
+
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    current = ref
+        .watch(prefsChangeNotifierProvider.select((value) => value.language));
+
+    return DesktopDialog(
+      maxHeight: 700,
+      maxWidth: 600,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.all(32),
+                child: Text(
+                  "Select language",
+                  style: STextStyles.desktopH3(context),
+                  textAlign: TextAlign.center,
+                ),
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+          Padding(
+            padding: EdgeInsets.symmetric(vertical: 16, horizontal: 32),
+            child: Column(
+              children: [
+                ClipRRect(
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
+                  child: TextField(
+                    autocorrect: false,
+                    enableSuggestions: false,
+                    controller: searchLanguageController,
+                    focusNode: searchLanguageFocusNode,
+                    style: STextStyles.desktopTextMedium(context).copyWith(
+                      height: 2,
+                    ),
+                    textAlign: TextAlign.left,
+                    decoration: standardInputDecoration(
+                            "Search", searchLanguageFocusNode, context)
+                        .copyWith(
+                      prefixIcon: Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 10,
+                          vertical: 16,
+                        ),
+                        child: SvgPicture.asset(
+                          Assets.svg.search,
+                          width: 16,
+                          height: 16,
+                        ),
+                      ),
+                    ),
+                  ),
+                ),
+              ],
+            ),
+          ),
+          const Spacer(),
+          Padding(
+            padding: const EdgeInsets.all(32),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    onPressed: () {
+                      Navigator.of(context).pop();
+                    },
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Save Changes",
+                    onPressed: () {},
+                  ),
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+// NestedScrollView(
+//   floatHeaderSlivers: true,
+//   headerSliverBuilder: (context, innerBoxIsScrolled) {
+//     return [
+//       SliverOverlapAbsorber(
+//         handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+//             context),
+//         sliver: SliverToBoxAdapter(
+//           child: Padding(
+//             padding: const EdgeInsets.only(bottom: 16),
+//             child: ClipRRect(
+//               borderRadius: BorderRadius.circular(
+//                 Constants.size.circularBorderRadius,
+//               ),
+//               child: TextField(
+//                 autocorrect: Util.isDesktop ? false : true,
+//                 enableSuggestions:
+//                     Util.isDesktop ? false : true,
+//                 controller: searchLanguageController,
+//                 focusNode: searchLanguageFocusNode,
+//                 onChanged: (newString) {
+//                   setState(() => filter = newString);
+//                 },
+//                 style: STextStyles.field(context),
+//                 decoration: standardInputDecoration(
+//                   "Search",
+//                   searchLanguageFocusNode,
+//                   context,
+//                 ).copyWith(
+//                   prefixIcon: Padding(
+//                     padding: const EdgeInsets.symmetric(
+//                       horizontal: 10,
+//                       vertical: 16,
+//                     ),
+//                     child: SvgPicture.asset(
+//                       Assets.svg.search,
+//                       width: 16,
+//                       height: 16,
+//                     ),
+//                   ),
+//                   suffixIcon: searchLanguageController
+//                           .text.isNotEmpty
+//                       ? Padding(
+//                           padding:
+//                               const EdgeInsets.only(right: 0),
+//                           child: UnconstrainedBox(
+//                             child: Row(
+//                               children: [
+//                                 TextFieldIconButton(
+//                                   child: const XIcon(),
+//                                   onTap: () async {
+//                                     setState(() {
+//                                       searchLanguageController
+//                                           .text = "";
+//                                       filter = "";
+//                                     });
+//                                   },
+//                                 ),
+//                               ],
+//                             ),
+//                           ),
+//                         )
+//                       : null,
+//                 ),
+//               ),
+//             ),
+//           ),
+//         ),
+//       ),
+//     ];
+//   },
+//   body: Builder(
+//     builder: (context) {
+//       return CustomScrollView(
+//         slivers: [
+//           SliverOverlapInjector(
+//             handle:
+//                 NestedScrollView.sliverOverlapAbsorberHandleFor(
+//               context,
+//             ),
+//           ),
+//           SliverList(
+//             delegate: SliverChildBuilderDelegate(
+//               (context, index) {
+//                 return Container(
+//                   decoration: BoxDecoration(
+//                     color: Theme.of(context)
+//                         .extension<StackColors>()!
+//                         .popupBG,
+//                     borderRadius: _borderRadius(index),
+//                   ),
+//                   child: Padding(
+//                     padding: const EdgeInsets.all(4),
+//                     key: Key(
+//                         "languageSelect_${listWithoutSelected[index]}"),
+//                     child: RoundedContainer(
+//                       padding: const EdgeInsets.all(0),
+//                       color: index == 0
+//                           ? Theme.of(context)
+//                               .extension<StackColors>()!
+//                               .currencyListItemBG
+//                           : Theme.of(context)
+//                               .extension<StackColors>()!
+//                               .popupBG,
+//                       child: RawMaterialButton(
+//                         onPressed: () async {
+//                           onTap(index);
+//                         },
+//                         shape: RoundedRectangleBorder(
+//                           borderRadius: BorderRadius.circular(
+//                             Constants.size.circularBorderRadius,
+//                           ),
+//                         ),
+//                         child: Padding(
+//                           padding: const EdgeInsets.all(12.0),
+//                           child: Row(
+//                             crossAxisAlignment:
+//                                 CrossAxisAlignment.start,
+//                             children: [
+//                               SizedBox(
+//                                 width: 20,
+//                                 height: 20,
+//                                 child: Radio(
+//                                   activeColor: Theme.of(context)
+//                                       .extension<StackColors>()!
+//                                       .radioButtonIconEnabled,
+//                                   value: true,
+//                                   groupValue: index == 0,
+//                                   onChanged: (_) {
+//                                     onTap(index);
+//                                   },
+//                                 ),
+//                               ),
+//                               const SizedBox(
+//                                 width: 12,
+//                               ),
+//                               Column(
+//                                 crossAxisAlignment:
+//                                     CrossAxisAlignment.start,
+//                                 children: [
+//                                   Text(
+//                                     listWithoutSelected[index],
+//                                     key: (index == 0)
+//                                         ? const Key(
+//                                             "selectedLanguageSettingsLanguageText")
+//                                         : null,
+//                                     style: STextStyles
+//                                         .largeMedium14(context),
+//                                   ),
+//                                   const SizedBox(
+//                                     height: 2,
+//                                   ),
+//                                   Text(
+//                                     listWithoutSelected[index],
+//                                     key: (index == 0)
+//                                         ? const Key(
+//                                             "selectedLanguageSettingsLanguageTextDescription")
+//                                         : null,
+//                                     style: STextStyles
+//                                         .itemSubtitle(context),
+//                                   ),
+//                                 ],
+//                               ),
+//                             ],
+//                           ),
+//                         ),
+//                       ),
+//                     ),
+//                   ),
+//                 );
+//               },
+//               childCount: listWithoutSelected.length,
+//             ),
+//           ),
+//         ],
+//       );
+//     },
+//   ),
+// ),
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
similarity index 88%
rename from lib/pages_desktop_specific/home/settings_menu/language_settings.dart
rename to lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
index 7655188e1..97b807b3b 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -87,6 +88,17 @@ class ChangeLanguageButton extends ConsumerWidget {
   }) : super(key: key);
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    Future<void> chooseLanguage() async {
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: true,
+        builder: (context) {
+          return LanguageDialog();
+        },
+      );
+    }
+
     return SizedBox(
       width: 200,
       height: 48,
@@ -94,7 +106,9 @@ class ChangeLanguageButton extends ConsumerWidget {
         style: Theme.of(context)
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
+        onPressed: () {
+          chooseLanguage();
+        },
         child: Text(
           "Change language",
           style: STextStyles.button(context),

From 95a35a5dd0a960b6ca1a03b4f075d53040ad8de4 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 14:16:16 -0600
Subject: [PATCH 103/426] more import fixes

---
 .../home/desktop_settings_view.dart           |  4 +--
 .../advanced_settings/advanced_settings.dart  | 32 +++++++++----------
 lib/route_generator.dart                      |  5 +--
 3 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index 34cb07f27..9b3f897a9 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -1,10 +1,10 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
index 7361d9773..1632576fd 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
@@ -1,7 +1,8 @@
 import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings/stack_privacy_dialog.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -165,7 +166,7 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
                                     .textDark),
                         textAlign: TextAlign.left,
                       ),
-                      const ShowLogsButton(),
+                      ShowLogsButton(),
                     ],
                   ),
                 ),
@@ -190,7 +191,7 @@ class StackPrivacyButton extends ConsumerWidget {
         useSafeArea: false,
         barrierDismissible: true,
         builder: (context) {
-          return const StackPrivacyDialog();
+          return StackPrivacyDialog();
         },
       );
     }
@@ -223,20 +224,19 @@ class ShowLogsButton extends ConsumerWidget {
   const ShowLogsButton({
     Key? key,
   }) : super(key: key);
-
-  Future<void> viewDebugLogs() async {
-    // await showDialog<dynamic>(
-    //   context: context,
-    //   useSafeArea: false,
-    //   barrierDismissible: true,
-    //   builder: (context) {
-    //     return const DebugInfoDialog();
-    //   },
-    // );
-  }
-
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    // Future<void> viewDebugLogs() async {
+    //   await showDialog<dynamic>(
+    //     context: context,
+    //     useSafeArea: false,
+    //     barrierDismissible: true,
+    //     builder: (context) {
+    //       return const DebugInfoDialog();
+    //     },
+    //   );
+    // }
+
     return SizedBox(
       width: 101,
       height: 37,
@@ -246,7 +246,7 @@ class ShowLogsButton extends ConsumerWidget {
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {
           //
-          viewDebugLogs();
+          // viewDebugLogs();
         },
         child: Text(
           "Show logs",
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index edc677946..c5b764995 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -91,11 +91,10 @@ import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_v
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
-import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
@@ -107,6 +106,8 @@ import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:tuple/tuple.dart';
 
+import 'pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart';
+
 class RouteGenerator {
   static const bool useMaterialPageRoute = true;
 

From 4aec412ce70ba38a149bc3c5e6d7742cce488edb Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 14:16:38 -0600
Subject: [PATCH 104/426] working language dialog

---
 .../language_settings/language_dialog.dart    | 408 +++++++++---------
 1 file changed, 197 insertions(+), 211 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
index 0bf5d0fcd..f68196710 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
@@ -12,6 +12,10 @@ import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 
 import '../../../../utilities/assets.dart';
+import '../../../../utilities/theme/stack_colors.dart';
+import '../../../../widgets/icon_widgets/x_icon.dart';
+import '../../../../widgets/rounded_container.dart';
+import '../../../../widgets/textfield_icon_button.dart';
 
 class LanguageDialog extends ConsumerStatefulWidget {
   const LanguageDialog({Key? key}) : super(key: key);
@@ -94,6 +98,13 @@ class _LanguageDialog extends ConsumerState<LanguageDialog> {
     current = ref
         .watch(prefsChangeNotifierProvider.select((value) => value.language));
 
+    listWithoutSelected = languages;
+    if (current.isNotEmpty) {
+      listWithoutSelected.remove(current);
+      listWithoutSelected.insert(0, current);
+    }
+    listWithoutSelected = _filtered();
+
     return DesktopDialog(
       maxHeight: 700,
       maxWidth: 600,
@@ -113,41 +124,196 @@ class _LanguageDialog extends ConsumerState<LanguageDialog> {
               const DesktopDialogCloseButton(),
             ],
           ),
-          Padding(
-            padding: EdgeInsets.symmetric(vertical: 16, horizontal: 32),
-            child: Column(
-              children: [
-                ClipRRect(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
-                  child: TextField(
-                    autocorrect: false,
-                    enableSuggestions: false,
-                    controller: searchLanguageController,
-                    focusNode: searchLanguageFocusNode,
-                    style: STextStyles.desktopTextMedium(context).copyWith(
-                      height: 2,
-                    ),
-                    textAlign: TextAlign.left,
-                    decoration: standardInputDecoration(
-                            "Search", searchLanguageFocusNode, context)
-                        .copyWith(
-                      prefixIcon: Padding(
-                        padding: const EdgeInsets.symmetric(
-                          horizontal: 10,
-                          vertical: 16,
-                        ),
-                        child: SvgPicture.asset(
-                          Assets.svg.search,
-                          width: 16,
-                          height: 16,
+          Expanded(
+            child: NestedScrollView(
+              floatHeaderSlivers: true,
+              headerSliverBuilder: (context, innerBoxIsScrolled) {
+                return [
+                  SliverOverlapAbsorber(
+                    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+                        context),
+                    sliver: SliverToBoxAdapter(
+                      child: Padding(
+                        padding:
+                            EdgeInsets.symmetric(vertical: 16, horizontal: 32),
+                        child: Column(
+                          children: [
+                            Padding(
+                              padding: const EdgeInsets.only(bottom: 16),
+                              child: ClipRRect(
+                                borderRadius: BorderRadius.circular(
+                                  Constants.size.circularBorderRadius,
+                                ),
+                                child: TextField(
+                                  autocorrect: false,
+                                  enableSuggestions: false,
+                                  controller: searchLanguageController,
+                                  focusNode: searchLanguageFocusNode,
+                                  style: STextStyles.desktopTextMedium(context)
+                                      .copyWith(
+                                    height: 2,
+                                  ),
+                                  textAlign: TextAlign.left,
+                                  decoration: standardInputDecoration("Search",
+                                          searchLanguageFocusNode, context)
+                                      .copyWith(
+                                    prefixIcon: Padding(
+                                      padding: const EdgeInsets.symmetric(
+                                        horizontal: 10,
+                                        vertical: 16,
+                                      ),
+                                      child: SvgPicture.asset(
+                                        Assets.svg.search,
+                                        width: 16,
+                                        height: 16,
+                                      ),
+                                    ),
+                                    suffixIcon: searchLanguageController
+                                            .text.isNotEmpty
+                                        ? Padding(
+                                            padding:
+                                                const EdgeInsets.only(right: 0),
+                                            child: UnconstrainedBox(
+                                              child: Row(
+                                                children: [
+                                                  TextFieldIconButton(
+                                                    child: const XIcon(),
+                                                    onTap: () async {
+                                                      setState(() {
+                                                        searchLanguageController
+                                                            .text = "";
+                                                        filter = "";
+                                                      });
+                                                    },
+                                                  ),
+                                                ],
+                                              ),
+                                            ),
+                                          )
+                                        : null,
+                                  ),
+                                ),
+                              ),
+                            ),
+                          ],
                         ),
                       ),
                     ),
                   ),
-                ),
-              ],
+                ];
+              },
+              body: Builder(
+                builder: (context) {
+                  return CustomScrollView(
+                    slivers: [
+                      SliverOverlapInjector(
+                        handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+                          context,
+                        ),
+                      ),
+                      SliverList(
+                        delegate: SliverChildBuilderDelegate(
+                          (context, index) {
+                            return Container(
+                              decoration: BoxDecoration(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .popupBG,
+                                borderRadius: _borderRadius(index),
+                              ),
+                              child: Padding(
+                                padding: const EdgeInsets.all(4),
+                                key: Key(
+                                    "desktopSelectLanguage_${listWithoutSelected[index]}"),
+                                child: Padding(
+                                  padding: const EdgeInsets.symmetric(
+                                      horizontal: 32),
+                                  child: RoundedContainer(
+                                    padding: const EdgeInsets.all(0),
+                                    color: index == 0
+                                        ? Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .currencyListItemBG
+                                        : Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .popupBG,
+                                    child: RawMaterialButton(
+                                      onPressed: () async {
+                                        onTap(index);
+                                      },
+                                      shape: RoundedRectangleBorder(
+                                        borderRadius: BorderRadius.circular(
+                                          Constants.size.circularBorderRadius,
+                                        ),
+                                      ),
+                                      child: Padding(
+                                        padding: const EdgeInsets.all(12.0),
+                                        child: Row(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            SizedBox(
+                                              width: 20,
+                                              height: 20,
+                                              child: Radio(
+                                                activeColor: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .radioButtonIconEnabled,
+                                                value: true,
+                                                groupValue: index == 0,
+                                                onChanged: (_) {
+                                                  onTap(index);
+                                                },
+                                              ),
+                                            ),
+                                            const SizedBox(
+                                              width: 12,
+                                            ),
+                                            Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.start,
+                                              children: [
+                                                Text(
+                                                  listWithoutSelected[index],
+                                                  key: (index == 0)
+                                                      ? const Key(
+                                                          "desktopSettingsSelectedLanguageText")
+                                                      : null,
+                                                  style:
+                                                      STextStyles.largeMedium14(
+                                                          context),
+                                                ),
+                                                const SizedBox(
+                                                  height: 2,
+                                                ),
+                                                Text(
+                                                  listWithoutSelected[index],
+                                                  key: (index == 0)
+                                                      ? const Key(
+                                                          "desktopSettingsSelectedLanguageTextDescription")
+                                                      : null,
+                                                  style:
+                                                      STextStyles.itemSubtitle(
+                                                          context),
+                                                ),
+                                              ],
+                                            ),
+                                          ],
+                                        ),
+                                      ),
+                                    ),
+                                  ),
+                                ),
+                              ),
+                            );
+                          },
+                          childCount: listWithoutSelected.length,
+                        ),
+                      ),
+                    ],
+                  );
+                },
+              ),
             ),
           ),
           const Spacer(),
@@ -180,183 +346,3 @@ class _LanguageDialog extends ConsumerState<LanguageDialog> {
     );
   }
 }
-
-// NestedScrollView(
-//   floatHeaderSlivers: true,
-//   headerSliverBuilder: (context, innerBoxIsScrolled) {
-//     return [
-//       SliverOverlapAbsorber(
-//         handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
-//             context),
-//         sliver: SliverToBoxAdapter(
-//           child: Padding(
-//             padding: const EdgeInsets.only(bottom: 16),
-//             child: ClipRRect(
-//               borderRadius: BorderRadius.circular(
-//                 Constants.size.circularBorderRadius,
-//               ),
-//               child: TextField(
-//                 autocorrect: Util.isDesktop ? false : true,
-//                 enableSuggestions:
-//                     Util.isDesktop ? false : true,
-//                 controller: searchLanguageController,
-//                 focusNode: searchLanguageFocusNode,
-//                 onChanged: (newString) {
-//                   setState(() => filter = newString);
-//                 },
-//                 style: STextStyles.field(context),
-//                 decoration: standardInputDecoration(
-//                   "Search",
-//                   searchLanguageFocusNode,
-//                   context,
-//                 ).copyWith(
-//                   prefixIcon: Padding(
-//                     padding: const EdgeInsets.symmetric(
-//                       horizontal: 10,
-//                       vertical: 16,
-//                     ),
-//                     child: SvgPicture.asset(
-//                       Assets.svg.search,
-//                       width: 16,
-//                       height: 16,
-//                     ),
-//                   ),
-//                   suffixIcon: searchLanguageController
-//                           .text.isNotEmpty
-//                       ? Padding(
-//                           padding:
-//                               const EdgeInsets.only(right: 0),
-//                           child: UnconstrainedBox(
-//                             child: Row(
-//                               children: [
-//                                 TextFieldIconButton(
-//                                   child: const XIcon(),
-//                                   onTap: () async {
-//                                     setState(() {
-//                                       searchLanguageController
-//                                           .text = "";
-//                                       filter = "";
-//                                     });
-//                                   },
-//                                 ),
-//                               ],
-//                             ),
-//                           ),
-//                         )
-//                       : null,
-//                 ),
-//               ),
-//             ),
-//           ),
-//         ),
-//       ),
-//     ];
-//   },
-//   body: Builder(
-//     builder: (context) {
-//       return CustomScrollView(
-//         slivers: [
-//           SliverOverlapInjector(
-//             handle:
-//                 NestedScrollView.sliverOverlapAbsorberHandleFor(
-//               context,
-//             ),
-//           ),
-//           SliverList(
-//             delegate: SliverChildBuilderDelegate(
-//               (context, index) {
-//                 return Container(
-//                   decoration: BoxDecoration(
-//                     color: Theme.of(context)
-//                         .extension<StackColors>()!
-//                         .popupBG,
-//                     borderRadius: _borderRadius(index),
-//                   ),
-//                   child: Padding(
-//                     padding: const EdgeInsets.all(4),
-//                     key: Key(
-//                         "languageSelect_${listWithoutSelected[index]}"),
-//                     child: RoundedContainer(
-//                       padding: const EdgeInsets.all(0),
-//                       color: index == 0
-//                           ? Theme.of(context)
-//                               .extension<StackColors>()!
-//                               .currencyListItemBG
-//                           : Theme.of(context)
-//                               .extension<StackColors>()!
-//                               .popupBG,
-//                       child: RawMaterialButton(
-//                         onPressed: () async {
-//                           onTap(index);
-//                         },
-//                         shape: RoundedRectangleBorder(
-//                           borderRadius: BorderRadius.circular(
-//                             Constants.size.circularBorderRadius,
-//                           ),
-//                         ),
-//                         child: Padding(
-//                           padding: const EdgeInsets.all(12.0),
-//                           child: Row(
-//                             crossAxisAlignment:
-//                                 CrossAxisAlignment.start,
-//                             children: [
-//                               SizedBox(
-//                                 width: 20,
-//                                 height: 20,
-//                                 child: Radio(
-//                                   activeColor: Theme.of(context)
-//                                       .extension<StackColors>()!
-//                                       .radioButtonIconEnabled,
-//                                   value: true,
-//                                   groupValue: index == 0,
-//                                   onChanged: (_) {
-//                                     onTap(index);
-//                                   },
-//                                 ),
-//                               ),
-//                               const SizedBox(
-//                                 width: 12,
-//                               ),
-//                               Column(
-//                                 crossAxisAlignment:
-//                                     CrossAxisAlignment.start,
-//                                 children: [
-//                                   Text(
-//                                     listWithoutSelected[index],
-//                                     key: (index == 0)
-//                                         ? const Key(
-//                                             "selectedLanguageSettingsLanguageText")
-//                                         : null,
-//                                     style: STextStyles
-//                                         .largeMedium14(context),
-//                                   ),
-//                                   const SizedBox(
-//                                     height: 2,
-//                                   ),
-//                                   Text(
-//                                     listWithoutSelected[index],
-//                                     key: (index == 0)
-//                                         ? const Key(
-//                                             "selectedLanguageSettingsLanguageTextDescription")
-//                                         : null,
-//                                     style: STextStyles
-//                                         .itemSubtitle(context),
-//                                   ),
-//                                 ],
-//                               ),
-//                             ],
-//                           ),
-//                         ),
-//                       ),
-//                     ),
-//                   ),
-//                 );
-//               },
-//               childCount: listWithoutSelected.length,
-//             ),
-//           ),
-//         ],
-//       );
-//     },
-//   ),
-// ),

From 1f1253e070d72829a6867510a6ceb55bfef9c2be Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 13:43:23 -0600
Subject: [PATCH 105/426] WIP: desktop wallet network settings popups

---
 .../wallet_network_settings_view.dart         | 891 +++++++++---------
 .../sub_widgets/network_info_button.dart      |  62 +-
 2 files changed, 513 insertions(+), 440 deletions(-)

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 5b1c57214..8195491d8 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
@@ -23,7 +23,9 @@ 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';
+import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/animated_text.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 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/progress_bar.dart';
@@ -75,17 +77,19 @@ class _WalletNetworkSettingsViewState
   late int _blocksRemaining;
 
   Future<void> _attemptRescan() async {
-    if (!Platform.isLinux) Wakelock.enable();
+    if (!Platform.isLinux) await Wakelock.enable();
 
     int maxUnusedAddressGap = 20;
 
     const int maxNumberOfIndexesToCheck = 1000;
 
-    showDialog<dynamic>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: false,
-      builder: (context) => const RescanningDialog(),
+    unawaited(
+      showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: false,
+        builder: (context) => const RescanningDialog(),
+      ),
     );
 
     try {
@@ -131,7 +135,7 @@ class _WalletNetworkSettingsViewState
         );
       }
     } catch (e) {
-      if (!Platform.isLinux) Wakelock.disable();
+      if (!Platform.isLinux) await Wakelock.disable();
 
       if (mounted) {
         // pop rescanning dialog
@@ -162,7 +166,7 @@ class _WalletNetworkSettingsViewState
       }
     }
 
-    if (!Platform.isLinux) Wakelock.disable();
+    if (!Platform.isLinux) await Wakelock.disable();
   }
 
   String _percentString(double value) {
@@ -262,9 +266,11 @@ class _WalletNetworkSettingsViewState
   @override
   Widget build(BuildContext context) {
     final screenWidth = MediaQuery.of(context).size.width;
+    final bool isDesktop = Util.isDesktop;
 
-    final progressLength =
-        screenWidth - (_padding * 2) - (_boxPadding * 3) - _iconSize;
+    final progressLength = isDesktop
+        ? 450.0
+        : screenWidth - (_padding * 2) - (_boxPadding * 3) - _iconSize;
 
     final coin = ref
         .read(walletsChangeNotifierProvider)
@@ -300,443 +306,464 @@ class _WalletNetworkSettingsViewState
       }
     }
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Network",
-          style: STextStyles.navBarTitle(context),
-        ),
-        actions: [
-          Padding(
-            padding: const EdgeInsets.only(
-              top: 10,
-              bottom: 10,
-              right: 10,
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
             ),
-            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,
+            title: Text(
+              "Network",
+              style: STextStyles.navBarTitle(context),
+            ),
+            actions: [
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
                 ),
-                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();
-                                      showDialog<dynamic>(
-                                        context: context,
-                                        useSafeArea: false,
-                                        barrierDismissible: true,
-                                        builder: (context) {
-                                          return ConfirmFullRescanDialog(
-                                            onConfirm: _attemptRescan,
+                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();
+                                          showDialog<dynamic>(
+                                            context: context,
+                                            useSafeArea: false,
+                                            barrierDismissible: true,
+                                            builder: (context) {
+                                              return ConfirmFullRescanDialog(
+                                                onConfirm: _attemptRescan,
+                                              );
+                                            },
                                           );
                                         },
-                                      );
-                                    },
-                                    child: RoundedWhiteContainer(
-                                      child: Material(
-                                        color: Colors.transparent,
-                                        child: Text(
-                                          "Rescan blockchain",
-                                          style: STextStyles.baseXS(context),
-                                        ),
-                                      ),
-                                    ),
-                                  ),
-                                ],
-                              ),
-                            ),
-                          ),
-                        ],
-                      );
-                    },
-                  );
-                },
-              ),
-            ),
-          ),
-        ],
-      ),
-      body: Padding(
-        padding: EdgeInsets.only(
-          top: 12,
-          left: _padding,
-          right: _padding,
-        ),
-        child: SingleChildScrollView(
-          child: Column(
-            crossAxisAlignment: CrossAxisAlignment.stretch,
-            children: [
-              Column(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "Blockchain status",
-                        textAlign: TextAlign.left,
-                        style: STextStyles.smallMed12(context),
-                      ),
-                      GestureDetector(
-                        onTap: () {
-                          ref
-                              .read(walletsChangeNotifierProvider)
-                              .getManager(widget.walletId)
-                              .refresh();
-                        },
-                        child: Text(
-                          "Resync",
-                          style: STextStyles.link2(context),
-                        ),
-                      ),
-                    ],
-                  ),
-                  const SizedBox(
-                    height: 9,
-                  ),
-                  if (_currentSyncStatus == WalletSyncStatus.synced)
-                    RoundedWhiteContainer(
-                      child: Row(
-                        children: [
-                          Container(
-                            width: _iconSize,
-                            height: _iconSize,
-                            decoration: BoxDecoration(
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .accentColorGreen
-                                  .withOpacity(0.2),
-                              borderRadius: BorderRadius.circular(_iconSize),
-                            ),
-                            child: Center(
-                              child: SvgPicture.asset(
-                                Assets.svg.radio,
-                                height: 14,
-                                width: 14,
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorGreen,
-                              ),
-                            ),
-                          ),
-                          SizedBox(
-                            width: _boxPadding,
-                          ),
-                          Column(
-                            children: [
-                              SizedBox(
-                                width: progressLength,
-                                child: Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
-                                  children: [
-                                    Text(
-                                      "Synchronized",
-                                      style: STextStyles.w600_10(context),
-                                    ),
-                                    Text(
-                                      "100%",
-                                      style: STextStyles.syncPercent(context)
-                                          .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorGreen,
-                                      ),
-                                    ),
-                                  ],
-                                ),
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              ProgressBar(
-                                width: progressLength,
-                                height: 5,
-                                fillColor: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorGreen,
-                                backgroundColor: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textFieldDefaultBG,
-                                percent: 1,
-                              ),
-                            ],
-                          ),
-                        ],
-                      ),
-                    ),
-                  if (_currentSyncStatus == WalletSyncStatus.syncing)
-                    RoundedWhiteContainer(
-                      child: Row(
-                        children: [
-                          Container(
-                            width: _iconSize,
-                            height: _iconSize,
-                            decoration: BoxDecoration(
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .accentColorYellow
-                                  .withOpacity(0.2),
-                              borderRadius: BorderRadius.circular(_iconSize),
-                            ),
-                            child: Center(
-                              child: SvgPicture.asset(
-                                Assets.svg.radioSyncing,
-                                height: 14,
-                                width: 14,
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorYellow,
-                              ),
-                            ),
-                          ),
-                          SizedBox(
-                            width: _boxPadding,
-                          ),
-                          Column(
-                            children: [
-                              SizedBox(
-                                width: progressLength,
-                                child: Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
-                                  children: [
-                                    AnimatedText(
-                                      style: STextStyles.w600_10(context),
-                                      stringsToLoopThrough: const [
-                                        "Synchronizing",
-                                        "Synchronizing.",
-                                        "Synchronizing..",
-                                        "Synchronizing...",
-                                      ],
-                                    ),
-                                    Row(
-                                      children: [
-                                        Text(
-                                          _percentString(_percent),
-                                          style:
-                                              STextStyles.syncPercent(context)
-                                                  .copyWith(
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .accentColorYellow,
-                                          ),
-                                        ),
-                                        if (coin == Coin.monero ||
-                                            coin == Coin.wownero ||
-                                            coin == Coin.epicCash)
-                                          Text(
-                                            " (Blocks to go: ${_blocksRemaining == -1 ? "?" : _blocksRemaining})",
-                                            style:
-                                                STextStyles.syncPercent(context)
-                                                    .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .accentColorYellow,
+                                        child: RoundedWhiteContainer(
+                                          child: Material(
+                                            color: Colors.transparent,
+                                            child: Text(
+                                              "Rescan blockchain",
+                                              style:
+                                                  STextStyles.baseXS(context),
                                             ),
                                           ),
-                                      ],
-                                    )
-                                  ],
+                                        ),
+                                      ),
+                                    ],
+                                  ),
                                 ),
                               ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              ProgressBar(
-                                width: progressLength,
-                                height: 5,
-                                fillColor: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorYellow,
-                                backgroundColor: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textFieldDefaultBG,
-                                percent: _percent,
-                              ),
                             ],
-                          ),
-                        ],
-                      ),
-                    ),
-                  if (_currentSyncStatus == WalletSyncStatus.unableToSync)
-                    RoundedWhiteContainer(
-                      child: Row(
-                        children: [
-                          Container(
-                            width: _iconSize,
-                            height: _iconSize,
-                            decoration: BoxDecoration(
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .accentColorRed
-                                  .withOpacity(0.2),
-                              borderRadius: BorderRadius.circular(_iconSize),
-                            ),
-                            child: Center(
-                              child: SvgPicture.asset(
-                                Assets.svg.radioProblem,
-                                height: 14,
-                                width: 14,
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorRed,
-                              ),
-                            ),
-                          ),
-                          SizedBox(
-                            width: _boxPadding,
-                          ),
-                          Column(
-                            children: [
-                              SizedBox(
-                                width: progressLength,
-                                child: Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
-                                  children: [
-                                    Text(
-                                      "Unable to synchronize",
-                                      style:
-                                          STextStyles.w600_10(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorRed,
-                                      ),
-                                    ),
-                                    Text(
-                                      "0%",
-                                      style: STextStyles.syncPercent(context)
-                                          .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorRed,
-                                      ),
-                                    ),
-                                  ],
-                                ),
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              ProgressBar(
-                                width: progressLength,
-                                height: 5,
-                                fillColor: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorRed,
-                                backgroundColor: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textFieldDefaultBG,
-                                percent: 0,
-                              ),
-                            ],
-                          ),
-                        ],
-                      ),
-                    ),
-                  if (_currentSyncStatus == WalletSyncStatus.unableToSync)
-                    Padding(
-                      padding: const EdgeInsets.only(
-                        top: 12,
-                      ),
-                      child: RoundedContainer(
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .warningBackground,
-                        child: Text(
-                          "Please check your internet connection and make sure your current node is not having issues.",
-                          style: STextStyles.baseXS(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .warningForeground,
-                          ),
-                        ),
-                      ),
-                    ),
-                  const SizedBox(
-                    height: 20,
-                  ),
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "${ref.watch(walletsChangeNotifierProvider.select((value) => value.getManager(widget.walletId).coin)).prettyName} nodes",
-                        textAlign: TextAlign.left,
-                        style: STextStyles.smallMed12(context),
-                      ),
-                      BlueTextButton(
-                        text: "Add new node",
-                        onTap: () {
-                          Navigator.of(context).pushNamed(
-                            AddEditNodeView.routeName,
-                            arguments: Tuple4(
-                              AddEditNodeViewType.add,
-                              ref
-                                  .read(walletsChangeNotifierProvider)
-                                  .getManager(widget.walletId)
-                                  .coin,
-                              null,
-                              WalletNetworkSettingsView.routeName,
-                            ),
                           );
                         },
-                      ),
-                    ],
+                      );
+                    },
                   ),
-                  const SizedBox(
-                    height: 8,
-                  ),
-                  NodesList(
-                    coin: ref.watch(walletsChangeNotifierProvider.select(
-                        (value) => value.getManager(widget.walletId).coin)),
-                    popBackToRoute: WalletNetworkSettingsView.routeName,
-                  ),
-                ],
+                ),
               ),
             ],
           ),
-        ),
+          body: Padding(
+            padding: EdgeInsets.only(
+              top: 12,
+              left: _padding,
+              right: _padding,
+            ),
+            child: SingleChildScrollView(
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: [
+                  child,
+                ],
+              ),
+            ),
+          ),
+        );
+      },
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Text(
+                "Blockchain status",
+                textAlign: TextAlign.left,
+                style: isDesktop
+                    ? STextStyles.desktopTextExtraExtraSmall(context)
+                    : STextStyles.smallMed12(context),
+              ),
+              GestureDetector(
+                onTap: () {
+                  ref
+                      .read(walletsChangeNotifierProvider)
+                      .getManager(widget.walletId)
+                      .refresh();
+                },
+                child: Text(
+                  "Resync",
+                  style: STextStyles.link2(context),
+                ),
+              ),
+            ],
+          ),
+          const SizedBox(
+            height: 9,
+          ),
+          if (_currentSyncStatus == WalletSyncStatus.synced)
+            RoundedWhiteContainer(
+              child: Row(
+                children: [
+                  Container(
+                    width: _iconSize,
+                    height: _iconSize,
+                    decoration: BoxDecoration(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorGreen
+                          .withOpacity(0.2),
+                      borderRadius: BorderRadius.circular(_iconSize),
+                    ),
+                    child: Center(
+                      child: SvgPicture.asset(
+                        Assets.svg.radio,
+                        height: 14,
+                        width: 14,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorGreen,
+                      ),
+                    ),
+                  ),
+                  SizedBox(
+                    width: _boxPadding,
+                  ),
+                  Column(
+                    children: [
+                      SizedBox(
+                        width: progressLength,
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          children: [
+                            Text(
+                              "Synchronized",
+                              style: STextStyles.w600_10(context),
+                            ),
+                            Text(
+                              "100%",
+                              style: STextStyles.syncPercent(context).copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorGreen,
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                      const SizedBox(
+                        height: 4,
+                      ),
+                      ProgressBar(
+                        width: progressLength,
+                        height: 5,
+                        fillColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorGreen,
+                        backgroundColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
+                        percent: 1,
+                      ),
+                    ],
+                  ),
+                ],
+              ),
+            ),
+          if (_currentSyncStatus == WalletSyncStatus.syncing)
+            RoundedWhiteContainer(
+              child: Row(
+                children: [
+                  Container(
+                    width: _iconSize,
+                    height: _iconSize,
+                    decoration: BoxDecoration(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorYellow
+                          .withOpacity(0.2),
+                      borderRadius: BorderRadius.circular(_iconSize),
+                    ),
+                    child: Center(
+                      child: SvgPicture.asset(
+                        Assets.svg.radioSyncing,
+                        height: 14,
+                        width: 14,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorYellow,
+                      ),
+                    ),
+                  ),
+                  SizedBox(
+                    width: _boxPadding,
+                  ),
+                  Column(
+                    children: [
+                      SizedBox(
+                        width: progressLength,
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          children: [
+                            AnimatedText(
+                              style: STextStyles.w600_10(context),
+                              stringsToLoopThrough: const [
+                                "Synchronizing",
+                                "Synchronizing.",
+                                "Synchronizing..",
+                                "Synchronizing...",
+                              ],
+                            ),
+                            Row(
+                              children: [
+                                Text(
+                                  _percentString(_percent),
+                                  style:
+                                      STextStyles.syncPercent(context).copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorYellow,
+                                  ),
+                                ),
+                                if (coin == Coin.monero ||
+                                    coin == Coin.wownero ||
+                                    coin == Coin.epicCash)
+                                  Text(
+                                    " (Blocks to go: ${_blocksRemaining == -1 ? "?" : _blocksRemaining})",
+                                    style: STextStyles.syncPercent(context)
+                                        .copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .accentColorYellow,
+                                    ),
+                                  ),
+                              ],
+                            )
+                          ],
+                        ),
+                      ),
+                      const SizedBox(
+                        height: 4,
+                      ),
+                      ProgressBar(
+                        width: progressLength,
+                        height: 5,
+                        fillColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorYellow,
+                        backgroundColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
+                        percent: _percent,
+                      ),
+                    ],
+                  ),
+                ],
+              ),
+            ),
+          if (_currentSyncStatus == WalletSyncStatus.unableToSync)
+            RoundedWhiteContainer(
+              child: Row(
+                children: [
+                  Container(
+                    width: _iconSize,
+                    height: _iconSize,
+                    decoration: BoxDecoration(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorRed
+                          .withOpacity(0.2),
+                      borderRadius: BorderRadius.circular(_iconSize),
+                    ),
+                    child: Center(
+                      child: SvgPicture.asset(
+                        Assets.svg.radioProblem,
+                        height: 14,
+                        width: 14,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorRed,
+                      ),
+                    ),
+                  ),
+                  SizedBox(
+                    width: _boxPadding,
+                  ),
+                  Column(
+                    children: [
+                      SizedBox(
+                        width: progressLength,
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          children: [
+                            Text(
+                              "Unable to synchronize",
+                              style: STextStyles.w600_10(context).copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorRed,
+                              ),
+                            ),
+                            Text(
+                              "0%",
+                              style: STextStyles.syncPercent(context).copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorRed,
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                      const SizedBox(
+                        height: 4,
+                      ),
+                      ProgressBar(
+                        width: progressLength,
+                        height: 5,
+                        fillColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorRed,
+                        backgroundColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
+                        percent: 0,
+                      ),
+                    ],
+                  ),
+                ],
+              ),
+            ),
+          if (_currentSyncStatus == WalletSyncStatus.unableToSync)
+            Padding(
+              padding: const EdgeInsets.only(
+                top: 12,
+              ),
+              child: RoundedContainer(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .warningBackground,
+                child: Text(
+                  "Please check your internet connection and make sure your current node is not having issues.",
+                  style: STextStyles.baseXS(context).copyWith(
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .warningForeground,
+                  ),
+                ),
+              ),
+            ),
+          const SizedBox(
+            height: 20,
+          ),
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Text(
+                "${ref.watch(walletsChangeNotifierProvider.select((value) => value.getManager(widget.walletId).coin)).prettyName} nodes",
+                textAlign: TextAlign.left,
+                style: isDesktop
+                    ? STextStyles.desktopTextExtraExtraSmall(context)
+                    : STextStyles.smallMed12(context),
+              ),
+              BlueTextButton(
+                text: "Add new node",
+                onTap: () {
+                  Navigator.of(context).pushNamed(
+                    AddEditNodeView.routeName,
+                    arguments: Tuple4(
+                      AddEditNodeViewType.add,
+                      ref
+                          .read(walletsChangeNotifierProvider)
+                          .getManager(widget.walletId)
+                          .coin,
+                      null,
+                      WalletNetworkSettingsView.routeName,
+                    ),
+                  );
+                },
+              ),
+            ],
+          ),
+          const SizedBox(
+            height: 8,
+          ),
+          NodesList(
+            coin: ref.watch(walletsChangeNotifierProvider
+                .select((value) => value.getManager(widget.walletId).coin)),
+            popBackToRoute: WalletNetworkSettingsView.routeName,
+          ),
+          if (isDesktop)
+            const SizedBox(
+              height: 20,
+            ),
+          if (isDesktop)
+            Row(
+              mainAxisAlignment: MainAxisAlignment.start,
+              children: [
+                Text(
+                  "Advanced",
+                  textAlign: TextAlign.left,
+                  style: STextStyles.desktopTextExtraExtraSmall(context),
+                ),
+              ],
+            ),
+        ],
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
index 830b5e667..37cd414c7 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
@@ -12,6 +12,9 @@ import 'package:stackwallet/services/event_bus/global_event_bus.dart';
 import 'package:stackwallet/utilities/assets.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/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:tuple/tuple.dart';
 
 class NetworkInfoButton extends ConsumerStatefulWidget {
@@ -150,14 +153,57 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
   Widget build(BuildContext context) {
     return GestureDetector(
       onTap: () {
-        Navigator.of(context).pushNamed(
-          WalletNetworkSettingsView.routeName,
-          arguments: Tuple3(
-            walletId,
-            _currentSyncStatus,
-            _currentNodeStatus,
-          ),
-        );
+        if (Util.isDesktop) {
+          showDialog<void>(
+            context: context,
+            builder: (context) => DesktopDialog(
+              maxHeight: 600,
+              maxWidth: 580,
+              child: Column(
+                mainAxisSize: MainAxisSize.min,
+                children: [
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      left: 32,
+                    ),
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Text(
+                          "Network",
+                          style: STextStyles.desktopH3(context),
+                        ),
+                        const DesktopDialogCloseButton(),
+                      ],
+                    ),
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      top: 16,
+                      left: 32,
+                      right: 32,
+                      bottom: 32,
+                    ),
+                    child: WalletNetworkSettingsView(
+                      walletId: walletId,
+                      initialSyncStatus: _currentSyncStatus,
+                      initialNodeStatus: _currentNodeStatus,
+                    ),
+                  ),
+                ],
+              ),
+            ),
+          );
+        } else {
+          Navigator.of(context).pushNamed(
+            WalletNetworkSettingsView.routeName,
+            arguments: Tuple3(
+              walletId,
+              _currentSyncStatus,
+              _currentNodeStatus,
+            ),
+          );
+        }
       },
       child: Container(
         color: Colors.transparent,

From 2afec92279c8faab60ba1baec3eb3bd29caeaff6 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 14:24:41 -0600
Subject: [PATCH 106/426]  desktop wallet network settings expanding advanced
 rescan

---
 assets/svg/network-wired-2.svg                |  10 ++
 .../sub_widgets/confirm_full_rescan.dart      | 139 +++++++++++----
 .../wallet_network_settings_view.dart         | 163 ++++++++++++++++--
 lib/utilities/assets.dart                     |   1 +
 lib/widgets/conditional_parent.dart           |   4 +-
 pubspec.yaml                                  |   1 +
 6 files changed, 266 insertions(+), 52 deletions(-)
 create mode 100644 assets/svg/network-wired-2.svg

diff --git a/assets/svg/network-wired-2.svg b/assets/svg/network-wired-2.svg
new file mode 100644
index 000000000..bbbfa056f
--- /dev/null
+++ b/assets/svg/network-wired-2.svg
@@ -0,0 +1,10 @@
+<svg width="24" height="19" viewBox="0 0 24 19" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_6129_18406)">
+<path d="M14.9173 0C15.8835 0 16.6673 0.769499 16.6673 1.71875V5.15625C16.6673 6.10514 15.8835 6.875 14.9173 6.875H13.1673V8.02083H22.5007C23.146 8.02083 23.6673 8.53288 23.6673 9.16667C23.6673 9.80046 23.146 10.3125 22.5007 10.3125H19.0007V11.4583H20.7507C21.7168 11.4583 22.5007 12.2282 22.5007 13.1771V16.6146C22.5007 17.5635 21.7168 18.3333 20.7507 18.3333H14.9173C13.9512 18.3333 13.1673 17.5635 13.1673 16.6146V13.1771C13.1673 12.2282 13.9512 11.4583 14.9173 11.4583H16.6673V10.3125H7.33398V11.4583H9.08398C10.0501 11.4583 10.834 12.2282 10.834 13.1771V16.6146C10.834 17.5635 10.0501 18.3333 9.08398 18.3333H3.25065C2.28414 18.3333 1.50065 17.5635 1.50065 16.6146V13.1771C1.50065 12.2282 2.28414 11.4583 3.25065 11.4583H5.00065V10.3125H1.50065C0.856432 10.3125 0.333984 9.80046 0.333984 9.16667C0.333984 8.53288 0.856432 8.02083 1.50065 8.02083H10.834V6.875H9.08398C8.11784 6.875 7.33398 6.10514 7.33398 5.15625V1.71875C7.33398 0.769499 8.11784 0 9.08398 0H14.9173ZM9.66732 2.29167V4.58333H14.334V2.29167H9.66732ZM8.50065 16.0417V13.75H3.83398V16.0417H8.50065ZM15.5007 13.75V16.0417H20.1673V13.75H15.5007Z" fill="#232323"/>
+</g>
+<defs>
+<clipPath id="clip0_6129_18406">
+<rect width="23.3333" height="18.3333" fill="white" transform="translate(0.333984)"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
index 141eb4c99..950d8d79e 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
@@ -1,6 +1,11 @@
 import 'package:flutter/material.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/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
 class ConfirmFullRescanDialog extends StatelessWidget {
@@ -11,40 +16,110 @@ class ConfirmFullRescanDialog extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return WillPopScope(
-      onWillPop: () async {
-        return true;
-      },
-      child: StackDialog(
-        title: "Rescan blockchain",
-        message:
-            "Warning! It may take a while. If you exit before completion, you will have to redo the process.",
-        leftButton: TextButton(
-          style: Theme.of(context)
-              .extension<StackColors>()!
-              .getSecondaryEnabledButtonColor(context),
-          child: Text(
-            "Cancel",
-            style: STextStyles.itemSubtitle12(context),
-          ),
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    if (Util.isDesktop) {
+      return DesktopDialog(
+        maxWidth: 576,
+        child: Column(
+          mainAxisSize: MainAxisSize.min,
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.only(
+                    left: 32,
+                  ),
+                  child: Text(
+                    "Rescan blockchain",
+                    style: STextStyles.desktopH3(context),
+                  ),
+                ),
+                const DesktopDialogCloseButton(),
+              ],
+            ),
+            Padding(
+              padding: const EdgeInsets.only(
+                top: 8,
+                left: 32,
+                right: 32,
+                bottom: 32,
+              ),
+              child: Column(
+                mainAxisSize: MainAxisSize.min,
+                children: [
+                  Text(
+                    "Warning! It may take a while. If you exit before completion, you will have to redo the process.",
+                    style: STextStyles.desktopTextSmall(context),
+                  ),
+                  const SizedBox(
+                    height: 43,
+                  ),
+                  Row(
+                    children: [
+                      Expanded(
+                        child: SecondaryButton(
+                          desktopMed: true,
+                          onPressed: Navigator.of(context).pop,
+                          label: "Cancel",
+                        ),
+                      ),
+                      const SizedBox(
+                        width: 16,
+                      ),
+                      Expanded(
+                        child: PrimaryButton(
+                          desktopMed: true,
+                          onPressed: () {
+                            Navigator.of(context).pop();
+                            onConfirm.call();
+                          },
+                          label: "Rescan",
+                        ),
+                      ),
+                    ],
+                  )
+                ],
+              ),
+            )
+          ],
         ),
-        rightButton: TextButton(
-          style: Theme.of(context)
-              .extension<StackColors>()!
-              .getPrimaryEnabledButtonColor(context),
-          child: Text(
-            "Rescan",
-            style: STextStyles.button(context),
+      );
+    } else {
+      return WillPopScope(
+        onWillPop: () async {
+          return true;
+        },
+        child: StackDialog(
+          title: "Rescan blockchain",
+          message:
+              "Warning! It may take a while. If you exit before completion, you will have to redo the process.",
+          leftButton: TextButton(
+            style: Theme.of(context)
+                .extension<StackColors>()!
+                .getSecondaryEnabledButtonColor(context),
+            child: Text(
+              "Cancel",
+              style: STextStyles.itemSubtitle12(context),
+            ),
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          rightButton: TextButton(
+            style: Theme.of(context)
+                .extension<StackColors>()!
+                .getPrimaryEnabledButtonColor(context),
+            child: Text(
+              "Rescan",
+              style: STextStyles.button(context),
+            ),
+            onPressed: () {
+              Navigator.of(context).pop();
+              onConfirm.call();
+            },
           ),
-          onPressed: () {
-            Navigator.of(context).pop();
-            onConfirm.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 8195491d8..fdb73fc88 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
@@ -28,6 +28,7 @@ import 'package:stackwallet/widgets/animated_text.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 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/expandable.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -61,7 +62,7 @@ class _WalletNetworkSettingsViewState
     extends ConsumerState<WalletNetworkSettingsView> {
   final double _padding = 16;
   final double _boxPadding = 12;
-  final double _iconSize = 28;
+  final double _iconSize = Util.isDesktop ? 40 : 28;
 
   late final EventBus eventBus;
 
@@ -75,6 +76,7 @@ class _WalletNetworkSettingsViewState
 
   late double _percent;
   late int _blocksRemaining;
+  bool _advancedIsExpanded = true;
 
   Future<void> _attemptRescan() async {
     if (!Platform.isLinux) await Wakelock.enable();
@@ -269,7 +271,7 @@ class _WalletNetworkSettingsViewState
     final bool isDesktop = Util.isDesktop;
 
     final progressLength = isDesktop
-        ? 450.0
+        ? 430.0
         : screenWidth - (_padding * 2) - (_boxPadding * 3) - _iconSize;
 
     final coin = ref
@@ -373,7 +375,7 @@ class _WalletNetworkSettingsViewState
                                       GestureDetector(
                                         onTap: () {
                                           Navigator.of(context).pop();
-                                          showDialog<dynamic>(
+                                          showDialog<void>(
                                             context: context,
                                             useSafeArea: false,
                                             barrierDismissible: true,
@@ -453,11 +455,17 @@ class _WalletNetworkSettingsViewState
               ),
             ],
           ),
-          const SizedBox(
-            height: 9,
+          SizedBox(
+            height: isDesktop ? 12 : 9,
           ),
           if (_currentSyncStatus == WalletSyncStatus.synced)
             RoundedWhiteContainer(
+              borderColor: isDesktop
+                  ? Theme.of(context).extension<StackColors>()!.background
+                  : null,
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
               child: Row(
                 children: [
                   Container(
@@ -527,6 +535,12 @@ class _WalletNetworkSettingsViewState
             ),
           if (_currentSyncStatus == WalletSyncStatus.syncing)
             RoundedWhiteContainer(
+              borderColor: isDesktop
+                  ? Theme.of(context).extension<StackColors>()!.background
+                  : null,
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
               child: Row(
                 children: [
                   Container(
@@ -618,6 +632,12 @@ class _WalletNetworkSettingsViewState
             ),
           if (_currentSyncStatus == WalletSyncStatus.unableToSync)
             RoundedWhiteContainer(
+              borderColor: isDesktop
+                  ? Theme.of(context).extension<StackColors>()!.background
+                  : null,
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
               child: Row(
                 children: [
                   Container(
@@ -708,8 +728,8 @@ class _WalletNetworkSettingsViewState
                 ),
               ),
             ),
-          const SizedBox(
-            height: 20,
+          SizedBox(
+            height: isDesktop ? 32 : 20,
           ),
           Row(
             mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -740,8 +760,8 @@ class _WalletNetworkSettingsViewState
               ),
             ],
           ),
-          const SizedBox(
-            height: 8,
+          SizedBox(
+            height: isDesktop ? 12 : 8,
           ),
           NodesList(
             coin: ref.watch(walletsChangeNotifierProvider
@@ -750,18 +770,125 @@ class _WalletNetworkSettingsViewState
           ),
           if (isDesktop)
             const SizedBox(
-              height: 20,
+              height: 32,
             ),
           if (isDesktop)
-            Row(
-              mainAxisAlignment: MainAxisAlignment.start,
-              children: [
-                Text(
-                  "Advanced",
-                  textAlign: TextAlign.left,
-                  style: STextStyles.desktopTextExtraExtraSmall(context),
+            Padding(
+              padding: const EdgeInsets.only(
+                bottom: 12,
+              ),
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.start,
+                children: [
+                  Text(
+                    "Advanced",
+                    textAlign: TextAlign.left,
+                    style: STextStyles.desktopTextExtraExtraSmall(context),
+                  ),
+                ],
+              ),
+            ),
+          if (isDesktop)
+            RoundedWhiteContainer(
+              borderColor: isDesktop
+                  ? Theme.of(context).extension<StackColors>()!.background
+                  : null,
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
+              child: Expandable(
+                onExpandChanged: (state) {
+                  setState(() {
+                    _advancedIsExpanded = state == ExpandableState.expanded;
+                  });
+                },
+                header: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Row(
+                      children: [
+                        Container(
+                          width: _iconSize,
+                          height: _iconSize,
+                          decoration: BoxDecoration(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textFieldDefaultBG,
+                            borderRadius: BorderRadius.circular(_iconSize),
+                          ),
+                          child: Center(
+                            child: SvgPicture.asset(
+                              Assets.svg.networkWired,
+                              width: 24,
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark,
+                            ),
+                          ),
+                        ),
+                        const SizedBox(
+                          width: 10,
+                        ),
+                        Column(
+                          mainAxisSize: MainAxisSize.min,
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            Text(
+                              "Advanced",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                      context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              ),
+                            ),
+                            Text(
+                              "Rescan blockchain",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                          ],
+                        )
+                      ],
+                    ),
+                    SvgPicture.asset(
+                      _advancedIsExpanded
+                          ? Assets.svg.chevronDown
+                          : Assets.svg.chevronUp,
+                      width: 12,
+                      height: 6,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textSubtitle1,
+                    ),
+                  ],
                 ),
-              ],
+                body: Row(
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.only(
+                        left: 50,
+                        top: 16,
+                        bottom: 6,
+                      ),
+                      child: BlueTextButton(
+                        text: "Rescan",
+                        onTap: () async {
+                          await showDialog<dynamic>(
+                            context: context,
+                            builder: (context) {
+                              return ConfirmFullRescanDialog(
+                                onConfirm: _attemptRescan,
+                              );
+                            },
+                          );
+                        },
+                      ),
+                    ),
+                  ],
+                ),
+              ),
             ),
         ],
       ),
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 78535c19b..386ea1cd8 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -101,6 +101,7 @@ class _SVG {
   String get downloadFolder => "assets/svg/folder-down.svg";
   String get lock => "assets/svg/lock-keyhole.svg";
   String get network => "assets/svg/network-wired.svg";
+  String get networkWired => "assets/svg/network-wired-2.svg";
   String get addressBook => "assets/svg/address-book.svg";
   String get addressBook2 => "assets/svg/address-book2.svg";
   String get arrowRotate3 => "assets/svg/rotate-exclamation.svg";
diff --git a/lib/widgets/conditional_parent.dart b/lib/widgets/conditional_parent.dart
index 6db50c6e8..757c8f992 100644
--- a/lib/widgets/conditional_parent.dart
+++ b/lib/widgets/conditional_parent.dart
@@ -4,13 +4,13 @@ class ConditionalParent extends StatelessWidget {
   const ConditionalParent({
     Key? key,
     required this.condition,
-    required this.child,
     required this.builder,
+    required this.child,
   }) : super(key: key);
 
   final bool condition;
-  final Widget child;
   final Widget Function(Widget) builder;
+  final Widget child;
 
   @override
   Widget build(BuildContext context) {
diff --git a/pubspec.yaml b/pubspec.yaml
index 29d25cb84..b84135f4a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -237,6 +237,7 @@ flutter:
     - assets/svg/rotate-exclamation.svg
     - assets/svg/folder-down.svg
     - assets/svg/network-wired.svg
+    - assets/svg/network-wired-2.svg
     - assets/svg/address-book.svg
     - assets/svg/address-book2.svg
     - assets/svg/arrow-right.svg

From e0a8f32d69e04c5a6f66670f1f9f1ac0358e746d Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 15:03:14 -0600
Subject: [PATCH 107/426]  desktop wallet network settings expanding node cards

---
 .../sub_widgets/network_info_button.dart      |   2 +-
 .../custom_buttons/blue_text_button.dart      |  65 ++--
 lib/widgets/node_card.dart                    | 360 ++++++++++++++----
 3 files changed, 329 insertions(+), 98 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
index 37cd414c7..5dc8c4723 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
@@ -157,7 +157,7 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
           showDialog<void>(
             context: context,
             builder: (context) => DesktopDialog(
-              maxHeight: 600,
+              maxHeight: MediaQuery.of(context).size.height - 64,
               maxWidth: 580,
               child: Column(
                 mainAxisSize: MainAxisSize.min,
diff --git a/lib/widgets/custom_buttons/blue_text_button.dart b/lib/widgets/custom_buttons/blue_text_button.dart
index 18757ab93..aa7f75b1f 100644
--- a/lib/widgets/custom_buttons/blue_text_button.dart
+++ b/lib/widgets/custom_buttons/blue_text_button.dart
@@ -5,11 +5,16 @@ import 'package:stackwallet/providers/ui/color_theme_provider.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 
 class BlueTextButton extends ConsumerStatefulWidget {
-  const BlueTextButton({Key? key, required this.text, this.onTap})
-      : super(key: key);
+  const BlueTextButton({
+    Key? key,
+    required this.text,
+    this.onTap,
+    this.enabled = true,
+  }) : super(key: key);
 
   final String text;
   final VoidCallback? onTap;
+  final bool enabled;
 
   @override
   ConsumerState<BlueTextButton> createState() => _BlueTextButtonState();
@@ -17,38 +22,42 @@ class BlueTextButton extends ConsumerStatefulWidget {
 
 class _BlueTextButtonState extends ConsumerState<BlueTextButton>
     with SingleTickerProviderStateMixin {
-  late AnimationController controller;
-  late Animation<dynamic> animation;
+  AnimationController? controller;
+  Animation<dynamic>? animation;
   late Color color;
 
   @override
   void initState() {
-    color = ref.read(colorThemeProvider.state).state.buttonTextBorderless;
-    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),
-    ).animate(controller);
+    if (widget.enabled) {
+      color = ref.read(colorThemeProvider.state).state.buttonTextBorderless;
+      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),
+      ).animate(controller!);
 
-    animation.addListener(() {
-      setState(() {
-        color = animation.value as Color;
+      animation!.addListener(() {
+        setState(() {
+          color = animation!.value as Color;
+        });
       });
-    });
+    } else {
+      color = ref.read(colorThemeProvider.state).state.textSubtitle1;
+    }
 
     super.initState();
   }
 
   @override
   void dispose() {
-    controller.dispose();
+    controller?.dispose();
     super.dispose();
   }
 
@@ -59,11 +68,13 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton>
       text: TextSpan(
         text: widget.text,
         style: STextStyles.link2(context).copyWith(color: color),
-        recognizer: TapGestureRecognizer()
-          ..onTap = () {
-            widget.onTap?.call();
-            controller.forward().then((value) => controller.reverse());
-          },
+        recognizer: widget.enabled
+            ? (TapGestureRecognizer()
+              ..onTap = () {
+                widget.onTap?.call();
+                controller?.forward().then((value) => controller?.reverse());
+              })
+            : null,
       ),
     );
   }
diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart
index 1f0287013..bf9d2746e 100644
--- a/lib/widgets/node_card.dart
+++ b/lib/widgets/node_card.dart
@@ -1,15 +1,31 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/electrumx_rpc/electrumx.dart';
+import 'package:stackwallet/models/node_model.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart';
 import 'package:stackwallet/providers/providers.dart';
 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/flush_bar_type.dart';
+import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
+import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/utilities/test_epic_box_connection.dart';
+import 'package:stackwallet/utilities/test_monero_node_connection.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/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/expandable.dart';
 import 'package:stackwallet/widgets/node_options_sheet.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:tuple/tuple.dart';
 
 class NodeCard extends ConsumerStatefulWidget {
   const NodeCard({
@@ -30,6 +46,125 @@ class NodeCard extends ConsumerStatefulWidget {
 class _NodeCardState extends ConsumerState<NodeCard> {
   String _status = "Disconnected";
   late final String nodeId;
+  bool _advancedIsExpanded = true;
+
+  Future<void> _notifyWalletsOfUpdatedNode(WidgetRef ref) async {
+    final managers = ref
+        .read(walletsChangeNotifierProvider)
+        .managers
+        .where((e) => e.coin == widget.coin);
+    final prefs = ref.read(prefsChangeNotifierProvider);
+
+    switch (prefs.syncType) {
+      case SyncingType.currentWalletOnly:
+        for (final manager in managers) {
+          if (manager.isActiveWallet) {
+            manager.updateNode(true);
+          } else {
+            manager.updateNode(false);
+          }
+        }
+        break;
+      case SyncingType.selectedWalletsAtStartup:
+        final List<String> walletIdsToSync = prefs.walletIdsSyncOnStartup;
+        for (final manager in managers) {
+          if (walletIdsToSync.contains(manager.walletId)) {
+            manager.updateNode(true);
+          } else {
+            manager.updateNode(false);
+          }
+        }
+        break;
+      case SyncingType.allWalletsOnStartup:
+        for (final manager in managers) {
+          manager.updateNode(true);
+        }
+        break;
+    }
+  }
+
+  Future<bool> _testConnection(
+    NodeModel node,
+    BuildContext context,
+    WidgetRef ref,
+  ) async {
+    bool testPassed = false;
+
+    switch (widget.coin) {
+      case Coin.epicCash:
+        try {
+          final String uriString = "${node.host}:${node.port}/v1/version";
+
+          testPassed = await testEpicBoxNodeConnection(Uri.parse(uriString));
+        } catch (e, s) {
+          Logging.instance.log("$e\n$s", level: LogLevel.Warning);
+        }
+        break;
+
+      case Coin.monero:
+      case Coin.wownero:
+        try {
+          final uri = Uri.parse(node.host);
+          if (uri.scheme.startsWith("http")) {
+            final String path = uri.path.isEmpty ? "/json_rpc" : uri.path;
+
+            String uriString = "${uri.scheme}://${uri.host}:${node.port}$path";
+
+            testPassed = await testMoneroNodeConnection(Uri.parse(uriString));
+          }
+        } catch (e, s) {
+          Logging.instance.log("$e\n$s", level: LogLevel.Warning);
+        }
+
+        break;
+
+      case Coin.bitcoin:
+      case Coin.litecoin:
+      case Coin.dogecoin:
+      case Coin.firo:
+      case Coin.bitcoinTestNet:
+      case Coin.firoTestNet:
+      case Coin.dogecoinTestNet:
+      case Coin.bitcoincash:
+      case Coin.litecoinTestNet:
+      case Coin.namecoin:
+      case Coin.bitcoincashTestnet:
+        final client = ElectrumX(
+          host: node.host,
+          port: node.port,
+          useSSL: node.useSSL,
+          failovers: [],
+          prefs: ref.read(prefsChangeNotifierProvider),
+        );
+
+        try {
+          testPassed = await client.ping();
+        } catch (_) {
+          testPassed = false;
+        }
+
+        break;
+    }
+
+    if (testPassed) {
+      // showFloatingFlushBar(
+      //   type: FlushBarType.success,
+      //   message: "Server ping success",
+      //   context: context,
+      // );
+    } else {
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          iconAsset: Assets.svg.circleAlert,
+          message: "Could not connect to node",
+          context: context,
+        ),
+      );
+    }
+
+    return testPassed;
+  }
 
   @override
   void initState() {
@@ -50,91 +185,176 @@ class _NodeCardState extends ConsumerState<NodeCard> {
       _status = "Disconnected";
     }
 
+    final isDesktop = Util.isDesktop;
+
     return RoundedWhiteContainer(
       padding: const EdgeInsets.all(0),
-      child: RawMaterialButton(
-        shape: RoundedRectangleBorder(
-          borderRadius: BorderRadius.circular(
-            Constants.size.circularBorderRadius,
-          ),
-        ),
-        onPressed: () {
-          showModalBottomSheet<dynamic>(
-            backgroundColor: Colors.transparent,
-            context: context,
-            builder: (_) => NodeOptionsSheet(
-              nodeId: nodeId,
-              coin: widget.coin,
-              popBackToRoute: widget.popBackToRoute,
+      borderColor: isDesktop
+          ? Theme.of(context).extension<StackColors>()!.background
+          : null,
+      child: ConditionalParent(
+        condition: !isDesktop,
+        builder: (child) {
+          return RawMaterialButton(
+            shape: RoundedRectangleBorder(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
             ),
+            onPressed: () {
+              showModalBottomSheet<void>(
+                backgroundColor: Colors.transparent,
+                context: context,
+                builder: (_) => NodeOptionsSheet(
+                  nodeId: nodeId,
+                  coin: widget.coin,
+                  popBackToRoute: widget.popBackToRoute,
+                ),
+              );
+            },
+            child: child,
           );
         },
-        child: Padding(
-          padding: const EdgeInsets.all(12),
-          child: Row(
-            children: [
-              Container(
-                width: 24,
-                height: 24,
-                decoration: BoxDecoration(
-                  color: _node.name == DefaultNodes.defaultName
-                      ? Theme.of(context)
-                          .extension<StackColors>()!
-                          .buttonBackSecondary
-                      : Theme.of(context)
-                          .extension<StackColors>()!
-                          .infoItemIcons
-                          .withOpacity(0.2),
-                  borderRadius: BorderRadius.circular(100),
+        child: ConditionalParent(
+          condition: isDesktop,
+          builder: (child) {
+            return Expandable(
+              onExpandChanged: (state) {
+                setState(() {
+                  _advancedIsExpanded = state == ExpandableState.expanded;
+                });
+              },
+              header: child,
+              body: Padding(
+                padding: const EdgeInsets.only(
+                  bottom: 24,
                 ),
-                child: Center(
-                  child: SvgPicture.asset(
-                    Assets.svg.node,
-                    height: 11,
-                    width: 14,
+                child: Row(
+                  children: [
+                    const SizedBox(
+                      width: 66,
+                    ),
+                    BlueTextButton(
+                      text: "Connect",
+                      enabled: _status == "Disconnected",
+                      onTap: () async {
+                        final canConnect =
+                            await _testConnection(_node, context, ref);
+                        if (!canConnect) {
+                          return;
+                        }
+
+                        await ref
+                            .read(nodeServiceChangeNotifierProvider)
+                            .setPrimaryNodeFor(
+                              coin: widget.coin,
+                              node: _node,
+                              shouldNotifyListeners: true,
+                            );
+
+                        await _notifyWalletsOfUpdatedNode(ref);
+                      },
+                    ),
+                    const SizedBox(
+                      width: 48,
+                    ),
+                    BlueTextButton(
+                      text: "Details",
+                      onTap: () {
+                        Navigator.of(context).pushNamed(
+                          NodeDetailsView.routeName,
+                          arguments: Tuple3(
+                            widget.coin,
+                            widget.nodeId,
+                            widget.popBackToRoute,
+                          ),
+                        );
+                      },
+                    ),
+                  ],
+                ),
+              ),
+            );
+          },
+          child: Padding(
+            padding: EdgeInsets.all(isDesktop ? 16 : 12),
+            child: Row(
+              children: [
+                Container(
+                  width: isDesktop ? 40 : 24,
+                  height: isDesktop ? 40 : 24,
+                  decoration: BoxDecoration(
                     color: _node.name == DefaultNodes.defaultName
                         ? Theme.of(context)
                             .extension<StackColors>()!
-                            .accentColorDark
+                            .buttonBackSecondary
                         : Theme.of(context)
                             .extension<StackColors>()!
-                            .infoItemIcons,
+                            .infoItemIcons
+                            .withOpacity(0.2),
+                    borderRadius: BorderRadius.circular(100),
+                  ),
+                  child: Center(
+                    child: SvgPicture.asset(
+                      Assets.svg.node,
+                      height: isDesktop ? 18 : 11,
+                      width: isDesktop ? 20 : 14,
+                      color: _node.name == DefaultNodes.defaultName
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorDark
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .infoItemIcons,
+                    ),
                   ),
                 ),
-              ),
-              const SizedBox(
-                width: 12,
-              ),
-              Column(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  Text(
-                    _node.name,
-                    style: STextStyles.titleBold12(context),
+                const SizedBox(
+                  width: 12,
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Text(
+                      _node.name,
+                      style: STextStyles.titleBold12(context),
+                    ),
+                    const SizedBox(
+                      height: 2,
+                    ),
+                    Text(
+                      _status,
+                      style: STextStyles.label(context),
+                    ),
+                  ],
+                ),
+                const Spacer(),
+                if (!isDesktop)
+                  SvgPicture.asset(
+                    Assets.svg.network,
+                    color: _status == "Connected"
+                        ? Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorGreen
+                        : Theme.of(context)
+                            .extension<StackColors>()!
+                            .buttonBackSecondary,
+                    width: 20,
+                    height: 20,
                   ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  Text(
-                    _status,
-                    style: STextStyles.label(context),
-                  ),
-                ],
-              ),
-              const Spacer(),
-              SvgPicture.asset(
-                Assets.svg.network,
-                color: _status == "Connected"
-                    ? Theme.of(context)
+                if (isDesktop)
+                  SvgPicture.asset(
+                    _advancedIsExpanded
+                        ? Assets.svg.chevronDown
+                        : Assets.svg.chevronUp,
+                    width: 12,
+                    height: 6,
+                    color: Theme.of(context)
                         .extension<StackColors>()!
-                        .accentColorGreen
-                    : Theme.of(context)
-                        .extension<StackColors>()!
-                        .buttonBackSecondary,
-                width: 20,
-                height: 20,
-              ),
-            ],
+                        .textSubtitle1,
+                  ),
+              ],
+            ),
           ),
         ),
       ),

From d8eb43f4e8656d56a3cc7c48eca03a6ef44b7330 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 16:13:14 -0600
Subject: [PATCH 108/426] tx details mobile fix

---
 .../transaction_details_view.dart             | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
index d1e415b26..6f23f2e01 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -25,6 +25,7 @@ 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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -260,11 +261,19 @@ class _TransactionDetailsViewState
                         bottom: 32,
                       )
                     : const EdgeInsets.all(0),
-                child: RoundedWhiteContainer(
-                  borderColor: isDesktop
-                      ? Theme.of(context).extension<StackColors>()!.background
-                      : null,
-                  padding: const EdgeInsets.all(0),
+                child: ConditionalParent(
+                  condition: isDesktop,
+                  builder: (child) {
+                    return RoundedWhiteContainer(
+                      borderColor: isDesktop
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .background
+                          : null,
+                      padding: const EdgeInsets.all(0),
+                      child: child,
+                    );
+                  },
                   child: SingleChildScrollView(
                     primary: isDesktop ? false : null,
                     child: Padding(

From 0c4cb961d6241b2318000ec0cbbccb4cbd3bccc1 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 17:18:22 -0600
Subject: [PATCH 109/426] WIP: currency popup

---
 .../currency_settings/currency_dialog.dart    | 371 ++++++++++++++++++
 .../currency_settings/currency_settings.dart  | 117 ++++++
 2 files changed, 488 insertions(+)
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
 create mode 100644 lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart

diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
new file mode 100644
index 000000000..aabc81cd1
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
@@ -0,0 +1,371 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/providers/global/base_currencies_provider.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/utilities/assets.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/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+import 'package:stackwallet/widgets/textfield_icon_button.dart';
+
+class CurrencyDialog extends ConsumerStatefulWidget {
+  const CurrencyDialog({Key? key}) : super(key: key);
+
+  @override
+  ConsumerState<CurrencyDialog> createState() => _CurrencyDialog();
+}
+
+class _CurrencyDialog extends ConsumerState<CurrencyDialog> {
+  late String current;
+  late List<String> currenciesWithoutSelected;
+
+  late final TextEditingController searchCurrencyController;
+
+  late final FocusNode searchCurrencyFocusNode;
+
+  void onTap(int index) {
+    if (currenciesWithoutSelected[index] == current || current.isEmpty) {
+      // ignore if already selected currency
+      return;
+    }
+    current = currenciesWithoutSelected[index];
+    currenciesWithoutSelected.remove(current);
+    currenciesWithoutSelected.insert(0, current);
+    ref.read(prefsChangeNotifierProvider).currency = current;
+  }
+
+  BorderRadius? _borderRadius(int index) {
+    if (index == 0 && currenciesWithoutSelected.length == 1) {
+      return BorderRadius.circular(
+        Constants.size.circularBorderRadius,
+      );
+    } else if (index == 0) {
+      return BorderRadius.vertical(
+        top: Radius.circular(
+          Constants.size.circularBorderRadius,
+        ),
+      );
+    } else if (index == currenciesWithoutSelected.length - 1) {
+      return BorderRadius.vertical(
+        bottom: Radius.circular(
+          Constants.size.circularBorderRadius,
+        ),
+      );
+    }
+    return null;
+  }
+
+  String filter = "";
+
+  List<String> _filtered() {
+    final currencyMap = ref.read(baseCurrenciesProvider).map;
+    return currenciesWithoutSelected.where((element) {
+      return element.toLowerCase().contains(filter.toLowerCase()) ||
+          (currencyMap[element]?.toLowerCase().contains(filter.toLowerCase()) ??
+              false);
+    }).toList();
+  }
+
+  @override
+  void initState() {
+    searchCurrencyController = TextEditingController();
+
+    searchCurrencyFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    searchCurrencyController.dispose();
+
+    searchCurrencyFocusNode.dispose();
+
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    current = ref
+        .watch(prefsChangeNotifierProvider.select((value) => value.language));
+
+    currenciesWithoutSelected = ref
+        .watch(baseCurrenciesProvider.select((value) => value.map))
+        .keys
+        .toList();
+    if (current.isNotEmpty) {
+      currenciesWithoutSelected.remove(current);
+      currenciesWithoutSelected.insert(0, current);
+    }
+    currenciesWithoutSelected = _filtered();
+
+    return DesktopDialog(
+      maxHeight: 800,
+      maxWidth: 600,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.all(32),
+                child: Text(
+                  "Select currency",
+                  style: STextStyles.desktopH3(context),
+                  textAlign: TextAlign.center,
+                ),
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+          Expanded(
+            flex: 24,
+            child: NestedScrollView(
+              floatHeaderSlivers: true,
+              headerSliverBuilder: (context, innerBoxIsScrolled) {
+                return [
+                  SliverOverlapAbsorber(
+                    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+                        context),
+                    sliver: SliverToBoxAdapter(
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(
+                            vertical: 16, horizontal: 32),
+                        child: Column(
+                          children: [
+                            Padding(
+                              padding: const EdgeInsets.only(bottom: 16),
+                              child: ClipRRect(
+                                borderRadius: BorderRadius.circular(
+                                  Constants.size.circularBorderRadius,
+                                ),
+                                child: TextField(
+                                  autocorrect: Util.isDesktop ? false : true,
+                                  enableSuggestions:
+                                      Util.isDesktop ? false : true,
+                                  controller: searchCurrencyController,
+                                  focusNode: searchCurrencyFocusNode,
+                                  onChanged: (newString) {
+                                    setState(() => filter = newString);
+                                  },
+                                  style: STextStyles.field(context),
+                                  decoration: standardInputDecoration(
+                                    "Search",
+                                    searchCurrencyFocusNode,
+                                    context,
+                                  ).copyWith(
+                                    prefixIcon: Padding(
+                                      padding: const EdgeInsets.symmetric(
+                                        horizontal: 10,
+                                        vertical: 16,
+                                      ),
+                                      child: SvgPicture.asset(
+                                        Assets.svg.search,
+                                        width: 16,
+                                        height: 16,
+                                      ),
+                                    ),
+                                    suffixIcon: searchCurrencyController
+                                            .text.isNotEmpty
+                                        ? Padding(
+                                            padding:
+                                                const EdgeInsets.only(right: 0),
+                                            child: UnconstrainedBox(
+                                              child: Row(
+                                                children: [
+                                                  TextFieldIconButton(
+                                                    child: const XIcon(),
+                                                    onTap: () async {
+                                                      setState(() {
+                                                        searchCurrencyController
+                                                            .text = "";
+                                                        filter = "";
+                                                      });
+                                                    },
+                                                  ),
+                                                ],
+                                              ),
+                                            ),
+                                          )
+                                        : null,
+                                  ),
+                                ),
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                ];
+              },
+              body: Builder(
+                builder: (context) {
+                  return CustomScrollView(
+                    slivers: [
+                      SliverOverlapInjector(
+                        handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+                          context,
+                        ),
+                      ),
+                      SliverList(
+                        delegate: SliverChildBuilderDelegate(
+                          (context, index) {
+                            return Container(
+                              decoration: BoxDecoration(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .popupBG,
+                                borderRadius: _borderRadius(index),
+                              ),
+                              child: Padding(
+                                padding: const EdgeInsets.all(4),
+                                key: Key(
+                                    "desktopSettingsCurrencySelect_${currenciesWithoutSelected[index]}"),
+                                child: Padding(
+                                  padding: const EdgeInsets.symmetric(
+                                      horizontal: 32),
+                                  child: RoundedContainer(
+                                    padding: const EdgeInsets.all(0),
+                                    color: currenciesWithoutSelected[index] ==
+                                            current
+                                        ? Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .currencyListItemBG
+                                        : Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .popupBG,
+                                    child: RawMaterialButton(
+                                      onPressed: () async {
+                                        onTap(index);
+                                      },
+                                      shape: RoundedRectangleBorder(
+                                        borderRadius: BorderRadius.circular(
+                                          Constants.size.circularBorderRadius,
+                                        ),
+                                      ),
+                                      child: Padding(
+                                        padding: const EdgeInsets.all(12.0),
+                                        child: Row(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            SizedBox(
+                                              width: 20,
+                                              height: 20,
+                                              child: Radio(
+                                                activeColor: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .radioButtonIconEnabled,
+                                                materialTapTargetSize:
+                                                    MaterialTapTargetSize
+                                                        .shrinkWrap,
+                                                value: true,
+                                                groupValue:
+                                                    currenciesWithoutSelected[
+                                                            index] ==
+                                                        current,
+                                                onChanged: (_) {
+                                                  onTap(index);
+                                                },
+                                              ),
+                                            ),
+                                            const SizedBox(
+                                              width: 12,
+                                            ),
+                                            Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.start,
+                                              children: [
+                                                Text(
+                                                  currenciesWithoutSelected[
+                                                      index],
+                                                  key: (currenciesWithoutSelected[
+                                                              index] ==
+                                                          current)
+                                                      ? const Key(
+                                                          "desktopSettingsSelectedCurrencyText")
+                                                      : null,
+                                                  style:
+                                                      STextStyles.largeMedium14(
+                                                          context),
+                                                ),
+                                                const SizedBox(
+                                                  height: 2,
+                                                ),
+                                                Text(
+                                                  ref.watch(baseCurrenciesProvider
+                                                              .select((value) =>
+                                                                  value.map))[
+                                                          currenciesWithoutSelected[
+                                                              index]] ??
+                                                      "",
+                                                  key: (currenciesWithoutSelected[
+                                                              index] ==
+                                                          current)
+                                                      ? const Key(
+                                                          "desktopSelectedCurrencyTextDescription")
+                                                      : null,
+                                                  style:
+                                                      STextStyles.itemSubtitle(
+                                                          context),
+                                                ),
+                                              ],
+                                            ),
+                                          ],
+                                        ),
+                                      ),
+                                    ),
+                                  ),
+                                ),
+                              ),
+                            );
+                          },
+                          childCount: currenciesWithoutSelected.length,
+                        ),
+                      ),
+                    ],
+                  );
+                },
+              ),
+            ),
+          ),
+          const Spacer(),
+          Padding(
+            padding: const EdgeInsets.all(32),
+            child: Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    onPressed: () {
+                      Navigator.of(context).pop();
+                    },
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Save Changes",
+                    onPressed: () {},
+                  ),
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
new file mode 100644
index 000000000..b8ce76d25
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -0,0 +1,117 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+import 'currency_dialog.dart';
+
+class CurrencySettings extends ConsumerStatefulWidget {
+  const CurrencySettings({Key? key}) : super(key: key);
+
+  static const String routeName = "/settingsMenuCurrency";
+
+  @override
+  ConsumerState<CurrencySettings> createState() => _CurrencySettings();
+}
+
+class _CurrencySettings extends ConsumerState<CurrencySettings> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return Column(
+      children: [
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.circleDollarSign,
+                  width: 48,
+                  height: 48,
+                ),
+                Center(
+                  child: Padding(
+                    padding: const EdgeInsets.all(10),
+                    child: RichText(
+                      textAlign: TextAlign.start,
+                      text: TextSpan(
+                        children: [
+                          TextSpan(
+                            text: "Currency",
+                            style: STextStyles.desktopTextSmall(context),
+                          ),
+                          TextSpan(
+                            text:
+                                "\n\nProtect your Stack Wallet with a strong password. Stack Wallet does not store "
+                                "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: const [
+                    Padding(
+                      padding: EdgeInsets.all(
+                        10,
+                      ),
+                      child: NewPasswordButton(),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class NewPasswordButton extends ConsumerWidget {
+  const NewPasswordButton({
+    Key? key,
+  }) : super(key: key);
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    Future<void> chooseCurrency() async {
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: true,
+        builder: (context) {
+          return CurrencyDialog();
+        },
+      );
+    }
+
+    return SizedBox(
+      width: 200,
+      height: 48,
+      child: TextButton(
+        style: Theme.of(context)
+            .extension<StackColors>()!
+            .getPrimaryEnabledButtonColor(context),
+        onPressed: () {
+          chooseCurrency();
+        },
+        child: Text(
+          "Change currency",
+          style: STextStyles.button(context),
+        ),
+      ),
+    );
+  }
+}

From 939ccc69116ad71de4a97d2d69f28d353d957482 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 17:19:12 -0600
Subject: [PATCH 110/426] created currency directory

---
 lib/pages_desktop_specific/home/desktop_settings_view.dart | 2 +-
 lib/route_generator.dart                                   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index 9b3f897a9..63e1ee613 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index c5b764995..d5a38c0fd 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -94,7 +94,7 @@ import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_vie
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';

From c1d81b52a5946f5acca3179e393745a757c81b25 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 17:20:21 -0600
Subject: [PATCH 111/426] added flex and removed commented code

---
 .../backup_and_restore/create_auto_backup.dart     | 14 --------------
 .../language_settings/language_dialog.dart         |  1 +
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 16bda2ff7..f3e502bcb 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -40,20 +40,6 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
     "Every 30 minutes",
   ];
 
-  // List<DropdownMenuItem<String>> get dropdownItems {
-  //   List<DropdownMenuItem<String>> menuItems = [
-  //     const DropdownMenuItem(
-  //       value: "Every 10 minutes",
-  //       child: Text("Every 10 minutes"),
-  //     ),
-  //     const DropdownMenuItem(
-  //       value: "Every 20 minutes",
-  //       child: Text("Every 20 minutes"),
-  //     ),
-  //   ];
-  //   return menuItems;
-  // }
-
   @override
   void initState() {
     fileLocationController = TextEditingController();
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
index f68196710..d07c9729f 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
@@ -125,6 +125,7 @@ class _LanguageDialog extends ConsumerState<LanguageDialog> {
             ],
           ),
           Expanded(
+            flex: 24,
             child: NestedScrollView(
               floatHeaderSlivers: true,
               headerSliverBuilder: (context, innerBoxIsScrolled) {

From 75d9ca6912654c2634b5c5366bfcd503db1177bd Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 16:24:55 -0600
Subject: [PATCH 112/426] desktop network icon size fix

---
 .../wallet_network_settings_view.dart                         | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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 fdb73fc88..322d67d74 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
@@ -481,8 +481,8 @@ class _WalletNetworkSettingsViewState
                     child: Center(
                       child: SvgPicture.asset(
                         Assets.svg.radio,
-                        height: 14,
-                        width: 14,
+                        height: isDesktop ? 19 : 14,
+                        width: isDesktop ? 19 : 14,
                         color: Theme.of(context)
                             .extension<StackColors>()!
                             .accentColorGreen,

From 9186be7fb644cf9516388263df503fb12f1d544c Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 17:29:26 -0600
Subject: [PATCH 113/426] WIP: desktop dialog transitions

---
 .../wallet_network_settings_view.dart         |  21 ++-
 .../sub_widgets/network_info_button.dart      | 126 +++++++++++++-----
 .../unlock_wallet_keys_desktop.dart           |  59 +++++---
 .../sub_widgets/wallet_keys_button.dart       |  24 +++-
 lib/route_generator.dart                      |  89 +++++++++++--
 5 files changed, 248 insertions(+), 71 deletions(-)

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 322d67d74..accf244eb 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
@@ -10,6 +10,7 @@ import 'package:stackwallet/pages/settings_views/sub_widgets/nodes_list.dart';
 import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart';
 import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
 import 'package:stackwallet/services/coins/monero/monero_wallet.dart';
 import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
@@ -875,14 +876,22 @@ class _WalletNetworkSettingsViewState
                       child: BlueTextButton(
                         text: "Rescan",
                         onTap: () async {
-                          await showDialog<dynamic>(
-                            context: context,
-                            builder: (context) {
-                              return ConfirmFullRescanDialog(
+                          await Navigator.of(context).push(
+                             FadePageRoute<void>(
+                              ConfirmFullRescanDialog(
                                 onConfirm: _attemptRescan,
-                              );
-                            },
+                              ),
+                             const RouteSettings(),
+                            ),
                           );
+                          // await showDialog<dynamic>(
+                          //   context: context,
+                          //   builder: (context) {
+                          //     return ConfirmFullRescanDialog(
+                          //       onConfirm: _attemptRescan,
+                          //     );
+                          //   },
+                          // );
                         },
                       ),
                     ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
index 5dc8c4723..c001f9bf3 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
@@ -6,6 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_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';
@@ -154,44 +155,103 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
     return GestureDetector(
       onTap: () {
         if (Util.isDesktop) {
+          // showDialog<void>(
+          //   context: context,
+          //   builder: (context) => DesktopDialog(
+          //     maxHeight: MediaQuery.of(context).size.height - 64,
+          //     maxWidth: 580,
+          //     child: Column(
+          //       mainAxisSize: MainAxisSize.min,
+          //       children: [
+          //         Padding(
+          //           padding: const EdgeInsets.only(
+          //             left: 32,
+          //           ),
+          //           child: Row(
+          //             mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          //             children: [
+          //               Text(
+          //                 "Network",
+          //                 style: STextStyles.desktopH3(context),
+          //               ),
+          //               const DesktopDialogCloseButton(),
+          //             ],
+          //           ),
+          //         ),
+          //         Padding(
+          //           padding: const EdgeInsets.only(
+          //             top: 16,
+          //             left: 32,
+          //             right: 32,
+          //             bottom: 32,
+          //           ),
+          //           child: WalletNetworkSettingsView(
+          //             walletId: walletId,
+          //             initialSyncStatus: _currentSyncStatus,
+          //             initialNodeStatus: _currentNodeStatus,
+          //           ),
+          //         ),
+          //       ],
+          //     ),
+          //   ),
+          // );
+
           showDialog<void>(
             context: context,
-            builder: (context) => DesktopDialog(
-              maxHeight: MediaQuery.of(context).size.height - 64,
-              maxWidth: 580,
-              child: Column(
-                mainAxisSize: MainAxisSize.min,
-                children: [
-                  Padding(
-                    padding: const EdgeInsets.only(
-                      left: 32,
+            builder: (context) => Navigator(
+              initialRoute: WalletNetworkSettingsView.routeName,
+              onGenerateRoute: RouteGenerator.generateRoute,
+              onGenerateInitialRoutes: (_, __) {
+                return [
+                  FadePageRoute(
+                    DesktopDialog(
+                      maxHeight: MediaQuery.of(context).size.height - 64,
+                      maxWidth: 580,
+                      child: Column(
+                        mainAxisSize: MainAxisSize.min,
+                        children: [
+                          Padding(
+                            padding: const EdgeInsets.only(
+                              left: 32,
+                            ),
+                            child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              children: [
+                                Text(
+                                  "Network",
+                                  style: STextStyles.desktopH3(context),
+                                ),
+                                DesktopDialogCloseButton(
+                                  onPressedOverride: Navigator.of(
+                                    context,
+                                    rootNavigator: true,
+                                  ).pop,
+                                ),
+                              ],
+                            ),
+                          ),
+                          Padding(
+                            padding: const EdgeInsets.only(
+                              top: 16,
+                              left: 32,
+                              right: 32,
+                              bottom: 32,
+                            ),
+                            child: WalletNetworkSettingsView(
+                              walletId: walletId,
+                              initialSyncStatus: _currentSyncStatus,
+                              initialNodeStatus: _currentNodeStatus,
+                            ),
+                          ),
+                        ],
+                      ),
                     ),
-                    child: Row(
-                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                      children: [
-                        Text(
-                          "Network",
-                          style: STextStyles.desktopH3(context),
-                        ),
-                        const DesktopDialogCloseButton(),
-                      ],
+                    const RouteSettings(
+                      name: WalletNetworkSettingsView.routeName,
                     ),
                   ),
-                  Padding(
-                    padding: const EdgeInsets.only(
-                      top: 16,
-                      left: 32,
-                      right: 32,
-                      bottom: 32,
-                    ),
-                    child: WalletNetworkSettingsView(
-                      walletId: walletId,
-                      initialSyncStatus: _currentSyncStatus,
-                      initialNodeStatus: _currentNodeStatus,
-                    ),
-                  ),
-                ],
-              ),
+                ];
+              },
             ),
           );
         } else {
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
index 37f047eed..e65820737 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
@@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
 import 'package:stackwallet/providers/providers.dart';
-import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -22,6 +21,8 @@ class UnlockWalletKeysDesktop extends ConsumerStatefulWidget {
 
   final String walletId;
 
+  static const String routeName = "/desktopUnlockWalletKeys";
+
   @override
   ConsumerState<UnlockWalletKeysDesktop> createState() =>
       _UnlockWalletKeysDesktopState();
@@ -59,8 +60,13 @@ class _UnlockWalletKeysDesktopState
         children: [
           Row(
             mainAxisAlignment: MainAxisAlignment.end,
-            children: const [
-              DesktopDialogCloseButton(),
+            children: [
+              DesktopDialogCloseButton(
+                onPressedOverride: Navigator.of(
+                  context,
+                  rootNavigator: true,
+                ).pop,
+              ),
             ],
           ),
           const SizedBox(
@@ -175,7 +181,10 @@ class _UnlockWalletKeysDesktopState
                 Expanded(
                   child: SecondaryButton(
                     label: "Cancel",
-                    onPressed: Navigator.of(context).pop,
+                    onPressed: Navigator.of(
+                      context,
+                      rootNavigator: true,
+                    ).pop,
                   ),
                 ),
                 const SizedBox(
@@ -188,29 +197,35 @@ class _UnlockWalletKeysDesktopState
                     onPressed: continueEnabled
                         ? () async {
                             // todo: check password
-                            Navigator.of(context).pop();
+                            // Navigator.of(context).pop();
                             final words = await ref
                                 .read(walletsChangeNotifierProvider)
                                 .getManager(widget.walletId)
                                 .mnemonic;
-                            await showDialog<void>(
-                              context: context,
-                              barrierDismissible: false,
-                              builder: (context) => Navigator(
-                                initialRoute: WalletKeysDesktopPopup.routeName,
-                                onGenerateRoute: RouteGenerator.generateRoute,
-                                onGenerateInitialRoutes: (_, __) {
-                                  return [
-                                    RouteGenerator.generateRoute(
-                                      RouteSettings(
-                                        name: WalletKeysDesktopPopup.routeName,
-                                        arguments: words,
-                                      ),
-                                    )
-                                  ];
-                                },
-                              ),
+
+                            await Navigator.of(context).pushReplacementNamed(
+                              WalletKeysDesktopPopup.routeName,
+                              arguments: words,
                             );
+                            //
+                            // await showDialog<void>(
+                            //   context: context,
+                            //   barrierDismissible: false,
+                            //   builder: (context) => Navigator(
+                            //     initialRoute: WalletKeysDesktopPopup.routeName,
+                            //     onGenerateRoute: RouteGenerator.generateRoute,
+                            //     onGenerateInitialRoutes: (_, __) {
+                            //       return [
+                            //         RouteGenerator.generateRoute(
+                            //           RouteSettings(
+                            //             name: WalletKeysDesktopPopup.routeName,
+                            //             arguments: words,
+                            //           ),
+                            //         )
+                            //       ];
+                            //     },
+                            //   ),
+                            // );
                           }
                         : null,
                   ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
index d4921276d..649433d52 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
@@ -1,6 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -20,10 +21,29 @@ class WalletKeysButton extends StatelessWidget {
         showDialog<void>(
           context: context,
           barrierDismissible: false,
-          builder: (context) => UnlockWalletKeysDesktop(
-            walletId: walletId,
+          builder: (context) => Navigator(
+            initialRoute: UnlockWalletKeysDesktop.routeName,
+            onGenerateRoute: RouteGenerator.generateRoute,
+            onGenerateInitialRoutes: (_, __) {
+              return [
+                RouteGenerator.generateRoute(
+                  RouteSettings(
+                    name: UnlockWalletKeysDesktop.routeName,
+                    arguments: walletId,
+                  ),
+                )
+              ];
+            },
           ),
         );
+
+        // showDialog<void>(
+        //   context: context,
+        //   barrierDismissible: false,
+        //   builder: (context) => UnlockWalletKeysDesktop(
+        //     walletId: walletId,
+        //   ),
+        // );
       },
       child: Container(
         color: Colors.transparent,
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index d5a38c0fd..a6f23ffdc 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -106,6 +106,7 @@ import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:tuple/tuple.dart';
 
+import 'pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart';
 import 'pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart';
 
 class RouteGenerator {
@@ -1085,29 +1086,67 @@ class RouteGenerator {
 
       case WalletKeysDesktopPopup.routeName:
         if (args is List<String>) {
-          return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => WalletKeysDesktopPopup(
+          return FadePageRoute(
+            WalletKeysDesktopPopup(
               words: args,
             ),
-            settings: RouteSettings(
+            RouteSettings(
               name: settings.name,
             ),
           );
+          // return getRoute(
+          //   shouldUseMaterialRoute: useMaterialPageRoute,
+          //   builder: (_) => WalletKeysDesktopPopup(
+          //     words: args,
+          //   ),
+          //   settings: RouteSettings(
+          //     name: settings.name,
+          //   ),
+          // );
+        }
+        return _routeError("${settings.name} invalid args: ${args.toString()}");
+
+      case UnlockWalletKeysDesktop.routeName:
+        if (args is String) {
+          return FadePageRoute(
+            UnlockWalletKeysDesktop(
+              walletId: args,
+            ),
+            RouteSettings(
+              name: settings.name,
+            ),
+          );
+          // return getRoute(
+          //   shouldUseMaterialRoute: useMaterialPageRoute,
+          //   builder: (_) => WalletKeysDesktopPopup(
+          //     words: args,
+          //   ),
+          //   settings: RouteSettings(
+          //     name: settings.name,
+          //   ),
+          // );
         }
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case QRCodeDesktopPopupContent.routeName:
         if (args is String) {
-          return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => QRCodeDesktopPopupContent(
+          return FadePageRoute(
+            QRCodeDesktopPopupContent(
               value: args,
             ),
-            settings: RouteSettings(
+            RouteSettings(
               name: settings.name,
             ),
           );
+          // return getRoute(
+          //   shouldUseMaterialRoute: useMaterialPageRoute,
+          //   builder: (_) => QRCodeDesktopPopupContent(
+          //     value: args,
+          //   ),
+          //   settings: RouteSettings(
+          //     name: settings.name,
+          //   ),
+          // );
         }
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
@@ -1181,3 +1220,37 @@ class RouteGenerator {
         builder: (_) => errorView);
   }
 }
+
+class FadePageRoute<T> extends PageRoute<T> {
+  FadePageRoute(this.child, RouteSettings settings) : _settings = settings;
+
+  final Widget child;
+  final RouteSettings _settings;
+
+  @override
+  Color? get barrierColor => null;
+
+  @override
+  String? get barrierLabel => null;
+
+  @override
+  Widget buildPage(
+    BuildContext context,
+    Animation<double> animation,
+    Animation<double> secondaryAnimation,
+  ) {
+    return FadeTransition(
+      opacity: animation,
+      child: child,
+    );
+  }
+
+  @override
+  bool get maintainState => true;
+
+  @override
+  Duration get transitionDuration => const Duration(milliseconds: 100);
+
+  @override
+  RouteSettings get settings => _settings;
+}

From 9432ee89bf480cf25aab0fa23df24c84b688fd9b Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 17:47:24 -0600
Subject: [PATCH 114/426] node card test fix

---
 test/widget_tests/node_card_test.dart | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/test/widget_tests/node_card_test.dart b/test/widget_tests/node_card_test.dart
index 2728fc304..22e0661bf 100644
--- a/test/widget_tests/node_card_test.dart
+++ b/test/widget_tests/node_card_test.dart
@@ -1,15 +1,16 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:flutter_test/flutter_test.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:mockito/annotations.dart';
 import 'package:mockito/mockito.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/theme/light_colors.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
-import 'package:stackwallet/services/node_service.dart';
+import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/node_card.dart';
 import 'package:stackwallet/widgets/node_options_sheet.dart';
 
@@ -190,13 +191,22 @@ void main() {
     await tester.tap(find.byType(NodeCard));
     await tester.pumpAndSettle();
 
-    expect(find.text("Connect"), findsOneWidget);
-    expect(find.text("Details"), findsOneWidget);
-    expect(find.byType(NodeOptionsSheet), findsOneWidget);
-    expect(find.byType(Text), findsNWidgets(7));
+    if (Util.isDesktop) {
+      expect(find.text("Connect"), findsNothing);
+      expect(find.text("Details"), findsNothing);
+
+      verify(nodeService.getPrimaryNodeFor(coin: Coin.bitcoin)).called(1);
+      verify(nodeService.getNodeById(id: "node id")).called(1);
+    } else {
+      expect(find.text("Connect"), findsOneWidget);
+      expect(find.text("Details"), findsOneWidget);
+      expect(find.byType(NodeOptionsSheet), findsOneWidget);
+      expect(find.byType(Text), findsNWidgets(7));
+
+      verify(nodeService.getPrimaryNodeFor(coin: Coin.bitcoin)).called(2);
+      verify(nodeService.getNodeById(id: "node id")).called(2);
+    }
 
-    verify(nodeService.getPrimaryNodeFor(coin: Coin.bitcoin)).called(2);
-    verify(nodeService.getNodeById(id: "node id")).called(2);
     verify(nodeService.addListener(any)).called(1);
 
     verifyNoMoreInteractions(nodeService);

From 40a6e916f2222c10b82909c3443d6649081a7987 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 2 Nov 2022 17:47:38 -0600
Subject: [PATCH 115/426] currency dialog fix

---
 .../home/settings_menu/currency_settings/currency_dialog.dart   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
index aabc81cd1..bbe98c1af 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
@@ -96,7 +96,7 @@ class _CurrencyDialog extends ConsumerState<CurrencyDialog> {
   @override
   Widget build(BuildContext context) {
     current = ref
-        .watch(prefsChangeNotifierProvider.select((value) => value.language));
+        .watch(prefsChangeNotifierProvider.select((value) => value.currency));
 
     currenciesWithoutSelected = ref
         .watch(baseCurrenciesProvider.select((value) => value.map))

From 424852136ea9d4cb18f6a4af2062892e7f9353c0 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 19:00:08 -0600
Subject: [PATCH 116/426] v1.5.13 build 84

---
 .../home/settings_menu/currency_settings.dart | 102 ------------------
 pubspec.yaml                                  |   2 +-
 2 files changed, 1 insertion(+), 103 deletions(-)
 delete mode 100644 lib/pages_desktop_specific/home/settings_menu/currency_settings.dart

diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings.dart
deleted file mode 100644
index 4327b320b..000000000
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings.dart
+++ /dev/null
@@ -1,102 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/src/widgets/framework.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
-import 'package:stackwallet/widgets/rounded_white_container.dart';
-
-class CurrencySettings extends ConsumerStatefulWidget {
-  const CurrencySettings({Key? key}) : super(key: key);
-
-  static const String routeName = "/settingsMenuCurrency";
-
-  @override
-  ConsumerState<CurrencySettings> createState() => _CurrencySettings();
-}
-
-class _CurrencySettings extends ConsumerState<CurrencySettings> {
-  @override
-  Widget build(BuildContext context) {
-    debugPrint("BUILD: $runtimeType");
-    return Column(
-      children: [
-        Padding(
-          padding: const EdgeInsets.only(
-            right: 30,
-          ),
-          child: RoundedWhiteContainer(
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                SvgPicture.asset(
-                  Assets.svg.circleDollarSign,
-                  width: 48,
-                  height: 48,
-                ),
-                Center(
-                  child: Padding(
-                    padding: const EdgeInsets.all(10),
-                    child: RichText(
-                      textAlign: TextAlign.start,
-                      text: TextSpan(
-                        children: [
-                          TextSpan(
-                            text: "Currency",
-                            style: STextStyles.desktopTextSmall(context),
-                          ),
-                          TextSpan(
-                            text:
-                                "\n\nProtect your Stack Wallet with a strong password. Stack Wallet does not store "
-                                "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
-                          ),
-                        ],
-                      ),
-                    ),
-                  ),
-                ),
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
-                    Padding(
-                      padding: EdgeInsets.all(
-                        10,
-                      ),
-                      child: NewPasswordButton(),
-                    ),
-                  ],
-                ),
-              ],
-            ),
-          ),
-        ),
-      ],
-    );
-  }
-}
-
-class NewPasswordButton extends ConsumerWidget {
-  const NewPasswordButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
-        child: Text(
-          "Set up new password",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
diff --git a/pubspec.yaml b/pubspec.yaml
index b84135f4a..5be35c66e 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.12+84
+version: 1.5.13+84
 
 environment:
   sdk: ">=2.17.0 <3.0.0"

From 0504f2336c135682ffc8d02d744fcae04d1f5cde Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 2 Nov 2022 20:07:27 -0600
Subject: [PATCH 117/426] debug popup

---
 .../advanced_settings/advanced_settings.dart  |  25 +-
 .../advanced_settings/debug_info_dialog.dart  | 308 +++++++++++++-----
 2 files changed, 245 insertions(+), 88 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
index 1632576fd..8e89e3f67 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
@@ -10,6 +10,8 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
+import 'debug_info_dialog.dart';
+
 class AdvancedSettings extends ConsumerStatefulWidget {
   const AdvancedSettings({Key? key}) : super(key: key);
 
@@ -226,16 +228,16 @@ class ShowLogsButton extends ConsumerWidget {
   }) : super(key: key);
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    // Future<void> viewDebugLogs() async {
-    //   await showDialog<dynamic>(
-    //     context: context,
-    //     useSafeArea: false,
-    //     barrierDismissible: true,
-    //     builder: (context) {
-    //       return const DebugInfoDialog();
-    //     },
-    //   );
-    // }
+    Future<void> viewDebugLogs() async {
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: true,
+        builder: (context) {
+          return const DebugInfoDialog();
+        },
+      );
+    }
 
     return SizedBox(
       width: 101,
@@ -245,8 +247,7 @@ class ShowLogsButton extends ConsumerWidget {
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {
-          //
-          // viewDebugLogs();
+          viewDebugLogs();
         },
         child: Text(
           "Show logs",
diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
index 342d9180a..0406a059f 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
@@ -1,29 +1,33 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/isar/models/log.dart';
+import 'package:stackwallet/providers/global/debug_service_provider.dart';
+import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/log_level_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/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-// import '../../../utilities/assets.dart';
-// import '../../../utilities/util.dart';
-// import '../../../widgets/icon_widgets/x_icon.dart';
-// import '../../../widgets/stack_text_field.dart';
-// import '../../../widgets/textfield_icon_button.dart';
-
-class DebugInfoDialog extends StatefulWidget {
+class DebugInfoDialog extends ConsumerStatefulWidget {
   const DebugInfoDialog({Key? key}) : super(key: key);
 
   @override
-  State<StatefulWidget> createState() => _DebugInfoDialog();
+  ConsumerState<DebugInfoDialog> createState() => _DebugInfoDialog();
 }
 
-class _DebugInfoDialog extends State<DebugInfoDialog> {
-  final _searchController = TextEditingController();
-  final _searchFocusNode = FocusNode();
+class _DebugInfoDialog extends ConsumerState<DebugInfoDialog> {
+  late final TextEditingController searchDebugController;
+  late final FocusNode searchDebugFocusNode;
 
   final scrollController = ScrollController();
 
@@ -62,15 +66,19 @@ class _DebugInfoDialog extends State<DebugInfoDialog> {
 
   @override
   void initState() {
-    // ref.read(debugServiceProvider).updateRecentLogs();
+    searchDebugController = TextEditingController();
+    searchDebugFocusNode = FocusNode();
+
+    ref.read(debugServiceProvider).updateRecentLogs();
     super.initState();
   }
 
   @override
   void dispose() {
-    _searchController.dispose();
+    searchDebugFocusNode.dispose();
+    searchDebugController.dispose();
+
     scrollController.dispose();
-    _searchFocusNode.dispose();
 
     super.dispose();
   }
@@ -78,7 +86,7 @@ class _DebugInfoDialog extends State<DebugInfoDialog> {
   @override
   Widget build(BuildContext context) {
     return DesktopDialog(
-      maxHeight: 800,
+      maxHeight: 850,
       maxWidth: 600,
       child: Column(
         children: [
@@ -96,68 +104,216 @@ class _DebugInfoDialog extends State<DebugInfoDialog> {
               const DesktopDialogCloseButton(),
             ],
           ),
-          Row(
-            children: [
-              // ClipRRect(
-              //   borderRadius: BorderRadius.circular(
-              //     Constants.size.circularBorderRadius,
-              //   ),
-              //   child: TextField(
-              //     key: const Key("desktopSettingDebugInfo"),
-              //     autocorrect: Util.isDesktop ? false : true,
-              //     enableSuggestions: Util.isDesktop ? false : true,
-              //     controller: _searchController,
-              //     focusNode: _searchFocusNode,
-              //     // onChanged: (newString) {
-              //     //   setState(() => _searchTerm = newString);
-              //     // },
-              //     style: STextStyles.field(context),
-              //     decoration: standardInputDecoration(
-              //       "Search",
-              //       _searchFocusNode,
-              //       context,
-              //     ).copyWith(
-              //       prefixIcon: Padding(
-              //         padding: const EdgeInsets.symmetric(
-              //           horizontal: 10,
-              //           vertical: 16,
-              //         ),
-              //         child: SvgPicture.asset(
-              //           Assets.svg.search,
-              //           width: 16,
-              //           height: 16,
-              //         ),
-              //       ),
-              //       suffixIcon: _searchController.text.isNotEmpty
-              //           ? Padding(
-              //               padding: const EdgeInsets.only(right: 0),
-              //               child: UnconstrainedBox(
-              //                 child: Row(
-              //                   children: [
-              //                     TextFieldIconButton(
-              //                       child: const XIcon(),
-              //                       onTap: () async {
-              //                         setState(() {
-              //                           _searchController.text = "";
-              //                           _searchTerm = "";
-              //                         });
-              //                       },
-              //                     ),
-              //                   ],
-              //                 ),
-              //               ),
-              //             )
-              //           : null,
-              //     ),
-              //   ),
-              // ),
-            ],
+          Expanded(
+            flex: 24,
+            child: NestedScrollView(
+              floatHeaderSlivers: true,
+              headerSliverBuilder: (context, innerBoxIsScrolled) {
+                return [
+                  SliverOverlapAbsorber(
+                    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+                        context),
+                    sliver: SliverToBoxAdapter(
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(
+                            vertical: 16, horizontal: 32),
+                        child: Column(
+                          children: [
+                            Padding(
+                              padding: const EdgeInsets.only(bottom: 16),
+                              child: ClipRRect(
+                                borderRadius: BorderRadius.circular(
+                                  Constants.size.circularBorderRadius,
+                                ),
+                                child: TextField(
+                                  autocorrect: Util.isDesktop ? false : true,
+                                  enableSuggestions:
+                                      Util.isDesktop ? false : true,
+                                  controller: searchDebugController,
+                                  focusNode: searchDebugFocusNode,
+                                  onChanged: (newString) {
+                                    setState(() => _searchTerm = newString);
+                                  },
+                                  style: STextStyles.field(context),
+                                  decoration: standardInputDecoration(
+                                    "Search",
+                                    searchDebugFocusNode,
+                                    context,
+                                  ).copyWith(
+                                    prefixIcon: Padding(
+                                      padding: const EdgeInsets.symmetric(
+                                        horizontal: 10,
+                                        vertical: 16,
+                                      ),
+                                      child: SvgPicture.asset(
+                                        Assets.svg.search,
+                                        width: 16,
+                                        height: 16,
+                                      ),
+                                    ),
+                                    suffixIcon: searchDebugController
+                                            .text.isNotEmpty
+                                        ? Padding(
+                                            padding:
+                                                const EdgeInsets.only(right: 0),
+                                            child: UnconstrainedBox(
+                                              child: Row(
+                                                children: [
+                                                  TextFieldIconButton(
+                                                    child: const XIcon(),
+                                                    onTap: () async {
+                                                      setState(() {
+                                                        searchDebugController
+                                                            .text = "";
+                                                        _searchTerm = "";
+                                                      });
+                                                    },
+                                                  ),
+                                                ],
+                                              ),
+                                            ),
+                                          )
+                                        : null,
+                                  ),
+                                ),
+                              ),
+                            ),
+                            const SizedBox(
+                              height: 12,
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                ];
+              },
+              body: Builder(
+                builder: (context) {
+                  final logs = filtered(
+                          ref.watch(debugServiceProvider
+                              .select((value) => value.recentLogs)),
+                          _searchTerm)
+                      .reversed
+                      .toList(growable: false);
+                  return CustomScrollView(
+                    reverse: true,
+                    // shrinkWrap: true,
+                    controller: scrollController,
+                    slivers: [
+                      SliverOverlapInjector(
+                        handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+                          context,
+                        ),
+                      ),
+                      SliverList(
+                        delegate: SliverChildBuilderDelegate(
+                          (context, index) {
+                            final log = logs[index];
+
+                            return Container(
+                              key: Key(
+                                  "log_${log.id}_${log.timestampInMillisUTC}"),
+                              decoration: BoxDecoration(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .popupBG,
+                                borderRadius: _borderRadius(index, logs.length),
+                              ),
+                              child: Padding(
+                                padding: const EdgeInsets.all(4),
+                                child: Padding(
+                                  padding: const EdgeInsets.symmetric(
+                                      horizontal: 32),
+                                  child: RoundedContainer(
+                                    padding: const EdgeInsets.all(0),
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .popupBG,
+                                    child: Column(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        Row(
+                                          children: [
+                                            Text(
+                                              " [${log.logLevel.name}]",
+                                              style: STextStyles.baseXS(context)
+                                                  .copyWith(
+                                                fontSize: 8,
+                                                color: (log.logLevel ==
+                                                        LogLevel.Info
+                                                    ? Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .topNavIconGreen
+                                                    : (log.logLevel ==
+                                                            LogLevel.Warning
+                                                        ? Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .topNavIconYellow
+                                                        : (log.logLevel ==
+                                                                LogLevel.Error
+                                                            ? Colors.orange
+                                                            : Theme.of(context)
+                                                                .extension<
+                                                                    StackColors>()!
+                                                                .topNavIconRed))),
+                                              ),
+                                            ),
+                                            Text(
+                                              "[${DateTime.fromMillisecondsSinceEpoch(log.timestampInMillisUTC, isUtc: true)}]: ",
+                                              style: STextStyles.baseXS(context)
+                                                  .copyWith(
+                                                fontSize: 12,
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark3,
+                                              ),
+                                            ),
+                                          ],
+                                        ),
+                                        Row(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            const SizedBox(
+                                              width: 20,
+                                            ),
+                                            Flexible(
+                                              child: Column(
+                                                crossAxisAlignment:
+                                                    CrossAxisAlignment.start,
+                                                children: [
+                                                  SelectableText(
+                                                    log.message,
+                                                    style: STextStyles.baseXS(
+                                                            context)
+                                                        .copyWith(
+                                                            fontSize: 11.5),
+                                                  ),
+                                                ],
+                                              ),
+                                            ),
+                                          ],
+                                        ),
+                                      ],
+                                    ),
+                                  ),
+                                ),
+                              ),
+                            );
+                          },
+                          childCount: logs.length,
+                        ),
+                      ),
+                    ],
+                  );
+                },
+              ),
+            ),
           ),
-          // Column(
-          //   children: [
-          //
-          //   ],
-          // ),
           const Spacer(),
           Padding(
             padding: const EdgeInsets.all(32),

From c711bb94195ef84038d637b98d29e2b44ca541e4 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 3 Nov 2022 09:41:10 -0600
Subject: [PATCH 118/426] added search bar to desktop nodes settings

---
 .../home/settings_menu/nodes_settings.dart    | 211 +++++++++++-------
 1 file changed, 130 insertions(+), 81 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index bb60061d8..5f1e70143 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -11,6 +11,9 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
+import '../../../utilities/util.dart';
+import '../../../widgets/stack_text_field.dart';
+
 class NodesSettings extends ConsumerStatefulWidget {
   const NodesSettings({Key? key}) : super(key: key);
 
@@ -23,15 +26,27 @@ class NodesSettings extends ConsumerStatefulWidget {
 class _NodesSettings extends ConsumerState<NodesSettings> {
   List<Coin> _coins = [...Coin.values];
 
+  late final TextEditingController searchNodeController;
+  late final FocusNode searchNodeFocusNode;
+
+  String filter = "";
+
   @override
   void initState() {
     _coins = _coins.toList();
     _coins.remove(Coin.firoTestNet);
+
+    searchNodeController = TextEditingController();
+    searchNodeFocusNode = FocusNode();
+
     super.initState();
   }
 
   @override
   void dispose() {
+    searchNodeController.dispose();
+    searchNodeFocusNode.dispose();
+
     super.dispose();
   }
 
@@ -85,88 +100,122 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                     ),
                   ],
                 ),
-                //TODO: add search bar
-                SingleChildScrollView(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      ...coins.map(
-                        (coin) {
-                          final count = ref
-                              .watch(nodeServiceChangeNotifierProvider
-                                  .select((value) => value.getNodesFor(coin)))
-                              .length;
-
-                          return Padding(
-                            padding: const EdgeInsets.all(0),
-                            child: RawMaterialButton(
-                              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                              shape: RoundedRectangleBorder(
-                                borderRadius: BorderRadius.circular(
-                                  Constants.size.circularBorderRadius,
-                                ),
-                                // side: BorderSide(
-                                //     color: Theme.of(context)
-                                //         .extension<StackColors>()!
-                                //         .shadow),
-                              ),
-                              materialTapTargetSize:
-                                  MaterialTapTargetSize.shrinkWrap,
-                              onPressed: () {
-                                Navigator.of(context).pushNamed(
-                                  CoinNodesView.routeName,
-                                  arguments: coin,
-                                );
-                              },
-                              child: Padding(
-                                padding: const EdgeInsets.all(
-                                  12.0,
-                                ),
-                                child: Row(
-                                  children: [
-                                    Row(
-                                      children: [
-                                        SvgPicture.asset(
-                                          Assets.svg.iconFor(coin: coin),
-                                          width: 24,
-                                          height: 24,
-                                        ),
-                                        const SizedBox(
-                                          width: 12,
-                                        ),
-                                        Column(
-                                          crossAxisAlignment:
-                                              CrossAxisAlignment.start,
-                                          children: [
-                                            Text(
-                                              "${coin.prettyName} nodes",
-                                              style: STextStyles.titleBold12(
-                                                  context),
-                                            ),
-                                            Text(
-                                              count > 1
-                                                  ? "$count nodes"
-                                                  : "Default",
-                                              style: STextStyles.label(context),
-                                            ),
-                                          ],
-                                        ),
-                                      ],
-                                    ),
-                                    Expanded(
-                                      child: SvgPicture.asset(
-                                        Assets.svg.chevronRight,
-                                        alignment: Alignment.centerRight,
-                                      ),
-                                    ),
-                                  ],
-                                ),
-                              ),
-                            ),
-                          );
-                        },
+                Padding(
+                  padding: const EdgeInsets.all(10.0),
+                  child: ClipRRect(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
+                    child: TextField(
+                      autocorrect: Util.isDesktop ? false : true,
+                      enableSuggestions: Util.isDesktop ? false : true,
+                      controller: searchNodeController,
+                      focusNode: searchNodeFocusNode,
+                      onChanged: (newString) {
+                        setState(() => filter = newString);
+                      },
+                      style: STextStyles.field(context),
+                      decoration: standardInputDecoration(
+                        "Search",
+                        searchNodeFocusNode,
+                        context,
+                      ).copyWith(
+                        prefixIcon: Padding(
+                          padding: const EdgeInsets.symmetric(
+                            horizontal: 10,
+                            vertical: 16,
+                          ),
+                          child: SvgPicture.asset(
+                            Assets.svg.search,
+                            width: 16,
+                            height: 16,
+                          ),
+                        ),
                       ),
-                    ],
+                    ),
+                  ),
+                ),
+                Padding(
+                  padding: const EdgeInsets.all(10.0),
+                  child: SingleChildScrollView(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        ...coins.map(
+                          (coin) {
+                            final count = ref
+                                .watch(nodeServiceChangeNotifierProvider
+                                    .select((value) => value.getNodesFor(coin)))
+                                .length;
+
+                            return Padding(
+                              padding: const EdgeInsets.all(0),
+                              child: RawMaterialButton(
+                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                                shape: RoundedRectangleBorder(
+                                  borderRadius: BorderRadius.circular(
+                                    Constants.size.circularBorderRadius,
+                                  ),
+                                ),
+                                materialTapTargetSize:
+                                    MaterialTapTargetSize.shrinkWrap,
+                                onPressed: () {
+                                  Navigator.of(context).pushNamed(
+                                    CoinNodesView.routeName,
+                                    arguments: coin,
+                                  );
+                                },
+                                child: Padding(
+                                  padding: const EdgeInsets.all(
+                                    12.0,
+                                  ),
+                                  child: Row(
+                                    children: [
+                                      Row(
+                                        children: [
+                                          SvgPicture.asset(
+                                            Assets.svg.iconFor(coin: coin),
+                                            width: 24,
+                                            height: 24,
+                                          ),
+                                          const SizedBox(
+                                            width: 12,
+                                          ),
+                                          Column(
+                                            crossAxisAlignment:
+                                                CrossAxisAlignment.start,
+                                            children: [
+                                              Text(
+                                                "${coin.prettyName} nodes",
+                                                style: STextStyles.titleBold12(
+                                                    context),
+                                              ),
+                                              Text(
+                                                count > 1
+                                                    ? "$count nodes"
+                                                    : "Default",
+                                                style:
+                                                    STextStyles.label(context),
+                                              ),
+                                            ],
+                                          ),
+                                        ],
+                                      ),
+                                      Expanded(
+                                        child: SvgPicture.asset(
+                                          Assets.svg.chevronRight,
+                                          alignment: Alignment.centerRight,
+                                        ),
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              ),
+                            );
+                          },
+                        ),
+                      ],
+                    ),
                   ),
                 ),
               ],

From 3950c025d88d42d4d61e3e043e895858f73e6703 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 3 Nov 2022 10:01:16 -0600
Subject: [PATCH 119/426] v1.5.13 build 85

---
 pubspec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index 5be35c66e..64c678637 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.13+84
+version: 1.5.13+85
 
 environment:
   sdk: ">=2.17.0 <3.0.0"

From dc4e7f4baebc2082f33bb07cae2f0abff2f5dcb2 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 3 Nov 2022 11:04:57 -0600
Subject: [PATCH 120/426] shared currency settings code

---
 .../global_settings_view/currency_view.dart   | 115 ++-
 .../currency_settings/currency_dialog.dart    | 742 +++++++++---------
 .../currency_settings/currency_settings.dart  |  38 +-
 3 files changed, 496 insertions(+), 399 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/currency_view.dart b/lib/pages/settings_views/global_settings_view/currency_view.dart
index e884393bd..4f2c3258c 100644
--- a/lib/pages/settings_views/global_settings_view/currency_view.dart
+++ b/lib/pages/settings_views/global_settings_view/currency_view.dart
@@ -7,13 +7,17 @@ import 'package:stackwallet/utilities/assets.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/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-import 'package:stackwallet/utilities/util.dart';
+import '../../../widgets/rounded_white_container.dart';
 
 class BaseCurrencySettingsView extends ConsumerStatefulWidget {
   const BaseCurrencySettingsView({Key? key}) : super(key: key);
@@ -102,31 +106,90 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
       currenciesWithoutSelected.insert(0, current);
     }
     currenciesWithoutSelected = _filtered();
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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(
-          "Currency",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.only(
-          top: 12,
-          left: 16,
-          right: 16,
-        ),
+    final isDesktop = Util.isDesktop;
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            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(
+              "Currency",
+              style: STextStyles.navBarTitle(context),
+            ),
+          ),
+          body: Padding(
+            padding: const EdgeInsets.only(
+              top: 12,
+              left: 16,
+              right: 16,
+            ),
+            child: child,
+          ),
+        );
+      },
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) {
+          return Padding(
+            padding: const EdgeInsets.only(
+              top: 16,
+              bottom: 32,
+              left: 32,
+              right: 32,
+            ),
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                Expanded(
+                  child: RoundedWhiteContainer(
+                    padding: const EdgeInsets.all(20),
+                    borderColor:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    child: child,
+                  ),
+                ),
+                const SizedBox(
+                  height: 16,
+                ),
+                Row(
+                  children: [
+                    Expanded(
+                      child: SecondaryButton(
+                        label: "Cancel",
+                        desktopMed: true,
+                        onPressed: Navigator.of(context).pop,
+                      ),
+                    ),
+                    const SizedBox(
+                      width: 16,
+                    ),
+                    Expanded(
+                      child: PrimaryButton(
+                        label: "Save changes",
+                        desktopMed: true,
+                        onPressed: Navigator.of(context).pop,
+                      ),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          );
+        },
         child: NestedScrollView(
           floatHeaderSlivers: true,
           headerSliverBuilder: (context, innerBoxIsScrolled) {
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
index bbe98c1af..602589cea 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
@@ -1,371 +1,371 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/providers/global/base_currencies_provider.dart';
-import 'package:stackwallet/providers/global/prefs_provider.dart';
-import 'package:stackwallet/utilities/assets.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/desktop/desktop_dialog.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
-import 'package:stackwallet/widgets/desktop/primary_button.dart';
-import 'package:stackwallet/widgets/desktop/secondary_button.dart';
-import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
-import 'package:stackwallet/widgets/rounded_container.dart';
-import 'package:stackwallet/widgets/stack_text_field.dart';
-import 'package:stackwallet/widgets/textfield_icon_button.dart';
-
-class CurrencyDialog extends ConsumerStatefulWidget {
-  const CurrencyDialog({Key? key}) : super(key: key);
-
-  @override
-  ConsumerState<CurrencyDialog> createState() => _CurrencyDialog();
-}
-
-class _CurrencyDialog extends ConsumerState<CurrencyDialog> {
-  late String current;
-  late List<String> currenciesWithoutSelected;
-
-  late final TextEditingController searchCurrencyController;
-
-  late final FocusNode searchCurrencyFocusNode;
-
-  void onTap(int index) {
-    if (currenciesWithoutSelected[index] == current || current.isEmpty) {
-      // ignore if already selected currency
-      return;
-    }
-    current = currenciesWithoutSelected[index];
-    currenciesWithoutSelected.remove(current);
-    currenciesWithoutSelected.insert(0, current);
-    ref.read(prefsChangeNotifierProvider).currency = current;
-  }
-
-  BorderRadius? _borderRadius(int index) {
-    if (index == 0 && currenciesWithoutSelected.length == 1) {
-      return BorderRadius.circular(
-        Constants.size.circularBorderRadius,
-      );
-    } else if (index == 0) {
-      return BorderRadius.vertical(
-        top: Radius.circular(
-          Constants.size.circularBorderRadius,
-        ),
-      );
-    } else if (index == currenciesWithoutSelected.length - 1) {
-      return BorderRadius.vertical(
-        bottom: Radius.circular(
-          Constants.size.circularBorderRadius,
-        ),
-      );
-    }
-    return null;
-  }
-
-  String filter = "";
-
-  List<String> _filtered() {
-    final currencyMap = ref.read(baseCurrenciesProvider).map;
-    return currenciesWithoutSelected.where((element) {
-      return element.toLowerCase().contains(filter.toLowerCase()) ||
-          (currencyMap[element]?.toLowerCase().contains(filter.toLowerCase()) ??
-              false);
-    }).toList();
-  }
-
-  @override
-  void initState() {
-    searchCurrencyController = TextEditingController();
-
-    searchCurrencyFocusNode = FocusNode();
-
-    super.initState();
-  }
-
-  @override
-  void dispose() {
-    searchCurrencyController.dispose();
-
-    searchCurrencyFocusNode.dispose();
-
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    current = ref
-        .watch(prefsChangeNotifierProvider.select((value) => value.currency));
-
-    currenciesWithoutSelected = ref
-        .watch(baseCurrenciesProvider.select((value) => value.map))
-        .keys
-        .toList();
-    if (current.isNotEmpty) {
-      currenciesWithoutSelected.remove(current);
-      currenciesWithoutSelected.insert(0, current);
-    }
-    currenciesWithoutSelected = _filtered();
-
-    return DesktopDialog(
-      maxHeight: 800,
-      maxWidth: 600,
-      child: Column(
-        children: [
-          Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            children: [
-              Padding(
-                padding: const EdgeInsets.all(32),
-                child: Text(
-                  "Select currency",
-                  style: STextStyles.desktopH3(context),
-                  textAlign: TextAlign.center,
-                ),
-              ),
-              const DesktopDialogCloseButton(),
-            ],
-          ),
-          Expanded(
-            flex: 24,
-            child: NestedScrollView(
-              floatHeaderSlivers: true,
-              headerSliverBuilder: (context, innerBoxIsScrolled) {
-                return [
-                  SliverOverlapAbsorber(
-                    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
-                        context),
-                    sliver: SliverToBoxAdapter(
-                      child: Padding(
-                        padding: const EdgeInsets.symmetric(
-                            vertical: 16, horizontal: 32),
-                        child: Column(
-                          children: [
-                            Padding(
-                              padding: const EdgeInsets.only(bottom: 16),
-                              child: ClipRRect(
-                                borderRadius: BorderRadius.circular(
-                                  Constants.size.circularBorderRadius,
-                                ),
-                                child: TextField(
-                                  autocorrect: Util.isDesktop ? false : true,
-                                  enableSuggestions:
-                                      Util.isDesktop ? false : true,
-                                  controller: searchCurrencyController,
-                                  focusNode: searchCurrencyFocusNode,
-                                  onChanged: (newString) {
-                                    setState(() => filter = newString);
-                                  },
-                                  style: STextStyles.field(context),
-                                  decoration: standardInputDecoration(
-                                    "Search",
-                                    searchCurrencyFocusNode,
-                                    context,
-                                  ).copyWith(
-                                    prefixIcon: Padding(
-                                      padding: const EdgeInsets.symmetric(
-                                        horizontal: 10,
-                                        vertical: 16,
-                                      ),
-                                      child: SvgPicture.asset(
-                                        Assets.svg.search,
-                                        width: 16,
-                                        height: 16,
-                                      ),
-                                    ),
-                                    suffixIcon: searchCurrencyController
-                                            .text.isNotEmpty
-                                        ? Padding(
-                                            padding:
-                                                const EdgeInsets.only(right: 0),
-                                            child: UnconstrainedBox(
-                                              child: Row(
-                                                children: [
-                                                  TextFieldIconButton(
-                                                    child: const XIcon(),
-                                                    onTap: () async {
-                                                      setState(() {
-                                                        searchCurrencyController
-                                                            .text = "";
-                                                        filter = "";
-                                                      });
-                                                    },
-                                                  ),
-                                                ],
-                                              ),
-                                            ),
-                                          )
-                                        : null,
-                                  ),
-                                ),
-                              ),
-                            ),
-                          ],
-                        ),
-                      ),
-                    ),
-                  ),
-                ];
-              },
-              body: Builder(
-                builder: (context) {
-                  return CustomScrollView(
-                    slivers: [
-                      SliverOverlapInjector(
-                        handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
-                          context,
-                        ),
-                      ),
-                      SliverList(
-                        delegate: SliverChildBuilderDelegate(
-                          (context, index) {
-                            return Container(
-                              decoration: BoxDecoration(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .popupBG,
-                                borderRadius: _borderRadius(index),
-                              ),
-                              child: Padding(
-                                padding: const EdgeInsets.all(4),
-                                key: Key(
-                                    "desktopSettingsCurrencySelect_${currenciesWithoutSelected[index]}"),
-                                child: Padding(
-                                  padding: const EdgeInsets.symmetric(
-                                      horizontal: 32),
-                                  child: RoundedContainer(
-                                    padding: const EdgeInsets.all(0),
-                                    color: currenciesWithoutSelected[index] ==
-                                            current
-                                        ? Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .currencyListItemBG
-                                        : Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .popupBG,
-                                    child: RawMaterialButton(
-                                      onPressed: () async {
-                                        onTap(index);
-                                      },
-                                      shape: RoundedRectangleBorder(
-                                        borderRadius: BorderRadius.circular(
-                                          Constants.size.circularBorderRadius,
-                                        ),
-                                      ),
-                                      child: Padding(
-                                        padding: const EdgeInsets.all(12.0),
-                                        child: Row(
-                                          crossAxisAlignment:
-                                              CrossAxisAlignment.start,
-                                          children: [
-                                            SizedBox(
-                                              width: 20,
-                                              height: 20,
-                                              child: Radio(
-                                                activeColor: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .radioButtonIconEnabled,
-                                                materialTapTargetSize:
-                                                    MaterialTapTargetSize
-                                                        .shrinkWrap,
-                                                value: true,
-                                                groupValue:
-                                                    currenciesWithoutSelected[
-                                                            index] ==
-                                                        current,
-                                                onChanged: (_) {
-                                                  onTap(index);
-                                                },
-                                              ),
-                                            ),
-                                            const SizedBox(
-                                              width: 12,
-                                            ),
-                                            Column(
-                                              crossAxisAlignment:
-                                                  CrossAxisAlignment.start,
-                                              children: [
-                                                Text(
-                                                  currenciesWithoutSelected[
-                                                      index],
-                                                  key: (currenciesWithoutSelected[
-                                                              index] ==
-                                                          current)
-                                                      ? const Key(
-                                                          "desktopSettingsSelectedCurrencyText")
-                                                      : null,
-                                                  style:
-                                                      STextStyles.largeMedium14(
-                                                          context),
-                                                ),
-                                                const SizedBox(
-                                                  height: 2,
-                                                ),
-                                                Text(
-                                                  ref.watch(baseCurrenciesProvider
-                                                              .select((value) =>
-                                                                  value.map))[
-                                                          currenciesWithoutSelected[
-                                                              index]] ??
-                                                      "",
-                                                  key: (currenciesWithoutSelected[
-                                                              index] ==
-                                                          current)
-                                                      ? const Key(
-                                                          "desktopSelectedCurrencyTextDescription")
-                                                      : null,
-                                                  style:
-                                                      STextStyles.itemSubtitle(
-                                                          context),
-                                                ),
-                                              ],
-                                            ),
-                                          ],
-                                        ),
-                                      ),
-                                    ),
-                                  ),
-                                ),
-                              ),
-                            );
-                          },
-                          childCount: currenciesWithoutSelected.length,
-                        ),
-                      ),
-                    ],
-                  );
-                },
-              ),
-            ),
-          ),
-          const Spacer(),
-          Padding(
-            padding: const EdgeInsets.all(32),
-            child: Row(
-              children: [
-                Expanded(
-                  child: SecondaryButton(
-                    label: "Cancel",
-                    onPressed: () {
-                      Navigator.of(context).pop();
-                    },
-                  ),
-                ),
-                const SizedBox(
-                  width: 16,
-                ),
-                Expanded(
-                  child: PrimaryButton(
-                    label: "Save Changes",
-                    onPressed: () {},
-                  ),
-                )
-              ],
-            ),
-          ),
-        ],
-      ),
-    );
-  }
-}
+// import 'package:flutter/material.dart';
+// import 'package:flutter_riverpod/flutter_riverpod.dart';
+// import 'package:flutter_svg/svg.dart';
+// import 'package:stackwallet/providers/global/base_currencies_provider.dart';
+// import 'package:stackwallet/providers/global/prefs_provider.dart';
+// import 'package:stackwallet/utilities/assets.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/desktop/desktop_dialog.dart';
+// import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+// import 'package:stackwallet/widgets/desktop/primary_button.dart';
+// import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+// import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+// import 'package:stackwallet/widgets/rounded_container.dart';
+// import 'package:stackwallet/widgets/stack_text_field.dart';
+// import 'package:stackwallet/widgets/textfield_icon_button.dart';
+//
+// class CurrencyDialog extends ConsumerStatefulWidget {
+//   const CurrencyDialog({Key? key}) : super(key: key);
+//
+//   @override
+//   ConsumerState<CurrencyDialog> createState() => _CurrencyDialog();
+// }
+//
+// class _CurrencyDialog extends ConsumerState<CurrencyDialog> {
+//   late String current;
+//   late List<String> currenciesWithoutSelected;
+//
+//   late final TextEditingController searchCurrencyController;
+//
+//   late final FocusNode searchCurrencyFocusNode;
+//
+//   void onTap(int index) {
+//     if (currenciesWithoutSelected[index] == current || current.isEmpty) {
+//       // ignore if already selected currency
+//       return;
+//     }
+//     current = currenciesWithoutSelected[index];
+//     currenciesWithoutSelected.remove(current);
+//     currenciesWithoutSelected.insert(0, current);
+//     ref.read(prefsChangeNotifierProvider).currency = current;
+//   }
+//
+//   BorderRadius? _borderRadius(int index) {
+//     if (index == 0 && currenciesWithoutSelected.length == 1) {
+//       return BorderRadius.circular(
+//         Constants.size.circularBorderRadius,
+//       );
+//     } else if (index == 0) {
+//       return BorderRadius.vertical(
+//         top: Radius.circular(
+//           Constants.size.circularBorderRadius,
+//         ),
+//       );
+//     } else if (index == currenciesWithoutSelected.length - 1) {
+//       return BorderRadius.vertical(
+//         bottom: Radius.circular(
+//           Constants.size.circularBorderRadius,
+//         ),
+//       );
+//     }
+//     return null;
+//   }
+//
+//   String filter = "";
+//
+//   List<String> _filtered() {
+//     final currencyMap = ref.read(baseCurrenciesProvider).map;
+//     return currenciesWithoutSelected.where((element) {
+//       return element.toLowerCase().contains(filter.toLowerCase()) ||
+//           (currencyMap[element]?.toLowerCase().contains(filter.toLowerCase()) ??
+//               false);
+//     }).toList();
+//   }
+//
+//   @override
+//   void initState() {
+//     searchCurrencyController = TextEditingController();
+//
+//     searchCurrencyFocusNode = FocusNode();
+//
+//     super.initState();
+//   }
+//
+//   @override
+//   void dispose() {
+//     searchCurrencyController.dispose();
+//
+//     searchCurrencyFocusNode.dispose();
+//
+//     super.dispose();
+//   }
+//
+//   @override
+//   Widget build(BuildContext context) {
+//     current = ref
+//         .watch(prefsChangeNotifierProvider.select((value) => value.currency));
+//
+//     currenciesWithoutSelected = ref
+//         .watch(baseCurrenciesProvider.select((value) => value.map))
+//         .keys
+//         .toList();
+//     if (current.isNotEmpty) {
+//       currenciesWithoutSelected.remove(current);
+//       currenciesWithoutSelected.insert(0, current);
+//     }
+//     currenciesWithoutSelected = _filtered();
+//
+//     return DesktopDialog(
+//       maxHeight: 800,
+//       maxWidth: 600,
+//       child: Column(
+//         children: [
+//           Row(
+//             mainAxisAlignment: MainAxisAlignment.spaceBetween,
+//             children: [
+//               Padding(
+//                 padding: const EdgeInsets.all(32),
+//                 child: Text(
+//                   "Select currency",
+//                   style: STextStyles.desktopH3(context),
+//                   textAlign: TextAlign.center,
+//                 ),
+//               ),
+//               const DesktopDialogCloseButton(),
+//             ],
+//           ),
+//           Expanded(
+//             flex: 24,
+//             child: NestedScrollView(
+//               floatHeaderSlivers: true,
+//               headerSliverBuilder: (context, innerBoxIsScrolled) {
+//                 return [
+//                   SliverOverlapAbsorber(
+//                     handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+//                         context),
+//                     sliver: SliverToBoxAdapter(
+//                       child: Padding(
+//                         padding: const EdgeInsets.symmetric(
+//                             vertical: 16, horizontal: 32),
+//                         child: Column(
+//                           children: [
+//                             Padding(
+//                               padding: const EdgeInsets.only(bottom: 16),
+//                               child: ClipRRect(
+//                                 borderRadius: BorderRadius.circular(
+//                                   Constants.size.circularBorderRadius,
+//                                 ),
+//                                 child: TextField(
+//                                   autocorrect: Util.isDesktop ? false : true,
+//                                   enableSuggestions:
+//                                       Util.isDesktop ? false : true,
+//                                   controller: searchCurrencyController,
+//                                   focusNode: searchCurrencyFocusNode,
+//                                   onChanged: (newString) {
+//                                     setState(() => filter = newString);
+//                                   },
+//                                   style: STextStyles.field(context),
+//                                   decoration: standardInputDecoration(
+//                                     "Search",
+//                                     searchCurrencyFocusNode,
+//                                     context,
+//                                   ).copyWith(
+//                                     prefixIcon: Padding(
+//                                       padding: const EdgeInsets.symmetric(
+//                                         horizontal: 10,
+//                                         vertical: 16,
+//                                       ),
+//                                       child: SvgPicture.asset(
+//                                         Assets.svg.search,
+//                                         width: 16,
+//                                         height: 16,
+//                                       ),
+//                                     ),
+//                                     suffixIcon: searchCurrencyController
+//                                             .text.isNotEmpty
+//                                         ? Padding(
+//                                             padding:
+//                                                 const EdgeInsets.only(right: 0),
+//                                             child: UnconstrainedBox(
+//                                               child: Row(
+//                                                 children: [
+//                                                   TextFieldIconButton(
+//                                                     child: const XIcon(),
+//                                                     onTap: () async {
+//                                                       setState(() {
+//                                                         searchCurrencyController
+//                                                             .text = "";
+//                                                         filter = "";
+//                                                       });
+//                                                     },
+//                                                   ),
+//                                                 ],
+//                                               ),
+//                                             ),
+//                                           )
+//                                         : null,
+//                                   ),
+//                                 ),
+//                               ),
+//                             ),
+//                           ],
+//                         ),
+//                       ),
+//                     ),
+//                   ),
+//                 ];
+//               },
+//               body: Builder(
+//                 builder: (context) {
+//                   return CustomScrollView(
+//                     slivers: [
+//                       SliverOverlapInjector(
+//                         handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+//                           context,
+//                         ),
+//                       ),
+//                       SliverList(
+//                         delegate: SliverChildBuilderDelegate(
+//                           (context, index) {
+//                             return Container(
+//                               decoration: BoxDecoration(
+//                                 color: Theme.of(context)
+//                                     .extension<StackColors>()!
+//                                     .popupBG,
+//                                 borderRadius: _borderRadius(index),
+//                               ),
+//                               child: Padding(
+//                                 padding: const EdgeInsets.all(4),
+//                                 key: Key(
+//                                     "desktopSettingsCurrencySelect_${currenciesWithoutSelected[index]}"),
+//                                 child: Padding(
+//                                   padding: const EdgeInsets.symmetric(
+//                                       horizontal: 32),
+//                                   child: RoundedContainer(
+//                                     padding: const EdgeInsets.all(0),
+//                                     color: currenciesWithoutSelected[index] ==
+//                                             current
+//                                         ? Theme.of(context)
+//                                             .extension<StackColors>()!
+//                                             .currencyListItemBG
+//                                         : Theme.of(context)
+//                                             .extension<StackColors>()!
+//                                             .popupBG,
+//                                     child: RawMaterialButton(
+//                                       onPressed: () async {
+//                                         onTap(index);
+//                                       },
+//                                       shape: RoundedRectangleBorder(
+//                                         borderRadius: BorderRadius.circular(
+//                                           Constants.size.circularBorderRadius,
+//                                         ),
+//                                       ),
+//                                       child: Padding(
+//                                         padding: const EdgeInsets.all(12.0),
+//                                         child: Row(
+//                                           crossAxisAlignment:
+//                                               CrossAxisAlignment.start,
+//                                           children: [
+//                                             SizedBox(
+//                                               width: 20,
+//                                               height: 20,
+//                                               child: Radio(
+//                                                 activeColor: Theme.of(context)
+//                                                     .extension<StackColors>()!
+//                                                     .radioButtonIconEnabled,
+//                                                 materialTapTargetSize:
+//                                                     MaterialTapTargetSize
+//                                                         .shrinkWrap,
+//                                                 value: true,
+//                                                 groupValue:
+//                                                     currenciesWithoutSelected[
+//                                                             index] ==
+//                                                         current,
+//                                                 onChanged: (_) {
+//                                                   onTap(index);
+//                                                 },
+//                                               ),
+//                                             ),
+//                                             const SizedBox(
+//                                               width: 12,
+//                                             ),
+//                                             Column(
+//                                               crossAxisAlignment:
+//                                                   CrossAxisAlignment.start,
+//                                               children: [
+//                                                 Text(
+//                                                   currenciesWithoutSelected[
+//                                                       index],
+//                                                   key: (currenciesWithoutSelected[
+//                                                               index] ==
+//                                                           current)
+//                                                       ? const Key(
+//                                                           "desktopSettingsSelectedCurrencyText")
+//                                                       : null,
+//                                                   style:
+//                                                       STextStyles.largeMedium14(
+//                                                           context),
+//                                                 ),
+//                                                 const SizedBox(
+//                                                   height: 2,
+//                                                 ),
+//                                                 Text(
+//                                                   ref.watch(baseCurrenciesProvider
+//                                                               .select((value) =>
+//                                                                   value.map))[
+//                                                           currenciesWithoutSelected[
+//                                                               index]] ??
+//                                                       "",
+//                                                   key: (currenciesWithoutSelected[
+//                                                               index] ==
+//                                                           current)
+//                                                       ? const Key(
+//                                                           "desktopSelectedCurrencyTextDescription")
+//                                                       : null,
+//                                                   style:
+//                                                       STextStyles.itemSubtitle(
+//                                                           context),
+//                                                 ),
+//                                               ],
+//                                             ),
+//                                           ],
+//                                         ),
+//                                       ),
+//                                     ),
+//                                   ),
+//                                 ),
+//                               ),
+//                             );
+//                           },
+//                           childCount: currenciesWithoutSelected.length,
+//                         ),
+//                       ),
+//                     ],
+//                   );
+//                 },
+//               ),
+//             ),
+//           ),
+//           const Spacer(),
+//           Padding(
+//             padding: const EdgeInsets.all(32),
+//             child: Row(
+//               children: [
+//                 Expanded(
+//                   child: SecondaryButton(
+//                     label: "Cancel",
+//                     onPressed: () {
+//                       Navigator.of(context).pop();
+//                     },
+//                   ),
+//                 ),
+//                 const SizedBox(
+//                   width: 16,
+//                 ),
+//                 Expanded(
+//                   child: PrimaryButton(
+//                     label: "Save Changes",
+//                     onPressed: () {},
+//                   ),
+//                 )
+//               ],
+//             ),
+//           ),
+//         ],
+//       ),
+//     );
+//   }
+// }
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index b8ce76d25..cf51940e0 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -2,12 +2,14 @@ import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/currency_view.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import 'currency_dialog.dart';
+import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
 
 class CurrencySettings extends ConsumerStatefulWidget {
   const CurrencySettings({Key? key}) : super(key: key);
@@ -87,12 +89,44 @@ class NewPasswordButton extends ConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     Future<void> chooseCurrency() async {
+      // await showDialog<dynamic>(
+      //   context: context,
+      //   useSafeArea: false,
+      //   barrierDismissible: true,
+      //   builder: (context) {
+      //     return CurrencyDialog();
+      //   },
+      // );
       await showDialog<dynamic>(
         context: context,
         useSafeArea: false,
         barrierDismissible: true,
         builder: (context) {
-          return CurrencyDialog();
+          return DesktopDialog(
+            maxHeight: 800,
+            maxWidth: 600,
+            child: Column(
+              children: [
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.all(32),
+                      child: Text(
+                        "Select currency",
+                        style: STextStyles.desktopH3(context),
+                        textAlign: TextAlign.center,
+                      ),
+                    ),
+                    const DesktopDialogCloseButton(),
+                  ],
+                ),
+                const Expanded(
+                  child: BaseCurrencySettingsView(),
+                ),
+              ],
+            ),
+          );
         },
       );
     }

From 66ead82462e508b2645a44d3d900d37524604730 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 3 Nov 2022 12:26:24 -0600
Subject: [PATCH 121/426] node settings desktop stuff and some code cleanup

---
 .../currency_settings/currency_dialog.dart    | 371 ------------------
 .../currency_settings/currency_settings.dart  |  92 +++--
 .../language_settings/language_settings.dart  |  26 +-
 .../home/settings_menu/nodes_settings.dart    | 153 ++++----
 4 files changed, 140 insertions(+), 502 deletions(-)
 delete mode 100644 lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart

diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
deleted file mode 100644
index 602589cea..000000000
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
+++ /dev/null
@@ -1,371 +0,0 @@
-// import 'package:flutter/material.dart';
-// import 'package:flutter_riverpod/flutter_riverpod.dart';
-// import 'package:flutter_svg/svg.dart';
-// import 'package:stackwallet/providers/global/base_currencies_provider.dart';
-// import 'package:stackwallet/providers/global/prefs_provider.dart';
-// import 'package:stackwallet/utilities/assets.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/desktop/desktop_dialog.dart';
-// import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
-// import 'package:stackwallet/widgets/desktop/primary_button.dart';
-// import 'package:stackwallet/widgets/desktop/secondary_button.dart';
-// import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
-// import 'package:stackwallet/widgets/rounded_container.dart';
-// import 'package:stackwallet/widgets/stack_text_field.dart';
-// import 'package:stackwallet/widgets/textfield_icon_button.dart';
-//
-// class CurrencyDialog extends ConsumerStatefulWidget {
-//   const CurrencyDialog({Key? key}) : super(key: key);
-//
-//   @override
-//   ConsumerState<CurrencyDialog> createState() => _CurrencyDialog();
-// }
-//
-// class _CurrencyDialog extends ConsumerState<CurrencyDialog> {
-//   late String current;
-//   late List<String> currenciesWithoutSelected;
-//
-//   late final TextEditingController searchCurrencyController;
-//
-//   late final FocusNode searchCurrencyFocusNode;
-//
-//   void onTap(int index) {
-//     if (currenciesWithoutSelected[index] == current || current.isEmpty) {
-//       // ignore if already selected currency
-//       return;
-//     }
-//     current = currenciesWithoutSelected[index];
-//     currenciesWithoutSelected.remove(current);
-//     currenciesWithoutSelected.insert(0, current);
-//     ref.read(prefsChangeNotifierProvider).currency = current;
-//   }
-//
-//   BorderRadius? _borderRadius(int index) {
-//     if (index == 0 && currenciesWithoutSelected.length == 1) {
-//       return BorderRadius.circular(
-//         Constants.size.circularBorderRadius,
-//       );
-//     } else if (index == 0) {
-//       return BorderRadius.vertical(
-//         top: Radius.circular(
-//           Constants.size.circularBorderRadius,
-//         ),
-//       );
-//     } else if (index == currenciesWithoutSelected.length - 1) {
-//       return BorderRadius.vertical(
-//         bottom: Radius.circular(
-//           Constants.size.circularBorderRadius,
-//         ),
-//       );
-//     }
-//     return null;
-//   }
-//
-//   String filter = "";
-//
-//   List<String> _filtered() {
-//     final currencyMap = ref.read(baseCurrenciesProvider).map;
-//     return currenciesWithoutSelected.where((element) {
-//       return element.toLowerCase().contains(filter.toLowerCase()) ||
-//           (currencyMap[element]?.toLowerCase().contains(filter.toLowerCase()) ??
-//               false);
-//     }).toList();
-//   }
-//
-//   @override
-//   void initState() {
-//     searchCurrencyController = TextEditingController();
-//
-//     searchCurrencyFocusNode = FocusNode();
-//
-//     super.initState();
-//   }
-//
-//   @override
-//   void dispose() {
-//     searchCurrencyController.dispose();
-//
-//     searchCurrencyFocusNode.dispose();
-//
-//     super.dispose();
-//   }
-//
-//   @override
-//   Widget build(BuildContext context) {
-//     current = ref
-//         .watch(prefsChangeNotifierProvider.select((value) => value.currency));
-//
-//     currenciesWithoutSelected = ref
-//         .watch(baseCurrenciesProvider.select((value) => value.map))
-//         .keys
-//         .toList();
-//     if (current.isNotEmpty) {
-//       currenciesWithoutSelected.remove(current);
-//       currenciesWithoutSelected.insert(0, current);
-//     }
-//     currenciesWithoutSelected = _filtered();
-//
-//     return DesktopDialog(
-//       maxHeight: 800,
-//       maxWidth: 600,
-//       child: Column(
-//         children: [
-//           Row(
-//             mainAxisAlignment: MainAxisAlignment.spaceBetween,
-//             children: [
-//               Padding(
-//                 padding: const EdgeInsets.all(32),
-//                 child: Text(
-//                   "Select currency",
-//                   style: STextStyles.desktopH3(context),
-//                   textAlign: TextAlign.center,
-//                 ),
-//               ),
-//               const DesktopDialogCloseButton(),
-//             ],
-//           ),
-//           Expanded(
-//             flex: 24,
-//             child: NestedScrollView(
-//               floatHeaderSlivers: true,
-//               headerSliverBuilder: (context, innerBoxIsScrolled) {
-//                 return [
-//                   SliverOverlapAbsorber(
-//                     handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
-//                         context),
-//                     sliver: SliverToBoxAdapter(
-//                       child: Padding(
-//                         padding: const EdgeInsets.symmetric(
-//                             vertical: 16, horizontal: 32),
-//                         child: Column(
-//                           children: [
-//                             Padding(
-//                               padding: const EdgeInsets.only(bottom: 16),
-//                               child: ClipRRect(
-//                                 borderRadius: BorderRadius.circular(
-//                                   Constants.size.circularBorderRadius,
-//                                 ),
-//                                 child: TextField(
-//                                   autocorrect: Util.isDesktop ? false : true,
-//                                   enableSuggestions:
-//                                       Util.isDesktop ? false : true,
-//                                   controller: searchCurrencyController,
-//                                   focusNode: searchCurrencyFocusNode,
-//                                   onChanged: (newString) {
-//                                     setState(() => filter = newString);
-//                                   },
-//                                   style: STextStyles.field(context),
-//                                   decoration: standardInputDecoration(
-//                                     "Search",
-//                                     searchCurrencyFocusNode,
-//                                     context,
-//                                   ).copyWith(
-//                                     prefixIcon: Padding(
-//                                       padding: const EdgeInsets.symmetric(
-//                                         horizontal: 10,
-//                                         vertical: 16,
-//                                       ),
-//                                       child: SvgPicture.asset(
-//                                         Assets.svg.search,
-//                                         width: 16,
-//                                         height: 16,
-//                                       ),
-//                                     ),
-//                                     suffixIcon: searchCurrencyController
-//                                             .text.isNotEmpty
-//                                         ? Padding(
-//                                             padding:
-//                                                 const EdgeInsets.only(right: 0),
-//                                             child: UnconstrainedBox(
-//                                               child: Row(
-//                                                 children: [
-//                                                   TextFieldIconButton(
-//                                                     child: const XIcon(),
-//                                                     onTap: () async {
-//                                                       setState(() {
-//                                                         searchCurrencyController
-//                                                             .text = "";
-//                                                         filter = "";
-//                                                       });
-//                                                     },
-//                                                   ),
-//                                                 ],
-//                                               ),
-//                                             ),
-//                                           )
-//                                         : null,
-//                                   ),
-//                                 ),
-//                               ),
-//                             ),
-//                           ],
-//                         ),
-//                       ),
-//                     ),
-//                   ),
-//                 ];
-//               },
-//               body: Builder(
-//                 builder: (context) {
-//                   return CustomScrollView(
-//                     slivers: [
-//                       SliverOverlapInjector(
-//                         handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
-//                           context,
-//                         ),
-//                       ),
-//                       SliverList(
-//                         delegate: SliverChildBuilderDelegate(
-//                           (context, index) {
-//                             return Container(
-//                               decoration: BoxDecoration(
-//                                 color: Theme.of(context)
-//                                     .extension<StackColors>()!
-//                                     .popupBG,
-//                                 borderRadius: _borderRadius(index),
-//                               ),
-//                               child: Padding(
-//                                 padding: const EdgeInsets.all(4),
-//                                 key: Key(
-//                                     "desktopSettingsCurrencySelect_${currenciesWithoutSelected[index]}"),
-//                                 child: Padding(
-//                                   padding: const EdgeInsets.symmetric(
-//                                       horizontal: 32),
-//                                   child: RoundedContainer(
-//                                     padding: const EdgeInsets.all(0),
-//                                     color: currenciesWithoutSelected[index] ==
-//                                             current
-//                                         ? Theme.of(context)
-//                                             .extension<StackColors>()!
-//                                             .currencyListItemBG
-//                                         : Theme.of(context)
-//                                             .extension<StackColors>()!
-//                                             .popupBG,
-//                                     child: RawMaterialButton(
-//                                       onPressed: () async {
-//                                         onTap(index);
-//                                       },
-//                                       shape: RoundedRectangleBorder(
-//                                         borderRadius: BorderRadius.circular(
-//                                           Constants.size.circularBorderRadius,
-//                                         ),
-//                                       ),
-//                                       child: Padding(
-//                                         padding: const EdgeInsets.all(12.0),
-//                                         child: Row(
-//                                           crossAxisAlignment:
-//                                               CrossAxisAlignment.start,
-//                                           children: [
-//                                             SizedBox(
-//                                               width: 20,
-//                                               height: 20,
-//                                               child: Radio(
-//                                                 activeColor: Theme.of(context)
-//                                                     .extension<StackColors>()!
-//                                                     .radioButtonIconEnabled,
-//                                                 materialTapTargetSize:
-//                                                     MaterialTapTargetSize
-//                                                         .shrinkWrap,
-//                                                 value: true,
-//                                                 groupValue:
-//                                                     currenciesWithoutSelected[
-//                                                             index] ==
-//                                                         current,
-//                                                 onChanged: (_) {
-//                                                   onTap(index);
-//                                                 },
-//                                               ),
-//                                             ),
-//                                             const SizedBox(
-//                                               width: 12,
-//                                             ),
-//                                             Column(
-//                                               crossAxisAlignment:
-//                                                   CrossAxisAlignment.start,
-//                                               children: [
-//                                                 Text(
-//                                                   currenciesWithoutSelected[
-//                                                       index],
-//                                                   key: (currenciesWithoutSelected[
-//                                                               index] ==
-//                                                           current)
-//                                                       ? const Key(
-//                                                           "desktopSettingsSelectedCurrencyText")
-//                                                       : null,
-//                                                   style:
-//                                                       STextStyles.largeMedium14(
-//                                                           context),
-//                                                 ),
-//                                                 const SizedBox(
-//                                                   height: 2,
-//                                                 ),
-//                                                 Text(
-//                                                   ref.watch(baseCurrenciesProvider
-//                                                               .select((value) =>
-//                                                                   value.map))[
-//                                                           currenciesWithoutSelected[
-//                                                               index]] ??
-//                                                       "",
-//                                                   key: (currenciesWithoutSelected[
-//                                                               index] ==
-//                                                           current)
-//                                                       ? const Key(
-//                                                           "desktopSelectedCurrencyTextDescription")
-//                                                       : null,
-//                                                   style:
-//                                                       STextStyles.itemSubtitle(
-//                                                           context),
-//                                                 ),
-//                                               ],
-//                                             ),
-//                                           ],
-//                                         ),
-//                                       ),
-//                                     ),
-//                                   ),
-//                                 ),
-//                               ),
-//                             );
-//                           },
-//                           childCount: currenciesWithoutSelected.length,
-//                         ),
-//                       ),
-//                     ],
-//                   );
-//                 },
-//               ),
-//             ),
-//           ),
-//           const Spacer(),
-//           Padding(
-//             padding: const EdgeInsets.all(32),
-//             child: Row(
-//               children: [
-//                 Expanded(
-//                   child: SecondaryButton(
-//                     label: "Cancel",
-//                     onPressed: () {
-//                       Navigator.of(context).pop();
-//                     },
-//                   ),
-//                 ),
-//                 const SizedBox(
-//                   width: 16,
-//                 ),
-//                 Expanded(
-//                   child: PrimaryButton(
-//                     label: "Save Changes",
-//                     onPressed: () {},
-//                   ),
-//                 )
-//               ],
-//             ),
-//           ),
-//         ],
-//       ),
-//     );
-//   }
-// }
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index cf51940e0..dab613f63 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -1,5 +1,4 @@
 import 'package:flutter/material.dart';
-import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/currency_view.dart';
@@ -7,10 +6,9 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
-
 class CurrencySettings extends ConsumerStatefulWidget {
   const CurrencySettings({Key? key}) : super(key: key);
 
@@ -86,51 +84,51 @@ class NewPasswordButton extends ConsumerWidget {
   const NewPasswordButton({
     Key? key,
   }) : super(key: key);
+  Future<void> chooseCurrency(BuildContext context) async {
+    // await showDialog<dynamic>(
+    //   context: context,
+    //   useSafeArea: false,
+    //   barrierDismissible: true,
+    //   builder: (context) {
+    //     return CurrencyDialog();
+    //   },
+    // );
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) {
+        return DesktopDialog(
+          maxHeight: 800,
+          maxWidth: 600,
+          child: Column(
+            children: [
+              Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Padding(
+                    padding: const EdgeInsets.all(32),
+                    child: Text(
+                      "Select currency",
+                      style: STextStyles.desktopH3(context),
+                      textAlign: TextAlign.center,
+                    ),
+                  ),
+                  const DesktopDialogCloseButton(),
+                ],
+              ),
+              const Expanded(
+                child: BaseCurrencySettingsView(),
+              ),
+            ],
+          ),
+        );
+      },
+    );
+  }
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    Future<void> chooseCurrency() async {
-      // await showDialog<dynamic>(
-      //   context: context,
-      //   useSafeArea: false,
-      //   barrierDismissible: true,
-      //   builder: (context) {
-      //     return CurrencyDialog();
-      //   },
-      // );
-      await showDialog<dynamic>(
-        context: context,
-        useSafeArea: false,
-        barrierDismissible: true,
-        builder: (context) {
-          return DesktopDialog(
-            maxHeight: 800,
-            maxWidth: 600,
-            child: Column(
-              children: [
-                Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  children: [
-                    Padding(
-                      padding: const EdgeInsets.all(32),
-                      child: Text(
-                        "Select currency",
-                        style: STextStyles.desktopH3(context),
-                        textAlign: TextAlign.center,
-                      ),
-                    ),
-                    const DesktopDialogCloseButton(),
-                  ],
-                ),
-                const Expanded(
-                  child: BaseCurrencySettingsView(),
-                ),
-              ],
-            ),
-          );
-        },
-      );
-    }
-
     return SizedBox(
       width: 200,
       height: 48,
@@ -139,7 +137,7 @@ class NewPasswordButton extends ConsumerWidget {
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {
-          chooseCurrency();
+          chooseCurrency(context);
         },
         child: Text(
           "Change currency",
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
index 97b807b3b..0f66d7dd5 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
@@ -1,5 +1,4 @@
 import 'package:flutter/material.dart';
-import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart';
@@ -86,19 +85,20 @@ class ChangeLanguageButton extends ConsumerWidget {
   const ChangeLanguageButton({
     Key? key,
   }) : super(key: key);
+
+  Future<void> chooseLanguage(BuildContext context) async {
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) {
+        return const LanguageDialog();
+      },
+    );
+  }
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    Future<void> chooseLanguage() async {
-      await showDialog<dynamic>(
-        context: context,
-        useSafeArea: false,
-        barrierDismissible: true,
-        builder: (context) {
-          return LanguageDialog();
-        },
-      );
-    }
-
     return SizedBox(
       width: 200,
       height: 48,
@@ -107,7 +107,7 @@ class ChangeLanguageButton extends ConsumerWidget {
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
         onPressed: () {
-          chooseLanguage();
+          chooseLanguage(context);
         },
         child: Text(
           "Change language",
diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index 5f1e70143..abba6cccc 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -1,5 +1,4 @@
 import 'package:flutter/material.dart';
-import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
@@ -9,10 +8,10 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
-
-import '../../../utilities/util.dart';
-import '../../../widgets/stack_text_field.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
 
 class NodesSettings extends ConsumerStatefulWidget {
   const NodesSettings({Key? key}) : super(key: key);
@@ -62,6 +61,7 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
 
     debugPrint("BUILD: $runtimeType");
     return Column(
+      mainAxisSize: MainAxisSize.min,
       children: [
         Padding(
           padding: const EdgeInsets.only(
@@ -70,6 +70,7 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
           child: RoundedWhiteContainer(
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
+              mainAxisSize: MainAxisSize.min,
               children: [
                 SvgPicture.asset(
                   Assets.svg.circleNode,
@@ -78,6 +79,7 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.stretch,
+                  mainAxisSize: MainAxisSize.min,
                   children: [
                     Padding(
                       padding: const EdgeInsets.all(10),
@@ -137,84 +139,93 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                 ),
                 Padding(
                   padding: const EdgeInsets.all(10.0),
-                  child: SingleChildScrollView(
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        ...coins.map(
-                          (coin) {
-                            final count = ref
-                                .watch(nodeServiceChangeNotifierProvider
-                                    .select((value) => value.getNodesFor(coin)))
-                                .length;
+                  child: RoundedWhiteContainer(
+                    padding: const EdgeInsets.all(0),
+                    borderColor:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    child: ListView.separated(
+                      primary: false,
+                      shrinkWrap: true,
+                      itemBuilder: (context, index) {
+                        final coin = coins[index];
+                        final count = ref
+                            .watch(nodeServiceChangeNotifierProvider
+                                .select((value) => value.getNodesFor(coin)))
+                            .length;
 
-                            return Padding(
-                              padding: const EdgeInsets.all(0),
-                              child: RawMaterialButton(
-                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
-                                  ),
+                        return Padding(
+                          padding: const EdgeInsets.all(0),
+                          child: RawMaterialButton(
+                            // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                            shape: RoundedRectangleBorder(
+                              borderRadius: BorderRadius.circular(
+                                Constants.size.circularBorderRadius,
+                              ),
+                            ),
+                            materialTapTargetSize:
+                                MaterialTapTargetSize.shrinkWrap,
+                            onPressed: () {
+                              showDialog<void>(
+                                context: context,
+                                builder: (context) => CoinNodesView(
+                                  coin: coin,
                                 ),
-                                materialTapTargetSize:
-                                    MaterialTapTargetSize.shrinkWrap,
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                    CoinNodesView.routeName,
-                                    arguments: coin,
-                                  );
-                                },
-                                child: Padding(
-                                  padding: const EdgeInsets.all(
-                                    12.0,
-                                  ),
-                                  child: Row(
+                              );
+                            },
+                            child: Padding(
+                              padding: const EdgeInsets.all(
+                                12.0,
+                              ),
+                              child: Row(
+                                children: [
+                                  Row(
                                     children: [
-                                      Row(
+                                      SvgPicture.asset(
+                                        Assets.svg.iconFor(coin: coin),
+                                        width: 24,
+                                        height: 24,
+                                      ),
+                                      const SizedBox(
+                                        width: 12,
+                                      ),
+                                      Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
                                         children: [
-                                          SvgPicture.asset(
-                                            Assets.svg.iconFor(coin: coin),
-                                            width: 24,
-                                            height: 24,
+                                          Text(
+                                            "${coin.prettyName} nodes",
+                                            style: STextStyles.titleBold12(
+                                                context),
                                           ),
-                                          const SizedBox(
-                                            width: 12,
-                                          ),
-                                          Column(
-                                            crossAxisAlignment:
-                                                CrossAxisAlignment.start,
-                                            children: [
-                                              Text(
-                                                "${coin.prettyName} nodes",
-                                                style: STextStyles.titleBold12(
-                                                    context),
-                                              ),
-                                              Text(
-                                                count > 1
-                                                    ? "$count nodes"
-                                                    : "Default",
-                                                style:
-                                                    STextStyles.label(context),
-                                              ),
-                                            ],
+                                          Text(
+                                            count > 1
+                                                ? "$count nodes"
+                                                : "Default",
+                                            style: STextStyles.label(context),
                                           ),
                                         ],
                                       ),
-                                      Expanded(
-                                        child: SvgPicture.asset(
-                                          Assets.svg.chevronRight,
-                                          alignment: Alignment.centerRight,
-                                        ),
-                                      ),
                                     ],
                                   ),
-                                ),
+                                  Expanded(
+                                    child: SvgPicture.asset(
+                                      Assets.svg.chevronRight,
+                                      alignment: Alignment.centerRight,
+                                    ),
+                                  ),
+                                ],
                               ),
-                            );
-                          },
-                        ),
-                      ],
+                            ),
+                          ),
+                        );
+                      },
+                      separatorBuilder: (context, index) => Container(
+                        height: 1,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .background,
+                      ),
+                      itemCount: coins.length,
                     ),
                   ),
                 ),

From e5f69700f7fcbaa4d380d1e8cf0f3ba67c6167cf Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 3 Nov 2022 14:28:24 -0600
Subject: [PATCH 122/426] conditional for desktop syncing pref settings

---
 .../syncing_options_view.dart                 | 701 +++++++++---------
 .../syncing_preferences_settings.dart         |   9 +
 2 files changed, 345 insertions(+), 365 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart
index bada67353..a65a03a87 100644
--- a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart
+++ b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart
@@ -6,6 +6,8 @@ import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/sync_type_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/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
@@ -16,383 +18,352 @@ class SyncingOptionsView extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Syncing",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    children: [
-                      RoundedWhiteContainer(
-                        padding: const EdgeInsets.all(0),
-                        child: Column(
-                          crossAxisAlignment: CrossAxisAlignment.stretch,
-                          children: [
-                            Padding(
-                              padding: const EdgeInsets.all(4),
-                              child: RawMaterialButton(
-                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                materialTapTargetSize:
-                                    MaterialTapTargetSize.shrinkWrap,
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
-                                  ),
-                                ),
-                                onPressed: () {
-                                  final state = ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .syncType;
-                                  if (state != SyncingType.currentWalletOnly) {
-                                    ref
-                                            .read(prefsChangeNotifierProvider)
-                                            .syncType =
-                                        SyncingType.currentWalletOnly;
+    return ConditionalParent(
+      condition: !Util.isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () async {
+                Navigator.of(context).pop();
+              },
+            ),
+            title: Text(
+              "Syncing",
+              style: STextStyles.navBarTitle(context),
+            ),
+          ),
+          body: Padding(
+            padding: const EdgeInsets.all(16),
+            child: LayoutBuilder(
+              builder: (context, constraints) {
+                return SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight,
+                    ),
+                    child: IntrinsicHeight(
+                      child: child,
+                    ),
+                  ),
+                );
+              },
+            ),
+          ),
+        );
+      },
+      child: Padding(
+        padding: const EdgeInsets.symmetric(horizontal: 10),
+        child: Column(
+          children: [
+            RoundedWhiteContainer(
+              padding: const EdgeInsets.all(0),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: [
+                  Padding(
+                    padding: const EdgeInsets.all(4),
+                    child: RawMaterialButton(
+                      // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                      ),
+                      onPressed: () {
+                        final state =
+                            ref.read(prefsChangeNotifierProvider).syncType;
+                        if (state != SyncingType.currentWalletOnly) {
+                          ref.read(prefsChangeNotifierProvider).syncType =
+                              SyncingType.currentWalletOnly;
 
-                                    // disable auto sync on all wallets that aren't active/current
-                                    ref
-                                        .read(walletsChangeNotifierProvider)
-                                        .managers
-                                        .forEach((e) {
-                                      if (!e.isActiveWallet) {
-                                        e.shouldAutoSync = false;
-                                      }
-                                    });
-                                  }
-                                },
-                                child: Container(
-                                  color: Colors.transparent,
-                                  child: Padding(
-                                    padding: const EdgeInsets.all(8.0),
-                                    child: Row(
-                                      crossAxisAlignment:
-                                          CrossAxisAlignment.start,
-                                      children: [
-                                        SizedBox(
-                                          width: 20,
-                                          height: 20,
-                                          child: Radio(
-                                            activeColor: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .radioButtonIconEnabled,
-                                            value:
-                                                SyncingType.currentWalletOnly,
-                                            groupValue: ref.watch(
-                                              prefsChangeNotifierProvider
-                                                  .select((value) =>
-                                                      value.syncType),
-                                            ),
-                                            onChanged: (value) {
-                                              if (value is SyncingType) {
-                                                ref
-                                                    .read(
-                                                        prefsChangeNotifierProvider)
-                                                    .syncType = value;
-                                              }
-                                            },
-                                          ),
-                                        ),
-                                        const SizedBox(
-                                          width: 12,
-                                        ),
-                                        Flexible(
-                                          child: Column(
-                                            crossAxisAlignment:
-                                                CrossAxisAlignment.start,
-                                            children: [
-                                              Text(
-                                                "Sync only currently open wallet",
-                                                style: STextStyles.titleBold12(
-                                                    context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                              Text(
-                                                "Sync only the wallet that you are using",
-                                                style: STextStyles.itemSubtitle(
-                                                    context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                            ],
-                                          ),
-                                        ),
-                                      ],
-                                    ),
+                          // disable auto sync on all wallets that aren't active/current
+                          ref
+                              .read(walletsChangeNotifierProvider)
+                              .managers
+                              .forEach((e) {
+                            if (!e.isActiveWallet) {
+                              e.shouldAutoSync = false;
+                            }
+                          });
+                        }
+                      },
+                      child: Container(
+                        color: Colors.transparent,
+                        child: Padding(
+                          padding: const EdgeInsets.all(8.0),
+                          child: Row(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              SizedBox(
+                                width: 20,
+                                height: 20,
+                                child: Radio(
+                                  activeColor: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .radioButtonIconEnabled,
+                                  value: SyncingType.currentWalletOnly,
+                                  groupValue: ref.watch(
+                                    prefsChangeNotifierProvider
+                                        .select((value) => value.syncType),
                                   ),
+                                  onChanged: (value) {
+                                    if (value is SyncingType) {
+                                      ref
+                                          .read(prefsChangeNotifierProvider)
+                                          .syncType = value;
+                                    }
+                                  },
                                 ),
                               ),
-                            ),
-                            Padding(
-                              padding: const EdgeInsets.all(4.0),
-                              child: RawMaterialButton(
-                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                materialTapTargetSize:
-                                    MaterialTapTargetSize.shrinkWrap,
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
-                                  ),
-                                ),
-                                onPressed: () {
-                                  final state = ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .syncType;
-                                  if (state !=
-                                      SyncingType.allWalletsOnStartup) {
-                                    ref
-                                            .read(prefsChangeNotifierProvider)
-                                            .syncType =
-                                        SyncingType.allWalletsOnStartup;
-
-                                    // enable auto sync on all wallets
-                                    ref
-                                        .read(walletsChangeNotifierProvider)
-                                        .managers
-                                        .forEach(
-                                            (e) => e.shouldAutoSync = true);
-                                  }
-                                },
-                                child: Container(
-                                  color: Colors.transparent,
-                                  child: Padding(
-                                    padding: const EdgeInsets.all(8.0),
-                                    child: Row(
-                                      crossAxisAlignment:
-                                          CrossAxisAlignment.start,
-                                      children: [
-                                        SizedBox(
-                                          width: 20,
-                                          height: 20,
-                                          child: Radio(
-                                            activeColor: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .radioButtonIconEnabled,
-                                            value:
-                                                SyncingType.allWalletsOnStartup,
-                                            groupValue: ref.watch(
-                                              prefsChangeNotifierProvider
-                                                  .select((value) =>
-                                                      value.syncType),
-                                            ),
-                                            onChanged: (value) {
-                                              if (value is SyncingType) {
-                                                ref
-                                                    .read(
-                                                        prefsChangeNotifierProvider)
-                                                    .syncType = value;
-                                              }
-                                            },
-                                          ),
-                                        ),
-                                        const SizedBox(
-                                          width: 12,
-                                        ),
-                                        Flexible(
-                                          child: Column(
-                                            crossAxisAlignment:
-                                                CrossAxisAlignment.start,
-                                            children: [
-                                              Text(
-                                                "Sync all wallets at startup",
-                                                style: STextStyles.titleBold12(
-                                                    context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                              Text(
-                                                "All of your wallets will start syncing when you open the app",
-                                                style: STextStyles.itemSubtitle(
-                                                    context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                            ],
-                                          ),
-                                        ),
-                                      ],
-                                    ),
-                                  ),
-                                ),
-                              ),
-                            ),
-                            Padding(
-                              padding: const EdgeInsets.all(4),
-                              child: RawMaterialButton(
-                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                materialTapTargetSize:
-                                    MaterialTapTargetSize.shrinkWrap,
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
-                                  ),
-                                ),
-                                onPressed: () {
-                                  final state = ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .syncType;
-                                  if (state !=
-                                      SyncingType.selectedWalletsAtStartup) {
-                                    ref
-                                            .read(prefsChangeNotifierProvider)
-                                            .syncType =
-                                        SyncingType.selectedWalletsAtStartup;
-
-                                    final ids = ref
-                                        .read(prefsChangeNotifierProvider)
-                                        .walletIdsSyncOnStartup;
-
-                                    // enable auto sync on selected wallets only
-                                    ref
-                                        .read(walletsChangeNotifierProvider)
-                                        .managers
-                                        .forEach((e) => e.shouldAutoSync =
-                                            ids.contains(e.walletId));
-                                  }
-                                },
-                                child: Container(
-                                  color: Colors.transparent,
-                                  child: Padding(
-                                    padding: const EdgeInsets.all(8),
-                                    child: Row(
-                                      crossAxisAlignment:
-                                          CrossAxisAlignment.start,
-                                      children: [
-                                        SizedBox(
-                                          width: 20,
-                                          height: 20,
-                                          child: Radio(
-                                            activeColor: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .radioButtonIconEnabled,
-                                            value: SyncingType
-                                                .selectedWalletsAtStartup,
-                                            groupValue: ref.watch(
-                                              prefsChangeNotifierProvider
-                                                  .select((value) =>
-                                                      value.syncType),
-                                            ),
-                                            onChanged: (value) {
-                                              if (value is SyncingType) {
-                                                ref
-                                                    .read(
-                                                        prefsChangeNotifierProvider)
-                                                    .syncType = value;
-                                              }
-                                            },
-                                          ),
-                                        ),
-                                        const SizedBox(
-                                          width: 12,
-                                        ),
-                                        Flexible(
-                                          child: Column(
-                                            crossAxisAlignment:
-                                                CrossAxisAlignment.start,
-                                            children: [
-                                              Text(
-                                                "Sync only selected wallets at startup",
-                                                style: STextStyles.titleBold12(
-                                                    context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                              Text(
-                                                "Only the wallets you select will start syncing when you open the app",
-                                                style: STextStyles.itemSubtitle(
-                                                    context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                            ],
-                                          ),
-                                        ),
-                                      ],
-                                    ),
-                                  ),
-                                ),
-                              ),
-                            ),
-                            if (ref.watch(prefsChangeNotifierProvider
-                                    .select((value) => value.syncType)) !=
-                                SyncingType.selectedWalletsAtStartup)
                               const SizedBox(
-                                height: 12,
+                                width: 12,
                               ),
-                            if (ref.watch(prefsChangeNotifierProvider
-                                    .select((value) => value.syncType)) ==
-                                SyncingType.selectedWalletsAtStartup)
-                              Container(
-                                color: Colors.transparent,
-                                child: Padding(
-                                  padding: const EdgeInsets.only(
-                                    left: 12.0,
-                                    right: 12,
-                                    bottom: 12,
-                                  ),
-                                  child: Row(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.start,
-                                    children: [
-                                      const SizedBox(
-                                        width: 12 + 20,
-                                        height: 12,
-                                      ),
-                                      Flexible(
-                                        child: RawMaterialButton(
-                                          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                          materialTapTargetSize:
-                                              MaterialTapTargetSize.shrinkWrap,
-                                          shape: RoundedRectangleBorder(
-                                            borderRadius: BorderRadius.circular(
-                                              Constants
-                                                  .size.circularBorderRadius,
-                                            ),
-                                          ),
-                                          onPressed: () {
-                                            Navigator.of(context).pushNamed(
-                                                WalletSyncingOptionsView
-                                                    .routeName);
-                                          },
-                                          child: Column(
-                                            crossAxisAlignment:
-                                                CrossAxisAlignment.start,
-                                            children: [
-                                              Text(
-                                                "Select wallets...",
-                                                style:
-                                                    STextStyles.link2(context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                            ],
-                                          ),
-                                        ),
-                                      ),
-                                    ],
-                                  ),
+                              Flexible(
+                                child: Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Sync only currently open wallet",
+                                      style: STextStyles.titleBold12(context),
+                                      textAlign: TextAlign.left,
+                                    ),
+                                    Text(
+                                      "Sync only the wallet that you are using",
+                                      style: STextStyles.itemSubtitle(context),
+                                      textAlign: TextAlign.left,
+                                    ),
+                                  ],
                                 ),
                               ),
+                            ],
+                          ),
+                        ),
+                      ),
+                    ),
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.all(4.0),
+                    child: RawMaterialButton(
+                      // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                      ),
+                      onPressed: () {
+                        final state =
+                            ref.read(prefsChangeNotifierProvider).syncType;
+                        if (state != SyncingType.allWalletsOnStartup) {
+                          ref.read(prefsChangeNotifierProvider).syncType =
+                              SyncingType.allWalletsOnStartup;
+
+                          // enable auto sync on all wallets
+                          ref
+                              .read(walletsChangeNotifierProvider)
+                              .managers
+                              .forEach((e) => e.shouldAutoSync = true);
+                        }
+                      },
+                      child: Container(
+                        color: Colors.transparent,
+                        child: Padding(
+                          padding: const EdgeInsets.all(8.0),
+                          child: Row(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              SizedBox(
+                                width: 20,
+                                height: 20,
+                                child: Radio(
+                                  activeColor: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .radioButtonIconEnabled,
+                                  value: SyncingType.allWalletsOnStartup,
+                                  groupValue: ref.watch(
+                                    prefsChangeNotifierProvider
+                                        .select((value) => value.syncType),
+                                  ),
+                                  onChanged: (value) {
+                                    if (value is SyncingType) {
+                                      ref
+                                          .read(prefsChangeNotifierProvider)
+                                          .syncType = value;
+                                    }
+                                  },
+                                ),
+                              ),
+                              const SizedBox(
+                                width: 12,
+                              ),
+                              Flexible(
+                                child: Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Sync all wallets at startup",
+                                      style: STextStyles.titleBold12(context),
+                                      textAlign: TextAlign.left,
+                                    ),
+                                    Text(
+                                      "All of your wallets will start syncing when you open the app",
+                                      style: STextStyles.itemSubtitle(context),
+                                      textAlign: TextAlign.left,
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            ],
+                          ),
+                        ),
+                      ),
+                    ),
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.all(4),
+                    child: RawMaterialButton(
+                      // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                      ),
+                      onPressed: () {
+                        final state =
+                            ref.read(prefsChangeNotifierProvider).syncType;
+                        if (state != SyncingType.selectedWalletsAtStartup) {
+                          ref.read(prefsChangeNotifierProvider).syncType =
+                              SyncingType.selectedWalletsAtStartup;
+
+                          final ids = ref
+                              .read(prefsChangeNotifierProvider)
+                              .walletIdsSyncOnStartup;
+
+                          // enable auto sync on selected wallets only
+                          ref
+                              .read(walletsChangeNotifierProvider)
+                              .managers
+                              .forEach((e) =>
+                                  e.shouldAutoSync = ids.contains(e.walletId));
+                        }
+                      },
+                      child: Container(
+                        color: Colors.transparent,
+                        child: Padding(
+                          padding: const EdgeInsets.all(8),
+                          child: Row(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              SizedBox(
+                                width: 20,
+                                height: 20,
+                                child: Radio(
+                                  activeColor: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .radioButtonIconEnabled,
+                                  value: SyncingType.selectedWalletsAtStartup,
+                                  groupValue: ref.watch(
+                                    prefsChangeNotifierProvider
+                                        .select((value) => value.syncType),
+                                  ),
+                                  onChanged: (value) {
+                                    if (value is SyncingType) {
+                                      ref
+                                          .read(prefsChangeNotifierProvider)
+                                          .syncType = value;
+                                    }
+                                  },
+                                ),
+                              ),
+                              const SizedBox(
+                                width: 12,
+                              ),
+                              Flexible(
+                                child: Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Sync only selected wallets at startup",
+                                      style: STextStyles.titleBold12(context),
+                                      textAlign: TextAlign.left,
+                                    ),
+                                    Text(
+                                      "Only the wallets you select will start syncing when you open the app",
+                                      style: STextStyles.itemSubtitle(context),
+                                      textAlign: TextAlign.left,
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            ],
+                          ),
+                        ),
+                      ),
+                    ),
+                  ),
+                  if (ref.watch(prefsChangeNotifierProvider
+                          .select((value) => value.syncType)) !=
+                      SyncingType.selectedWalletsAtStartup)
+                    const SizedBox(
+                      height: 12,
+                    ),
+                  if (ref.watch(prefsChangeNotifierProvider
+                          .select((value) => value.syncType)) ==
+                      SyncingType.selectedWalletsAtStartup)
+                    Container(
+                      color: Colors.transparent,
+                      child: Padding(
+                        padding: const EdgeInsets.only(
+                          left: 12.0,
+                          right: 12,
+                          bottom: 12,
+                        ),
+                        child: Row(
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            const SizedBox(
+                              width: 12 + 20,
+                              height: 12,
+                            ),
+                            Flexible(
+                              child: RawMaterialButton(
+                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                                materialTapTargetSize:
+                                    MaterialTapTargetSize.shrinkWrap,
+                                shape: RoundedRectangleBorder(
+                                  borderRadius: BorderRadius.circular(
+                                    Constants.size.circularBorderRadius,
+                                  ),
+                                ),
+                                onPressed: () {
+                                  Navigator.of(context).pushNamed(
+                                      WalletSyncingOptionsView.routeName);
+                                },
+                                child: Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Select wallets...",
+                                      style: STextStyles.link2(context),
+                                      textAlign: TextAlign.left,
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            ),
                           ],
                         ),
                       ),
-                    ],
-                  ),
-                ),
+                    ),
+                ],
               ),
-            );
-          },
+            ),
+          ],
         ),
       ),
     );
diff --git a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
index 9b6c6c85c..7f6aac260 100644
--- a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
@@ -7,6 +7,8 @@ import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
+import '../../../pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart';
+
 class SyncingPreferencesSettings extends ConsumerStatefulWidget {
   const SyncingPreferencesSettings({Key? key}) : super(key: key);
 
@@ -62,6 +64,13 @@ class _SyncingPreferencesSettings
                     ),
                   ],
                 ),
+
+                ///TODO: ONLY SHOW SYNC OPTIONS ON BUTTON PRESS
+                Column(
+                  children: [
+                    SyncingOptionsView(),
+                  ],
+                ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
                   children: const [

From 563492d4e85c9557ccb1e7fe4d5a8fb524dfe823 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 3 Nov 2022 17:11:01 -0600
Subject: [PATCH 123/426] conditional and padding for wallet syncing options

---
 .../syncing_options_view.dart                 | 625 ++++++++++--------
 .../wallet_syncing_options_view.dart          |  69 +-
 2 files changed, 376 insertions(+), 318 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart
index a65a03a87..3681009a9 100644
--- a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart
+++ b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart
@@ -9,6 +9,8 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class SyncingOptionsView extends ConsumerWidget {
@@ -18,8 +20,9 @@ class SyncingOptionsView extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    final isDesktop = Util.isDesktop;
     return ConditionalParent(
-      condition: !Util.isDesktop,
+      condition: !isDesktop,
       builder: (child) {
         return Scaffold(
           backgroundColor:
@@ -54,317 +57,353 @@ class SyncingOptionsView extends ConsumerWidget {
           ),
         );
       },
-      child: Padding(
-        padding: const EdgeInsets.symmetric(horizontal: 10),
-        child: Column(
-          children: [
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: Column(
-                crossAxisAlignment: CrossAxisAlignment.stretch,
-                children: [
-                  Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: RawMaterialButton(
-                      // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                      shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
-                        ),
-                      ),
-                      onPressed: () {
-                        final state =
-                            ref.read(prefsChangeNotifierProvider).syncType;
-                        if (state != SyncingType.currentWalletOnly) {
-                          ref.read(prefsChangeNotifierProvider).syncType =
-                              SyncingType.currentWalletOnly;
-
-                          // disable auto sync on all wallets that aren't active/current
-                          ref
-                              .read(walletsChangeNotifierProvider)
-                              .managers
-                              .forEach((e) {
-                            if (!e.isActiveWallet) {
-                              e.shouldAutoSync = false;
-                            }
-                          });
-                        }
-                      },
-                      child: Container(
-                        color: Colors.transparent,
-                        child: Padding(
-                          padding: const EdgeInsets.all(8.0),
-                          child: Row(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              SizedBox(
-                                width: 20,
-                                height: 20,
-                                child: Radio(
-                                  activeColor: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .radioButtonIconEnabled,
-                                  value: SyncingType.currentWalletOnly,
-                                  groupValue: ref.watch(
-                                    prefsChangeNotifierProvider
-                                        .select((value) => value.syncType),
-                                  ),
-                                  onChanged: (value) {
-                                    if (value is SyncingType) {
-                                      ref
-                                          .read(prefsChangeNotifierProvider)
-                                          .syncType = value;
-                                    }
-                                  },
-                                ),
-                              ),
-                              const SizedBox(
-                                width: 12,
-                              ),
-                              Flexible(
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Sync only currently open wallet",
-                                      style: STextStyles.titleBold12(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    Text(
-                                      "Sync only the wallet that you are using",
-                                      style: STextStyles.itemSubtitle(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                  ],
-                                ),
-                              ),
-                            ],
-                          ),
-                        ),
+      child: Column(
+        children: [
+          RoundedWhiteContainer(
+            padding: const EdgeInsets.all(0),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.stretch,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.all(4),
+                  child: RawMaterialButton(
+                    // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
                       ),
                     ),
-                  ),
-                  Padding(
-                    padding: const EdgeInsets.all(4.0),
-                    child: RawMaterialButton(
-                      // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                      shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
-                        ),
-                      ),
-                      onPressed: () {
-                        final state =
-                            ref.read(prefsChangeNotifierProvider).syncType;
-                        if (state != SyncingType.allWalletsOnStartup) {
-                          ref.read(prefsChangeNotifierProvider).syncType =
-                              SyncingType.allWalletsOnStartup;
+                    onPressed: () {
+                      final state =
+                          ref.read(prefsChangeNotifierProvider).syncType;
+                      if (state != SyncingType.currentWalletOnly) {
+                        ref.read(prefsChangeNotifierProvider).syncType =
+                            SyncingType.currentWalletOnly;
 
-                          // enable auto sync on all wallets
-                          ref
-                              .read(walletsChangeNotifierProvider)
-                              .managers
-                              .forEach((e) => e.shouldAutoSync = true);
-                        }
-                      },
-                      child: Container(
-                        color: Colors.transparent,
-                        child: Padding(
-                          padding: const EdgeInsets.all(8.0),
-                          child: Row(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              SizedBox(
-                                width: 20,
-                                height: 20,
-                                child: Radio(
-                                  activeColor: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .radioButtonIconEnabled,
-                                  value: SyncingType.allWalletsOnStartup,
-                                  groupValue: ref.watch(
-                                    prefsChangeNotifierProvider
-                                        .select((value) => value.syncType),
-                                  ),
-                                  onChanged: (value) {
-                                    if (value is SyncingType) {
-                                      ref
-                                          .read(prefsChangeNotifierProvider)
-                                          .syncType = value;
-                                    }
-                                  },
-                                ),
-                              ),
-                              const SizedBox(
-                                width: 12,
-                              ),
-                              Flexible(
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Sync all wallets at startup",
-                                      style: STextStyles.titleBold12(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    Text(
-                                      "All of your wallets will start syncing when you open the app",
-                                      style: STextStyles.itemSubtitle(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                  ],
-                                ),
-                              ),
-                            ],
-                          ),
-                        ),
-                      ),
-                    ),
-                  ),
-                  Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: RawMaterialButton(
-                      // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                      shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
-                        ),
-                      ),
-                      onPressed: () {
-                        final state =
-                            ref.read(prefsChangeNotifierProvider).syncType;
-                        if (state != SyncingType.selectedWalletsAtStartup) {
-                          ref.read(prefsChangeNotifierProvider).syncType =
-                              SyncingType.selectedWalletsAtStartup;
-
-                          final ids = ref
-                              .read(prefsChangeNotifierProvider)
-                              .walletIdsSyncOnStartup;
-
-                          // enable auto sync on selected wallets only
-                          ref
-                              .read(walletsChangeNotifierProvider)
-                              .managers
-                              .forEach((e) =>
-                                  e.shouldAutoSync = ids.contains(e.walletId));
-                        }
-                      },
-                      child: Container(
-                        color: Colors.transparent,
-                        child: Padding(
-                          padding: const EdgeInsets.all(8),
-                          child: Row(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              SizedBox(
-                                width: 20,
-                                height: 20,
-                                child: Radio(
-                                  activeColor: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .radioButtonIconEnabled,
-                                  value: SyncingType.selectedWalletsAtStartup,
-                                  groupValue: ref.watch(
-                                    prefsChangeNotifierProvider
-                                        .select((value) => value.syncType),
-                                  ),
-                                  onChanged: (value) {
-                                    if (value is SyncingType) {
-                                      ref
-                                          .read(prefsChangeNotifierProvider)
-                                          .syncType = value;
-                                    }
-                                  },
-                                ),
-                              ),
-                              const SizedBox(
-                                width: 12,
-                              ),
-                              Flexible(
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Sync only selected wallets at startup",
-                                      style: STextStyles.titleBold12(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    Text(
-                                      "Only the wallets you select will start syncing when you open the app",
-                                      style: STextStyles.itemSubtitle(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                  ],
-                                ),
-                              ),
-                            ],
-                          ),
-                        ),
-                      ),
-                    ),
-                  ),
-                  if (ref.watch(prefsChangeNotifierProvider
-                          .select((value) => value.syncType)) !=
-                      SyncingType.selectedWalletsAtStartup)
-                    const SizedBox(
-                      height: 12,
-                    ),
-                  if (ref.watch(prefsChangeNotifierProvider
-                          .select((value) => value.syncType)) ==
-                      SyncingType.selectedWalletsAtStartup)
-                    Container(
+                        // disable auto sync on all wallets that aren't active/current
+                        ref
+                            .read(walletsChangeNotifierProvider)
+                            .managers
+                            .forEach((e) {
+                          if (!e.isActiveWallet) {
+                            e.shouldAutoSync = false;
+                          }
+                        });
+                      }
+                    },
+                    child: Container(
                       color: Colors.transparent,
                       child: Padding(
-                        padding: const EdgeInsets.only(
-                          left: 12.0,
-                          right: 12,
-                          bottom: 12,
-                        ),
+                        padding: const EdgeInsets.all(8.0),
                         child: Row(
                           crossAxisAlignment: CrossAxisAlignment.start,
                           children: [
+                            SizedBox(
+                              width: 20,
+                              height: 20,
+                              child: Radio(
+                                activeColor: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .radioButtonIconEnabled,
+                                value: SyncingType.currentWalletOnly,
+                                groupValue: ref.watch(
+                                  prefsChangeNotifierProvider
+                                      .select((value) => value.syncType),
+                                ),
+                                onChanged: (value) {
+                                  if (value is SyncingType) {
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .syncType = value;
+                                  }
+                                },
+                              ),
+                            ),
                             const SizedBox(
-                              width: 12 + 20,
-                              height: 12,
+                              width: 12,
                             ),
                             Flexible(
-                              child: RawMaterialButton(
-                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                materialTapTargetSize:
-                                    MaterialTapTargetSize.shrinkWrap,
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    "Sync only currently open wallet",
+                                    style: STextStyles.titleBold12(context),
+                                    textAlign: TextAlign.left,
                                   ),
-                                ),
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                      WalletSyncingOptionsView.routeName);
-                                },
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Select wallets...",
-                                      style: STextStyles.link2(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                  ],
-                                ),
+                                  Text(
+                                    "Sync only the wallet that you are using",
+                                    style: STextStyles.itemSubtitle(context),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                ],
                               ),
                             ),
                           ],
                         ),
                       ),
                     ),
-                ],
-              ),
+                  ),
+                ),
+                Padding(
+                  padding: const EdgeInsets.all(4.0),
+                  child: RawMaterialButton(
+                    // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
+                      ),
+                    ),
+                    onPressed: () {
+                      final state =
+                          ref.read(prefsChangeNotifierProvider).syncType;
+                      if (state != SyncingType.allWalletsOnStartup) {
+                        ref.read(prefsChangeNotifierProvider).syncType =
+                            SyncingType.allWalletsOnStartup;
+
+                        // enable auto sync on all wallets
+                        ref
+                            .read(walletsChangeNotifierProvider)
+                            .managers
+                            .forEach((e) => e.shouldAutoSync = true);
+                      }
+                    },
+                    child: Container(
+                      color: Colors.transparent,
+                      child: Padding(
+                        padding: const EdgeInsets.all(8.0),
+                        child: Row(
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            SizedBox(
+                              width: 20,
+                              height: 20,
+                              child: Radio(
+                                activeColor: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .radioButtonIconEnabled,
+                                value: SyncingType.allWalletsOnStartup,
+                                groupValue: ref.watch(
+                                  prefsChangeNotifierProvider
+                                      .select((value) => value.syncType),
+                                ),
+                                onChanged: (value) {
+                                  if (value is SyncingType) {
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .syncType = value;
+                                  }
+                                },
+                              ),
+                            ),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                            Flexible(
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    "Sync all wallets at startup",
+                                    style: STextStyles.titleBold12(context),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                  Text(
+                                    "All of your wallets will start syncing when you open the app",
+                                    style: STextStyles.itemSubtitle(context),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                ],
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                ),
+                Padding(
+                  padding: const EdgeInsets.all(4),
+                  child: RawMaterialButton(
+                    // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
+                      ),
+                    ),
+                    onPressed: () {
+                      final state =
+                          ref.read(prefsChangeNotifierProvider).syncType;
+                      if (state != SyncingType.selectedWalletsAtStartup) {
+                        ref.read(prefsChangeNotifierProvider).syncType =
+                            SyncingType.selectedWalletsAtStartup;
+
+                        final ids = ref
+                            .read(prefsChangeNotifierProvider)
+                            .walletIdsSyncOnStartup;
+
+                        // enable auto sync on selected wallets only
+                        ref
+                            .read(walletsChangeNotifierProvider)
+                            .managers
+                            .forEach((e) =>
+                                e.shouldAutoSync = ids.contains(e.walletId));
+                      }
+                    },
+                    child: Container(
+                      color: Colors.transparent,
+                      child: Padding(
+                        padding: const EdgeInsets.all(8),
+                        child: Row(
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            SizedBox(
+                              width: 20,
+                              height: 20,
+                              child: Radio(
+                                activeColor: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .radioButtonIconEnabled,
+                                value: SyncingType.selectedWalletsAtStartup,
+                                groupValue: ref.watch(
+                                  prefsChangeNotifierProvider
+                                      .select((value) => value.syncType),
+                                ),
+                                onChanged: (value) {
+                                  if (value is SyncingType) {
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .syncType = value;
+                                  }
+                                },
+                              ),
+                            ),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                            Flexible(
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    "Sync only selected wallets at startup",
+                                    style: STextStyles.titleBold12(context),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                  Text(
+                                    "Only the wallets you select will start syncing when you open the app",
+                                    style: STextStyles.itemSubtitle(context),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                ],
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                ),
+                if (ref.watch(prefsChangeNotifierProvider
+                        .select((value) => value.syncType)) !=
+                    SyncingType.selectedWalletsAtStartup)
+                  const SizedBox(
+                    height: 12,
+                  ),
+                if (ref.watch(prefsChangeNotifierProvider
+                        .select((value) => value.syncType)) ==
+                    SyncingType.selectedWalletsAtStartup)
+                  Container(
+                    color: Colors.transparent,
+                    child: Padding(
+                      padding: const EdgeInsets.only(
+                        left: 12.0,
+                        right: 12,
+                        bottom: 12,
+                      ),
+                      child: Row(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          const SizedBox(
+                            width: 12 + 20,
+                            height: 12,
+                          ),
+                          Flexible(
+                            child: RawMaterialButton(
+                              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                              materialTapTargetSize:
+                                  MaterialTapTargetSize.shrinkWrap,
+                              shape: RoundedRectangleBorder(
+                                borderRadius: BorderRadius.circular(
+                                  Constants.size.circularBorderRadius,
+                                ),
+                              ),
+                              onPressed: () {
+                                !isDesktop
+                                    ? Navigator.of(context).pushNamed(
+                                        WalletSyncingOptionsView.routeName)
+                                    : showDialog(
+                                        context: context,
+                                        useSafeArea: false,
+                                        barrierDismissible: true,
+                                        builder: (context) {
+                                          return DesktopDialog(
+                                            maxWidth: 600,
+                                            maxHeight: 800,
+                                            child: Column(
+                                              children: [
+                                                Row(
+                                                  mainAxisAlignment:
+                                                      MainAxisAlignment
+                                                          .spaceBetween,
+                                                  children: [
+                                                    Padding(
+                                                      padding:
+                                                          const EdgeInsets.all(
+                                                              32),
+                                                      child: Text(
+                                                        "Select wallets to sync",
+                                                        style: STextStyles
+                                                            .desktopH3(context),
+                                                        textAlign:
+                                                            TextAlign.center,
+                                                      ),
+                                                    ),
+                                                    const DesktopDialogCloseButton(),
+                                                  ],
+                                                ),
+                                                const Expanded(
+                                                  child:
+                                                      WalletSyncingOptionsView(),
+                                                ),
+                                              ],
+                                            ),
+                                          );
+                                        });
+                              },
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    "Select wallets...",
+                                    style: STextStyles.link2(context),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                ],
+                              ),
+                            ),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+              ],
             ),
-          ],
-        ),
+          ),
+        ],
       ),
     );
   }
diff --git a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
index 1e302cf12..c615d5f94 100644
--- a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
+++ b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
@@ -10,7 +10,9 @@ import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
 import 'package:stackwallet/utilities/format.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/animated_text.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -25,30 +27,47 @@ class WalletSyncingOptionsView extends ConsumerWidget {
     final managers = ref
         .watch(walletsChangeNotifierProvider.select((value) => value.managers));
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: FittedBox(
-          fit: BoxFit.scaleDown,
-          child: Text(
-            "Sync only selected wallets at startup",
-            style: STextStyles.navBarTitle(context),
+    final isDesktop = Util.isDesktop;
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () async {
+                Navigator.of(context).pop();
+              },
+            ),
+            title: FittedBox(
+              fit: BoxFit.scaleDown,
+              child: Text(
+                "Sync only selected wallets at startup",
+                style: STextStyles.navBarTitle(context),
+              ),
+            ),
           ),
-        ),
-      ),
-      body: LayoutBuilder(builder: (context, constraints) {
-        return Padding(
-          padding: const EdgeInsets.only(
-            left: 12,
-            top: 12,
-            right: 12,
+          body: Padding(
+            padding: const EdgeInsets.only(
+              left: 12,
+              top: 12,
+              right: 12,
+            ),
+            child: child,
           ),
-          child: SingleChildScrollView(
+        );
+      },
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) {
+          return Padding(
+            padding: EdgeInsets.symmetric(horizontal: 32),
+            child: child,
+          );
+        },
+        child: LayoutBuilder(builder: (context, constraints) {
+          return SingleChildScrollView(
             child: ConstrainedBox(
               constraints: BoxConstraints(
                 minHeight: constraints.maxHeight - 24,
@@ -208,9 +227,9 @@ class WalletSyncingOptionsView extends ConsumerWidget {
                 ),
               ),
             ),
-          ),
-        );
-      }),
+          );
+        }),
+      ),
     );
   }
 }

From bd04f1d9f9133d1a871ce57d8ae65f2a98669bf1 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 3 Nov 2022 17:26:56 -0600
Subject: [PATCH 124/426] added border to wallet selection

---
 .../wallet_syncing_options_view.dart                         | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
index c615d5f94..9724356a1 100644
--- a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
+++ b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
@@ -90,6 +90,11 @@ class WalletSyncingOptionsView extends ConsumerWidget {
                       ),
                       RoundedWhiteContainer(
                         padding: const EdgeInsets.all(0),
+                        borderColor: !isDesktop
+                            ? Colors.transparent
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .background,
                         child: Column(
                           children: [
                             ...managers.map(

From 14d7c443f237e06a957fcd719413baae7c3cd072 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 3 Nov 2022 17:58:31 -0600
Subject: [PATCH 125/426] v1.5.14 build 86

---
 pubspec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index 64c678637..9ba6d4eb9 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.13+85
+version: 1.5.14+86
 
 environment:
   sdk: ">=2.17.0 <3.0.0"

From bed25b37f720a756c76200372e742c2cf2173ac7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 3 Nov 2022 17:53:19 -0600
Subject: [PATCH 126/426] desktop node management ui

---
 .../add_edit_node_view.dart                   | 653 +++++++++++-------
 .../manage_nodes_views/coin_nodes_view.dart   |  33 +-
 .../manage_nodes_views/node_details_view.dart | 333 ++++++---
 .../home/settings_menu/nodes_settings.dart    |  19 +-
 lib/utilities/theme/stack_colors.dart         |  14 +
 lib/widgets/desktop/delete_button.dart        |  98 +++
 6 files changed, 762 insertions(+), 388 deletions(-)
 create mode 100644 lib/widgets/desktop/delete_button.dart

diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 77349f399..87aee413e 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -8,7 +8,6 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
-import 'package:stackwallet/providers/global/node_service_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -20,15 +19,18 @@ import 'package:stackwallet/utilities/test_epic_box_connection.dart';
 import 'package:stackwallet/utilities/test_monero_node_connection.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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 import 'package:uuid/uuid.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 enum AddEditNodeViewType { add, edit }
 
 class AddEditNodeView extends ConsumerStatefulWidget {
@@ -59,6 +61,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
   late final AddEditNodeViewType viewType;
   late final Coin coin;
   late final String? nodeId;
+  late final bool isDesktop;
 
   late bool saveEnabled;
   late bool testConnectionEnabled;
@@ -162,8 +165,198 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
     return testPassed;
   }
 
+  Future<void> attemptSave() async {
+    final canConnect = await _testConnection(showFlushBar: false);
+
+    bool? shouldSave;
+
+    if (!canConnect) {
+      await showDialog<dynamic>(
+        context: context,
+        useSafeArea: true,
+        barrierDismissible: true,
+        builder: (_) => isDesktop
+            ? DesktopDialog(
+                maxWidth: 440,
+                maxHeight: 300,
+                child: Column(
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.only(
+                        top: 32,
+                      ),
+                      child: Row(
+                        children: [
+                          const SizedBox(
+                            width: 32,
+                          ),
+                          Text(
+                            "Server currently unreachable",
+                            style: STextStyles.desktopH3(context),
+                          ),
+                        ],
+                      ),
+                    ),
+                    Expanded(
+                      child: Padding(
+                        padding: const EdgeInsets.only(
+                          left: 32,
+                          right: 32,
+                          top: 16,
+                          bottom: 32,
+                        ),
+                        child: Column(
+                          children: [
+                            const Spacer(),
+                            Text(
+                              "Would you like to save this node anyways?",
+                              style: STextStyles.desktopTextMedium(context),
+                            ),
+                            const Spacer(
+                              flex: 2,
+                            ),
+                            Row(
+                              children: [
+                                Expanded(
+                                  child: SecondaryButton(
+                                    label: "Cancel",
+                                    desktopMed: true,
+                                    onPressed: () => Navigator.of(
+                                      context,
+                                      rootNavigator: true,
+                                    ).pop(false),
+                                  ),
+                                ),
+                                const SizedBox(
+                                  width: 16,
+                                ),
+                                Expanded(
+                                  child: PrimaryButton(
+                                    label: "Save",
+                                    desktopMed: true,
+                                    onPressed: () => Navigator.of(
+                                      context,
+                                      rootNavigator: true,
+                                    ).pop(true),
+                                  ),
+                                ),
+                              ],
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+              )
+            : StackDialog(
+                title: "Server currently unreachable",
+                message: "Would you like to save this node anyways?",
+                leftButton: TextButton(
+                  onPressed: () async {
+                    Navigator.of(context).pop(false);
+                  },
+                  child: Text(
+                    "Cancel",
+                    style: STextStyles.button(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark),
+                  ),
+                ),
+                rightButton: TextButton(
+                  onPressed: () async {
+                    Navigator.of(context).pop(true);
+                  },
+                  style: Theme.of(context)
+                      .extension<StackColors>()!
+                      .getPrimaryEnabledButtonColor(context),
+                  child: Text(
+                    "Save",
+                    style: STextStyles.button(context),
+                  ),
+                ),
+              ),
+      ).then((value) {
+        if (value is bool && value) {
+          shouldSave = true;
+        } else {
+          shouldSave = false;
+        }
+      });
+    }
+
+    if (!canConnect && !shouldSave!) {
+      // return without saving
+      return;
+    }
+
+    final formData = ref.read(nodeFormDataProvider);
+
+    // strip unused path
+    String address = formData.host!;
+    if (coin == Coin.monero || coin == Coin.wownero || coin == Coin.epicCash) {
+      if (address.startsWith("http")) {
+        final uri = Uri.parse(address);
+        address = "${uri.scheme}://${uri.host}";
+      }
+    }
+
+    switch (viewType) {
+      case AddEditNodeViewType.add:
+        NodeModel node = NodeModel(
+          host: address,
+          port: formData.port!,
+          name: formData.name!,
+          id: const Uuid().v1(),
+          useSSL: formData.useSSL!,
+          loginName: formData.login,
+          enabled: true,
+          coinName: coin.name,
+          isFailover: formData.isFailover!,
+          isDown: false,
+        );
+
+        await ref.read(nodeServiceChangeNotifierProvider).add(
+              node,
+              formData.password,
+              true,
+            );
+        if (mounted) {
+          Navigator.of(context)
+              .popUntil(ModalRoute.withName(widget.routeOnSuccessOrDelete));
+        }
+        break;
+      case AddEditNodeViewType.edit:
+        NodeModel node = NodeModel(
+          host: address,
+          port: formData.port!,
+          name: formData.name!,
+          id: nodeId!,
+          useSSL: formData.useSSL!,
+          loginName: formData.login,
+          enabled: true,
+          coinName: coin.name,
+          isFailover: formData.isFailover!,
+          isDown: false,
+        );
+
+        await ref.read(nodeServiceChangeNotifierProvider).add(
+              node,
+              formData.password,
+              true,
+            );
+        if (mounted) {
+          Navigator.of(context)
+              .popUntil(ModalRoute.withName(widget.routeOnSuccessOrDelete));
+        }
+        break;
+    }
+  }
+
   @override
   void initState() {
+    isDesktop = Util.isDesktop;
     ref.refresh(nodeFormDataProvider);
 
     viewType = widget.viewType;
@@ -196,279 +389,203 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
                 .select((value) => value.getNodeById(id: nodeId!)))
             : null;
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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(
-          viewType == AddEditNodeViewType.edit ? "Edit node" : "Add node",
-          style: STextStyles.navBarTitle(context),
-        ),
-        actions: [
-          if (viewType == AddEditNodeViewType.edit)
-            Padding(
-              padding: const EdgeInsets.only(
-                top: 10,
-                bottom: 10,
-                right: 10,
-              ),
-              child: AspectRatio(
-                aspectRatio: 1,
-                child: AppBarIconButton(
-                  key: const Key("deleteNodeAppBarButtonKey"),
-                  size: 36,
-                  shadows: const [],
-                  color: Theme.of(context).extension<StackColors>()!.background,
-                  icon: SvgPicture.asset(
-                    Assets.svg.trash,
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .accentColorDark,
-                    width: 20,
-                    height: 20,
-                  ),
-                  onPressed: () async {
-                    Navigator.popUntil(context,
-                        ModalRoute.withName(widget.routeOnSuccessOrDelete));
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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(
+            viewType == AddEditNodeViewType.edit ? "Edit node" : "Add node",
+            style: STextStyles.navBarTitle(context),
+          ),
+          actions: [
+            if (viewType == AddEditNodeViewType.edit)
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
+                ),
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("deleteNodeAppBarButtonKey"),
+                    size: 36,
+                    shadows: const [],
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    icon: SvgPicture.asset(
+                      Assets.svg.trash,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                      width: 20,
+                      height: 20,
+                    ),
+                    onPressed: () async {
+                      Navigator.popUntil(context,
+                          ModalRoute.withName(widget.routeOnSuccessOrDelete));
 
-                    await ref.read(nodeServiceChangeNotifierProvider).delete(
-                          nodeId!,
-                          true,
-                        );
-                  },
+                      await ref.read(nodeServiceChangeNotifierProvider).delete(
+                            nodeId!,
+                            true,
+                          );
+                    },
+                  ),
                 ),
               ),
-            ),
-        ],
-      ),
-      body: Padding(
-        padding: const EdgeInsets.only(
-          top: 12,
-          left: 12,
-          right: 12,
-          bottom: 12,
+          ],
         ),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: Padding(
-                padding: const EdgeInsets.all(4),
-                child: ConstrainedBox(
-                  constraints:
-                      BoxConstraints(minHeight: constraints.maxHeight - 8),
-                  child: IntrinsicHeight(
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        NodeForm(
-                          node: node,
-                          secureStore: widget.secureStore,
-                          readOnly: false,
-                          coin: widget.coin,
-                          onChanged: (canSave, canTest) {
-                            if (canSave != saveEnabled &&
-                                canTest != testConnectionEnabled) {
-                              setState(() {
-                                saveEnabled = canSave;
-                                testConnectionEnabled = canTest;
-                              });
-                            } else if (canSave != saveEnabled) {
-                              setState(() {
-                                saveEnabled = canSave;
-                              });
-                            } else if (canTest != testConnectionEnabled) {
-                              setState(() {
-                                testConnectionEnabled = canTest;
-                              });
-                            }
-                          },
-                        ),
-                        const Spacer(),
-                        TextButton(
-                          onPressed: testConnectionEnabled
-                              ? () async {
-                                  await _testConnection();
-                                }
-                              : null,
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getSecondaryEnabledButtonColor(context),
-                          child: Text(
-                            "Test connection",
-                            style: STextStyles.button(context).copyWith(
-                              color: testConnectionEnabled
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textWhite,
-                            ),
-                          ),
-                        ),
-                        const SizedBox(height: 16),
-                        TextButton(
-                          style: saveEnabled
-                              ? Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .getPrimaryEnabledButtonColor(context)
-                              : Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .getPrimaryDisabledButtonColor(context),
-                          onPressed: saveEnabled
-                              ? () async {
-                                  final canConnect = await _testConnection(
-                                      showFlushBar: false);
-
-                                  bool? shouldSave;
-
-                                  if (!canConnect) {
-                                    await showDialog<dynamic>(
-                                      context: context,
-                                      useSafeArea: true,
-                                      barrierDismissible: true,
-                                      builder: (_) => StackDialog(
-                                        title: "Server currently unreachable",
-                                        message:
-                                            "Would you like to save this node anyways?",
-                                        leftButton: TextButton(
-                                          onPressed: () async {
-                                            Navigator.of(context).pop(false);
-                                          },
-                                          child: Text(
-                                            "Cancel",
-                                            style: STextStyles.button(context)
-                                                .copyWith(
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .accentColorDark),
-                                          ),
-                                        ),
-                                        rightButton: TextButton(
-                                          onPressed: () async {
-                                            Navigator.of(context).pop(true);
-                                          },
-                                          style: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .getPrimaryEnabledButtonColor(
-                                                  context),
-                                          child: Text(
-                                            "Save",
-                                            style: STextStyles.button(context),
-                                          ),
-                                        ),
-                                      ),
-                                    ).then((value) {
-                                      if (value is bool && value) {
-                                        shouldSave = true;
-                                      } else {
-                                        shouldSave = false;
-                                      }
-                                    });
-                                  }
-
-                                  if (!canConnect && !shouldSave!) {
-                                    // return without saving
-                                    return;
-                                  }
-
-                                  final formData =
-                                      ref.read(nodeFormDataProvider);
-
-                                  // strip unused path
-                                  String address = formData.host!;
-                                  if (coin == Coin.monero ||
-                                      coin == Coin.wownero ||
-                                      coin == Coin.epicCash) {
-                                    if (address.startsWith("http")) {
-                                      final uri = Uri.parse(address);
-                                      address = "${uri.scheme}://${uri.host}";
-                                    }
-                                  }
-
-                                  switch (viewType) {
-                                    case AddEditNodeViewType.add:
-                                      NodeModel node = NodeModel(
-                                        host: address,
-                                        port: formData.port!,
-                                        name: formData.name!,
-                                        id: const Uuid().v1(),
-                                        useSSL: formData.useSSL!,
-                                        loginName: formData.login,
-                                        enabled: true,
-                                        coinName: coin.name,
-                                        isFailover: formData.isFailover!,
-                                        isDown: false,
-                                      );
-
-                                      await ref
-                                          .read(
-                                              nodeServiceChangeNotifierProvider)
-                                          .add(
-                                            node,
-                                            formData.password,
-                                            true,
-                                          );
-                                      if (mounted) {
-                                        Navigator.of(context).popUntil(
-                                            ModalRoute.withName(
-                                                widget.routeOnSuccessOrDelete));
-                                      }
-                                      break;
-                                    case AddEditNodeViewType.edit:
-                                      NodeModel node = NodeModel(
-                                        host: address,
-                                        port: formData.port!,
-                                        name: formData.name!,
-                                        id: nodeId!,
-                                        useSSL: formData.useSSL!,
-                                        loginName: formData.login,
-                                        enabled: true,
-                                        coinName: coin.name,
-                                        isFailover: formData.isFailover!,
-                                        isDown: false,
-                                      );
-
-                                      await ref
-                                          .read(
-                                              nodeServiceChangeNotifierProvider)
-                                          .add(
-                                            node,
-                                            formData.password,
-                                            true,
-                                          );
-                                      if (mounted) {
-                                        Navigator.of(context).popUntil(
-                                            ModalRoute.withName(
-                                                widget.routeOnSuccessOrDelete));
-                                      }
-                                      break;
-                                  }
-                                }
-                              : null,
-                          child: Text(
-                            "Save",
-                            style: STextStyles.button(context),
-                          ),
-                        ),
-                      ],
+        body: Padding(
+          padding: const EdgeInsets.only(
+            top: 12,
+            left: 12,
+            right: 12,
+            bottom: 12,
+          ),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: Padding(
+                  padding: const EdgeInsets.all(4),
+                  child: ConstrainedBox(
+                    constraints:
+                        BoxConstraints(minHeight: constraints.maxHeight - 8),
+                    child: IntrinsicHeight(
+                      child: child,
                     ),
                   ),
                 ),
+              );
+            },
+          ),
+        ),
+      ),
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) => DesktopDialog(
+          maxWidth: 580,
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              Row(
+                children: [
+                  const SizedBox(
+                    width: 8,
+                  ),
+                  const AppBarBackButton(
+                    iconSize: 24,
+                    size: 40,
+                  ),
+                  Text(
+                    "Add new node",
+                    style: STextStyles.desktopH3(context),
+                  )
+                ],
               ),
-            );
-          },
+              Padding(
+                padding: const EdgeInsets.only(
+                  left: 32,
+                  right: 32,
+                  top: 16,
+                  bottom: 32,
+                ),
+                child: child,
+              ),
+            ],
+          ),
+        ),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: [
+            NodeForm(
+              node: node,
+              secureStore: widget.secureStore,
+              readOnly: false,
+              coin: widget.coin,
+              onChanged: (canSave, canTest) {
+                if (canSave != saveEnabled &&
+                    canTest != testConnectionEnabled) {
+                  setState(() {
+                    saveEnabled = canSave;
+                    testConnectionEnabled = canTest;
+                  });
+                } else if (canSave != saveEnabled) {
+                  setState(() {
+                    saveEnabled = canSave;
+                  });
+                } else if (canTest != testConnectionEnabled) {
+                  setState(() {
+                    testConnectionEnabled = canTest;
+                  });
+                }
+              },
+            ),
+            if (!isDesktop) const Spacer(),
+            if (isDesktop)
+              const SizedBox(
+                height: 78,
+              ),
+            Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Test connection",
+                    enabled: testConnectionEnabled,
+                    desktopMed: true,
+                    onPressed: testConnectionEnabled
+                        ? () async {
+                            await _testConnection();
+                          }
+                        : null,
+                  ),
+                ),
+                if (isDesktop)
+                  const SizedBox(
+                    width: 16,
+                  ),
+                if (isDesktop)
+                  Expanded(
+                    child: PrimaryButton(
+                      label: "Save",
+                      enabled: saveEnabled,
+                      desktopMed: true,
+                      onPressed: saveEnabled ? attemptSave : null,
+                    ),
+                  ),
+              ],
+            ),
+            if (!isDesktop)
+              const SizedBox(
+                height: 16,
+              ),
+            if (!isDesktop)
+              TextButton(
+                style: saveEnabled
+                    ? Theme.of(context)
+                        .extension<StackColors>()!
+                        .getPrimaryEnabledButtonColor(context)
+                    : Theme.of(context)
+                        .extension<StackColors>()!
+                        .getPrimaryDisabledButtonColor(context),
+                onPressed: saveEnabled ? attemptSave : null,
+                child: Text(
+                  "Save",
+                  style: STextStyles.button(context),
+                ),
+              ),
+          ],
         ),
       ),
     );
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 e3743d54e..a93b64be3 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
@@ -9,6 +9,7 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:tuple/tuple.dart';
@@ -17,11 +18,13 @@ class CoinNodesView extends ConsumerStatefulWidget {
   const CoinNodesView({
     Key? key,
     required this.coin,
+    this.rootNavigator = false,
   }) : super(key: key);
 
   static const String routeName = "/coinNodes";
 
   final Coin coin;
+  final bool rootNavigator;
 
   @override
   ConsumerState<CoinNodesView> createState() => _CoinNodesViewState();
@@ -63,12 +66,17 @@ class _CoinNodesViewState extends ConsumerState<CoinNodesView> {
                   textAlign: TextAlign.center,
                 ),
                 Expanded(
-                  child: const DesktopDialogCloseButton(),
+                  child: DesktopDialogCloseButton(
+                    onPressedOverride: Navigator.of(
+                      context,
+                      rootNavigator: widget.rootNavigator,
+                    ).pop,
+                  ),
                 ),
               ],
             ),
             Padding(
-              padding: EdgeInsets.only(
+              padding: const EdgeInsets.only(
                 left: 32,
                 right: 32,
               ),
@@ -83,14 +91,19 @@ class _CoinNodesViewState extends ConsumerState<CoinNodesView> {
                     ),
                     textAlign: TextAlign.left,
                   ),
-                  RichText(
-                    text: TextSpan(
-                      text: 'Add new nodes',
-                      style:
-                          STextStyles.desktopTextExtraSmall(context).copyWith(
-                        color: Colors.blueAccent,
-                      ),
-                    ),
+                  BlueTextButton(
+                    text: "Add new node",
+                    onTap: () {
+                      Navigator.of(context).pushNamed(
+                        AddEditNodeView.routeName,
+                        arguments: Tuple4(
+                          AddEditNodeViewType.add,
+                          widget.coin,
+                          null,
+                          CoinNodesView.routeName,
+                        ),
+                      );
+                    },
                   ),
                 ],
               ),
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index c5f797e37..c5e666ce2 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -17,7 +17,13 @@ import 'package:stackwallet/utilities/test_epic_box_connection.dart';
 import 'package:stackwallet/utilities/test_monero_node_connection.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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/delete_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:tuple/tuple.dart';
 
 class NodeDetailsView extends ConsumerStatefulWidget {
@@ -48,6 +54,8 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
   late final String nodeId;
   late final String popRouteName;
 
+  bool _desktopReadOnly = true;
+
   @override
   initState() {
     secureStore = widget.secureStore;
@@ -126,130 +134,239 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
     }
 
     if (testPassed) {
-      showFloatingFlushBar(
-        type: FlushBarType.success,
-        message: "Server ping success",
-        context: context,
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.success,
+          message: "Server ping success",
+          context: context,
+        ),
       );
     } else {
-      showFloatingFlushBar(
-        type: FlushBarType.warning,
-        message: "Server unreachable",
-        context: context,
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "Server unreachable",
+          context: context,
+        ),
       );
     }
   }
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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(
-          "Node details",
-          style: STextStyles.navBarTitle(context),
-        ),
-        actions: [
-          if (!nodeId.startsWith("default"))
-            Padding(
-              padding: const EdgeInsets.only(
-                top: 10,
-                bottom: 10,
-                right: 10,
-              ),
-              child: AspectRatio(
-                aspectRatio: 1,
-                child: AppBarIconButton(
-                  key: const Key("nodeDetailsEditNodeAppBarButtonKey"),
-                  size: 36,
-                  shadows: const [],
-                  color: Theme.of(context).extension<StackColors>()!.background,
-                  icon: SvgPicture.asset(
-                    Assets.svg.pencil,
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .accentColorDark,
-                    width: 20,
-                    height: 20,
+    final isDesktop = Util.isDesktop;
+
+    final node = ref.watch(nodeServiceChangeNotifierProvider
+        .select((value) => value.getNodeById(id: nodeId)));
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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(
+            "Node details",
+            style: STextStyles.navBarTitle(context),
+          ),
+          actions: [
+            if (!nodeId.startsWith("default"))
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
+                ),
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("nodeDetailsEditNodeAppBarButtonKey"),
+                    size: 36,
+                    shadows: const [],
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    icon: SvgPicture.asset(
+                      Assets.svg.pencil,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                      width: 20,
+                      height: 20,
+                    ),
+                    onPressed: () {
+                      Navigator.of(context).pushNamed(
+                        AddEditNodeView.routeName,
+                        arguments: Tuple4(
+                          AddEditNodeViewType.edit,
+                          coin,
+                          nodeId,
+                          popRouteName,
+                        ),
+                      );
+                    },
                   ),
-                  onPressed: () {
-                    Navigator.of(context).pushNamed(
-                      AddEditNodeView.routeName,
-                      arguments: Tuple4(
-                        AddEditNodeViewType.edit,
-                        coin,
-                        nodeId,
-                        popRouteName,
-                      ),
-                    );
-                  },
                 ),
               ),
-            ),
-        ],
-      ),
-      body: Padding(
-        padding: const EdgeInsets.only(
-          top: 12,
-          left: 12,
-          right: 12,
+          ],
         ),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            final node = ref.watch(nodeServiceChangeNotifierProvider
-                .select((value) => value.getNodeById(id: nodeId)));
-
-            return SingleChildScrollView(
-              child: Padding(
-                padding: const EdgeInsets.all(4),
-                child: ConstrainedBox(
-                  constraints:
-                      BoxConstraints(minHeight: constraints.maxHeight - 8),
-                  child: IntrinsicHeight(
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        NodeForm(
-                          node: node,
-                          secureStore: secureStore,
-                          readOnly: true,
-                          coin: coin,
-                        ),
-                        const Spacer(),
-                        TextButton(
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getSecondaryEnabledButtonColor(context),
-                          onPressed: () async {
-                            await _testConnection(ref, context);
-                          },
-                          child: Text(
-                            "Test connection",
-                            style: STextStyles.button(context).copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorDark),
-                          ),
-                        ),
-                        const SizedBox(height: 16),
-                      ],
+        body: Padding(
+          padding: const EdgeInsets.only(
+            top: 12,
+            left: 12,
+            right: 12,
+          ),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: Padding(
+                  padding: const EdgeInsets.all(4),
+                  child: ConstrainedBox(
+                    constraints:
+                        BoxConstraints(minHeight: constraints.maxHeight - 8),
+                    child: IntrinsicHeight(
+                      child: child,
                     ),
                   ),
                 ),
+              );
+            },
+          ),
+        ),
+      ),
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) => DesktopDialog(
+          maxWidth: 580,
+          maxHeight: double.infinity,
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              Row(
+                children: [
+                  const SizedBox(
+                    width: 8,
+                  ),
+                  const AppBarBackButton(
+                    iconSize: 24,
+                    size: 40,
+                  ),
+                  Text(
+                    "Node details",
+                    style: STextStyles.desktopH3(context),
+                  )
+                ],
               ),
-            );
-          },
+              Padding(
+                padding: const EdgeInsets.only(
+                  left: 32,
+                  right: 32,
+                  top: 16,
+                  bottom: 32,
+                ),
+                child: child,
+              ),
+            ],
+          ),
+        ),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: [
+            NodeForm(
+              node: node,
+              secureStore: secureStore,
+              readOnly: isDesktop ? _desktopReadOnly : true,
+              coin: coin,
+            ),
+            if (!isDesktop) const Spacer(),
+            if (isDesktop)
+              const SizedBox(
+                height: 22,
+              ),
+            if (isDesktop)
+              SizedBox(
+                height: 56,
+                child: _desktopReadOnly
+                    ? null
+                    : Row(
+                        children: [
+                          Expanded(
+                            child: DeleteButton(
+                              label: "Delete node",
+                              desktopMed: true,
+                              onPressed: () async {
+                                Navigator.of(context).pop();
+
+                                await ref
+                                    .read(nodeServiceChangeNotifierProvider)
+                                    .delete(
+                                      node!.id,
+                                      true,
+                                    );
+                              },
+                            ),
+                          ),
+                          const SizedBox(
+                            width: 16,
+                          ),
+                          const Spacer(),
+                        ],
+                      ),
+              ),
+            if (isDesktop && !_desktopReadOnly)
+              const SizedBox(
+                height: 45,
+              ),
+            Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Test connection",
+                    desktopMed: true,
+                    onPressed: () async {
+                      await _testConnection(ref, context);
+                    },
+                  ),
+                ),
+                if (isDesktop)
+                  const SizedBox(
+                    width: 16,
+                  ),
+                if (isDesktop)
+                  Expanded(
+                    child: !nodeId.startsWith("default")
+                        ? PrimaryButton(
+                            label: _desktopReadOnly ? "Edit" : "Save",
+                            desktopMed: true,
+                            onPressed: () async {
+                              final shouldSave = _desktopReadOnly == false;
+                              setState(() {
+                                _desktopReadOnly = !_desktopReadOnly;
+                              });
+
+                              if (shouldSave) {
+                                // todo save node
+                              }
+                            },
+                          )
+                        : Container(),
+                  ),
+              ],
+            ),
+            if (!isDesktop)
+              const SizedBox(
+                height: 16,
+              ),
+          ],
         ),
       ),
     );
diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index abba6cccc..1d0317037 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -4,6 +4,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
 import 'package:stackwallet/providers/global/node_service_provider.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
@@ -167,8 +168,22 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                             onPressed: () {
                               showDialog<void>(
                                 context: context,
-                                builder: (context) => CoinNodesView(
-                                  coin: coin,
+                                builder: (context) => Navigator(
+                                  initialRoute: CoinNodesView.routeName,
+                                  onGenerateRoute: RouteGenerator.generateRoute,
+                                  onGenerateInitialRoutes: (_, __) {
+                                    return [
+                                      FadePageRoute(
+                                        CoinNodesView(
+                                          coin: coin,
+                                          rootNavigator: true,
+                                        ),
+                                        const RouteSettings(
+                                          name: CoinNodesView.routeName,
+                                        ),
+                                      ),
+                                    ];
+                                  },
                                 ),
                               );
                             },
diff --git a/lib/utilities/theme/stack_colors.dart b/lib/utilities/theme/stack_colors.dart
index 8a241db06..8249dccf4 100644
--- a/lib/utilities/theme/stack_colors.dart
+++ b/lib/utilities/theme/stack_colors.dart
@@ -1468,6 +1468,20 @@ class StackColors extends ThemeExtension<StackColors> {
     }
   }
 
+  ButtonStyle? getDeleteEnabledButtonColor(BuildContext context) =>
+      Theme.of(context).textButtonTheme.style?.copyWith(
+            backgroundColor: MaterialStateProperty.all<Color>(
+              textFieldErrorBG,
+            ),
+          );
+
+  ButtonStyle? getDeleteDisabledButtonColor(BuildContext context) =>
+      Theme.of(context).textButtonTheme.style?.copyWith(
+            backgroundColor: MaterialStateProperty.all<Color>(
+              buttonBackSecondaryDisabled,
+            ),
+          );
+
   ButtonStyle? getPrimaryEnabledButtonColor(BuildContext context) =>
       Theme.of(context).textButtonTheme.style?.copyWith(
             backgroundColor: MaterialStateProperty.all<Color>(
diff --git a/lib/widgets/desktop/delete_button.dart b/lib/widgets/desktop/delete_button.dart
new file mode 100644
index 000000000..e64c85f34
--- /dev/null
+++ b/lib/widgets/desktop/delete_button.dart
@@ -0,0 +1,98 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.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/custom_text_button.dart';
+
+class DeleteButton extends StatelessWidget {
+  const DeleteButton({
+    Key? key,
+    this.width,
+    this.height,
+    this.label,
+    this.onPressed,
+    this.enabled = true,
+    this.desktopMed = false,
+  }) : super(key: key);
+
+  final double? width;
+  final double? height;
+  final String? label;
+  final VoidCallback? onPressed;
+  final bool enabled;
+  final bool desktopMed;
+
+  TextStyle getStyle(bool isDesktop, BuildContext context) {
+    if (isDesktop) {
+      if (desktopMed) {
+        return STextStyles.desktopTextExtraSmall(context).copyWith(
+          color: enabled
+              ? Theme.of(context).extension<StackColors>()!.accentColorRed
+              : Theme.of(context)
+                  .extension<StackColors>()!
+                  .buttonTextSecondaryDisabled,
+        );
+      } else {
+        return enabled
+            ? STextStyles.desktopButtonSecondaryEnabled(context).copyWith(
+                color:
+                    Theme.of(context).extension<StackColors>()!.accentColorRed)
+            : STextStyles.desktopButtonSecondaryDisabled(context);
+      }
+    } else {
+      return STextStyles.button(context).copyWith(
+        color: enabled
+            ? Theme.of(context).extension<StackColors>()!.accentColorRed
+            : Theme.of(context)
+                .extension<StackColors>()!
+                .buttonTextSecondaryDisabled,
+      );
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final isDesktop = Util.isDesktop;
+
+    return CustomTextButtonBase(
+      height: desktopMed ? 56 : height,
+      width: width,
+      textButton: TextButton(
+        onPressed: enabled ? onPressed : null,
+        style: enabled
+            ? Theme.of(context)
+                .extension<StackColors>()!
+                .getDeleteEnabledButtonColor(context)
+            : Theme.of(context)
+                .extension<StackColors>()!
+                .getDeleteDisabledButtonColor(context),
+        child: Row(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            SvgPicture.asset(
+              Assets.svg.trash,
+              width: 20,
+              height: 20,
+              color: enabled
+                  ? Theme.of(context).extension<StackColors>()!.accentColorRed
+                  : Theme.of(context)
+                      .extension<StackColors>()!
+                      .buttonTextSecondaryDisabled,
+            ),
+            if (label != null)
+              const SizedBox(
+                width: 10,
+              ),
+            if (label != null)
+              Text(
+                label!,
+                style: getStyle(isDesktop, context),
+              ),
+          ],
+        ),
+      ),
+    );
+  }
+}

From 23d0ab8734de658e361e56654375048a62998e94 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 3 Nov 2022 18:11:29 -0600
Subject: [PATCH 127/426] stack privacy calls fix for small or narrow mobile
 screens

---
 lib/pages/stack_privacy_calls.dart | 489 +++++++++++------------------
 1 file changed, 175 insertions(+), 314 deletions(-)

diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index fd6f60def..3f819492e 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -14,6 +14,7 @@ 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/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
@@ -70,180 +71,195 @@ class _StackPrivacyCalls extends ConsumerState<StackPrivacyCalls> {
               ),
             ),
       body: SafeArea(
-        child: Padding(
-          padding: EdgeInsets.fromLTRB(0, isDesktop ? 0 : 40, 0, 0),
-          child: ConstrainedBox(
-            constraints: BoxConstraints(
-              maxWidth: isDesktop ? 480 : double.infinity,
+        child: ConditionalParent(
+          condition: !isDesktop,
+          builder: (child) => LayoutBuilder(
+            builder: (context, constraints) => SingleChildScrollView(
+              child: ConstrainedBox(
+                constraints: BoxConstraints(
+                  minHeight: constraints.maxHeight,
+                ),
+                child: IntrinsicHeight(
+                  child: child,
+                ),
+              ),
             ),
-            child: Column(
-              mainAxisAlignment: MainAxisAlignment.center,
-              children: [
-                Text(
-                  "Choose your Stack experience",
-                  style: isDesktop
-                      ? STextStyles.desktopH2(context)
-                      : STextStyles.pageTitleH1(context),
-                ),
-                SizedBox(
-                  height: isDesktop ? 16 : 8,
-                ),
-                Text(
-                  !widget.isSettings
-                      ? "You can change it later in Settings"
-                      : "",
-                  style: isDesktop
-                      ? STextStyles.desktopSubtitleH2(context)
-                      : STextStyles.subtitle(context),
-                ),
-                SizedBox(
-                  height: isDesktop ? 32 : 36,
-                ),
-                Padding(
-                  padding: EdgeInsets.symmetric(
-                    horizontal: isDesktop ? 0 : 16,
+          ),
+          child: Padding(
+            padding: EdgeInsets.fromLTRB(0, isDesktop ? 0 : 40, 0, 0),
+            child: ConstrainedBox(
+              constraints: BoxConstraints(
+                maxWidth: isDesktop ? 480 : double.infinity,
+              ),
+              child: Column(
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: [
+                  Text(
+                    "Choose your Stack experience",
+                    style: isDesktop
+                        ? STextStyles.desktopH2(context)
+                        : STextStyles.pageTitleH1(context),
                   ),
-                  child: PrivacyToggle(
-                    externalCallsEnabled: isEasy,
-                    onChanged: (externalCalls) {
-                      isEasy = externalCalls;
-                      setState(() {
-                        infoToggle = isEasy;
-                      });
-                    },
+                  SizedBox(
+                    height: isDesktop ? 16 : 8,
                   ),
-                ),
-                SizedBox(
-                  height: isDesktop ? 16 : 36,
-                ),
-                Padding(
-                  padding: isDesktop
-                      ? const EdgeInsets.all(0)
-                      : const EdgeInsets.all(16.0),
-                  child: RoundedWhiteContainer(
-                    child: Center(
-                      child: RichText(
-                        textAlign: TextAlign.left,
-                        text: TextSpan(
-                          style: isDesktop
-                              ? STextStyles.desktopTextExtraExtraSmall(context)
-                              : STextStyles.label(context).copyWith(
-                                  fontSize: 12.0,
-                                ),
-                          children: infoToggle
-                              ? [
-                                  const TextSpan(
-                                      text:
-                                          "Exchange data preloaded for a seamless experience."),
-                                  const TextSpan(
-                                      text:
-                                          "\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."),
-                                  TextSpan(
-                                    text:
-                                        "\n\nRecommended for most crypto users.",
-                                    style: isDesktop
-                                        ? STextStyles
-                                            .desktopTextExtraExtraSmall600(
-                                                context)
-                                        : TextStyle(
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textDark,
-                                            fontWeight: FontWeight.w600,
-                                          ),
+                  Text(
+                    !widget.isSettings
+                        ? "You can change it later in Settings"
+                        : "",
+                    style: isDesktop
+                        ? STextStyles.desktopSubtitleH2(context)
+                        : STextStyles.subtitle(context),
+                  ),
+                  SizedBox(
+                    height: isDesktop ? 32 : 36,
+                  ),
+                  Padding(
+                    padding: EdgeInsets.symmetric(
+                      horizontal: isDesktop ? 0 : 16,
+                    ),
+                    child: PrivacyToggle(
+                      externalCallsEnabled: isEasy,
+                      onChanged: (externalCalls) {
+                        isEasy = externalCalls;
+                        setState(() {
+                          infoToggle = isEasy;
+                        });
+                      },
+                    ),
+                  ),
+                  SizedBox(
+                    height: isDesktop ? 16 : 36,
+                  ),
+                  Padding(
+                    padding: isDesktop
+                        ? const EdgeInsets.all(0)
+                        : const EdgeInsets.all(16.0),
+                    child: RoundedWhiteContainer(
+                      child: Center(
+                        child: RichText(
+                          textAlign: TextAlign.left,
+                          text: TextSpan(
+                            style: isDesktop
+                                ? STextStyles.desktopTextExtraExtraSmall(context)
+                                : STextStyles.label(context).copyWith(
+                                    fontSize: 12.0,
                                   ),
-                                ]
-                              : [
-                                  const TextSpan(
+                            children: infoToggle
+                                ? [
+                                    const TextSpan(
+                                        text:
+                                            "Exchange data preloaded for a seamless experience."),
+                                    const TextSpan(
+                                        text:
+                                            "\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."),
+                                    TextSpan(
                                       text:
-                                          "Exchange data not preloaded (slower experience)."),
-                                  const TextSpan(
+                                          "\n\nRecommended for most crypto users.",
+                                      style: isDesktop
+                                          ? STextStyles
+                                              .desktopTextExtraExtraSmall600(
+                                                  context)
+                                          : TextStyle(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark,
+                                              fontWeight: FontWeight.w600,
+                                            ),
+                                    ),
+                                  ]
+                                : [
+                                    const TextSpan(
+                                        text:
+                                            "Exchange data not preloaded (slower experience)."),
+                                    const TextSpan(
+                                        text:
+                                            "\n\nCoinGecko disabled (price changes not shown, no wallet value shown in other currencies)."),
+                                    TextSpan(
                                       text:
-                                          "\n\nCoinGecko disabled (price changes not shown, no wallet value shown in other currencies)."),
-                                  TextSpan(
-                                    text:
-                                        "\n\nRecommended for the privacy conscious.",
-                                    style: isDesktop
-                                        ? STextStyles
-                                            .desktopTextExtraExtraSmall600(
-                                                context)
-                                        : TextStyle(
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textDark,
-                                            fontWeight: FontWeight.w600,
-                                          ),
-                                  ),
-                                ],
+                                          "\n\nRecommended for the privacy conscious.",
+                                      style: isDesktop
+                                          ? STextStyles
+                                              .desktopTextExtraExtraSmall600(
+                                                  context)
+                                          : TextStyle(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark,
+                                              fontWeight: FontWeight.w600,
+                                            ),
+                                    ),
+                                  ],
+                          ),
                         ),
                       ),
                     ),
                   ),
-                ),
-                if (!isDesktop)
-                  const Spacer(
-                    flex: 4,
-                  ),
-                if (isDesktop)
-                  const SizedBox(
-                    height: 32,
-                  ),
-                Padding(
-                  padding: isDesktop
-                      ? const EdgeInsets.all(0)
-                      : const EdgeInsets.symmetric(
-                          horizontal: 16,
-                          vertical: 16,
-                        ),
-                  child: Row(
-                    children: [
-                      Expanded(
-                        child: PrimaryButton(
-                          label:
-                              !widget.isSettings ? "Continue" : "Save changes",
-                          onPressed: () {
-                            ref
-                                .read(prefsChangeNotifierProvider)
-                                .externalCalls = isEasy;
+                  if (!isDesktop)
+                    const Spacer(
+                      flex: 4,
+                    ),
+                  if (isDesktop)
+                    const SizedBox(
+                      height: 32,
+                    ),
+                  Padding(
+                    padding: isDesktop
+                        ? const EdgeInsets.all(0)
+                        : const EdgeInsets.symmetric(
+                            horizontal: 16,
+                            vertical: 16,
+                          ),
+                    child: Row(
+                      children: [
+                        Expanded(
+                          child: PrimaryButton(
+                            label:
+                                !widget.isSettings ? "Continue" : "Save changes",
+                            onPressed: () {
+                              ref
+                                  .read(prefsChangeNotifierProvider)
+                                  .externalCalls = isEasy;
 
-                            DB.instance
-                                .put<dynamic>(
-                                    boxName: DB.boxNamePrefs,
-                                    key: "externalCalls",
-                                    value: isEasy)
-                                .then((_) {
-                              if (isEasy) {
-                                unawaited(
-                                    ExchangeDataLoadingService().loadAll(ref));
-                                ref
-                                    .read(priceAnd24hChangeNotifierProvider)
-                                    .start(true);
-                              }
-                            });
-                            if (!widget.isSettings) {
-                              if (isDesktop) {
-                                Navigator.of(context).pushNamed(
-                                  CreatePasswordView.routeName,
-                                );
+                              DB.instance
+                                  .put<dynamic>(
+                                      boxName: DB.boxNamePrefs,
+                                      key: "externalCalls",
+                                      value: isEasy)
+                                  .then((_) {
+                                if (isEasy) {
+                                  unawaited(
+                                      ExchangeDataLoadingService().loadAll(ref));
+                                  ref
+                                      .read(priceAnd24hChangeNotifierProvider)
+                                      .start(true);
+                                }
+                              });
+                              if (!widget.isSettings) {
+                                if (isDesktop) {
+                                  Navigator.of(context).pushNamed(
+                                    CreatePasswordView.routeName,
+                                  );
+                                } else {
+                                  Navigator.of(context).pushNamed(
+                                    CreatePinView.routeName,
+                                  );
+                                }
                               } else {
-                                Navigator.of(context).pushNamed(
-                                  CreatePinView.routeName,
-                                );
+                                Navigator.pop(context);
                               }
-                            } else {
-                              Navigator.pop(context);
-                            }
-                          },
+                            },
+                          ),
                         ),
-                      ),
-                    ],
+                      ],
+                    ),
                   ),
-                ),
-                if (isDesktop)
-                  const SizedBox(
-                    height: kDesktopAppBarHeight,
-                  ),
-              ],
+                  if (isDesktop)
+                    const SizedBox(
+                      height: kDesktopAppBarHeight,
+                    ),
+                ],
+              ),
             ),
           ),
         ),
@@ -494,158 +510,3 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
     );
   }
 }
-
-// class ContinueButton extends ConsumerWidget {
-//   const ContinueButton({
-//     Key? key,
-//     required this.isDesktop,
-//     required this.onPressed,
-//     required this.label,
-//   }) : super(key: key);
-//
-//   final String label;
-//   final bool isDesktop;
-//   final VoidCallback onPressed;
-//
-//   @override
-//   Widget build(BuildContext context, WidgetRef ref) {
-//     if (isDesktop) {
-//       return SizedBox(
-//         width: 328,
-//         height: 70,
-//         child: TextButton(
-//           style: Theme.of(context)
-//               .extension<StackColors>()!
-//               .getPrimaryEnabledButtonColor(context),
-//           onPressed: onPressed,
-//           child: Text(
-//             label,
-//             style: STextStyles.button(context).copyWith(fontSize: 20),
-//           ),
-//         ),
-//       );
-//     } else {
-//       return TextButton(
-//         style: Theme.of(context)
-//             .extension<StackColors>()!
-//             .getPrimaryEnabledButtonColor(context),
-//         onPressed: onPressed,
-//         child: Text(
-//           label,
-//           style: STextStyles.button(context),
-//         ),
-//       );
-//     }
-//   }
-// }
-
-// class CustomRadio extends StatefulWidget {
-//   CustomRadio(this.upperCall, {Key? key}) : super(key: key);
-//
-//   Function upperCall;
-//
-//   @override
-//   createState() {
-//     return CustomRadioState();
-//   }
-// }
-//
-// class CustomRadioState extends State<CustomRadio> {
-//   List<RadioModel> sampleData = <RadioModel>[];
-//
-//   @override
-//   void initState() {
-//     super.initState();
-//     sampleData.add(
-//         RadioModel(true, Assets.svg.personaEasy, 'Easy Crypto', 'Recommended'));
-//     sampleData.add(RadioModel(
-//         false, Assets.svg.personaIncognito, 'Incognito', 'Privacy conscious'));
-//   }
-//
-//   @override
-//   Widget build(BuildContext context) {
-//     return Row(
-//       mainAxisAlignment: MainAxisAlignment.center,
-//       children: [
-//         InkWell(
-//           onTap: () {
-//             setState(() {
-//               // if (!sampleData[0].isSelected) {
-//               widget.upperCall.call(true);
-//               // }
-//               for (var element in sampleData) {
-//                 element.isSelected = false;
-//               }
-//               sampleData[0].isSelected = true;
-//             });
-//           },
-//           child: RadioItem(sampleData[0]),
-//         ),
-//         InkWell(
-//           onTap: () {
-//             setState(() {
-//               // if (!sampleData[1].isSelected) {
-//               widget.upperCall.call(false);
-//               // }
-//               for (var element in sampleData) {
-//                 element.isSelected = false;
-//               }
-//               sampleData[1].isSelected = true;
-//             });
-//           },
-//           child: RadioItem(sampleData[1]),
-//         )
-//       ],
-//     );
-//   }
-// }
-//
-// class RadioItem extends StatelessWidget {
-//   final RadioModel _item;
-//   const RadioItem(this._item, {Key? key}) : super(key: key);
-//   @override
-//   Widget build(BuildContext context) {
-//     return Container(
-//       margin: const EdgeInsets.all(15.0),
-//       child: RoundedWhiteContainer(
-//         borderColor: _item.isSelected ? const Color(0xFF0056D2) : null,
-//         child: Center(
-//             child: Column(
-//           children: [
-//             SvgPicture.asset(
-//               _item.svg,
-//               // color: Theme.of(context).extension<StackColors>()!.textWhite,
-//               width: 140,
-//               height: 140,
-//             ),
-//             RichText(
-//               textAlign: TextAlign.center,
-//               text: TextSpan(
-//                 style: STextStyles.label(context).copyWith(fontSize: 12.0),
-//                 children: [
-//                   TextSpan(
-//                       text: _item.topText,
-//                       style: TextStyle(
-//                           color: Theme.of(context)
-//                               .extension<StackColors>()!
-//                               .textDark,
-//                           fontWeight: FontWeight.bold)),
-//                   TextSpan(text: "\n${_item.bottomText}"),
-//                 ],
-//               ),
-//             ),
-//           ],
-//         )),
-//       ),
-//     );
-//   }
-// }
-//
-// class RadioModel {
-//   bool isSelected;
-//   final String svg;
-//   final String topText;
-//   final String bottomText;
-//
-//   RadioModel(this.isSelected, this.svg, this.topText, this.bottomText);
-// }

From 9231c3a2a59a3322ca0e8ed1bb6eaed1cbeff611 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 3 Nov 2022 18:11:51 -0600
Subject: [PATCH 128/426] all transactions search field fix for mobile

---
 .../all_transactions_view.dart                | 131 ++++++++++--------
 1 file changed, 71 insertions(+), 60 deletions(-)

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 8604ae721..d41877a9a 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -21,6 +21,7 @@ import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -302,68 +303,78 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
               padding: const EdgeInsets.all(4),
               child: Row(
                 children: [
-                  SizedBox(
-                    width: isDesktop ? 570 : null,
-                    child: ClipRRect(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
+                  ConditionalParent(
+                    condition: isDesktop,
+                    builder: (child) => SizedBox(
+                      width: 570,
+                      child: child,
+                    ),
+                    child: ConditionalParent(
+                      condition: !isDesktop,
+                      builder: (child) => Expanded(
+                        child: child,
                       ),
-                      child: TextField(
-                        autocorrect: !isDesktop,
-                        enableSuggestions: !isDesktop,
-                        controller: _searchController,
-                        focusNode: searchFieldFocusNode,
-                        onChanged: (value) {
-                          setState(() {
-                            _searchString = value;
-                          });
-                        },
-                        style: isDesktop
-                            ? STextStyles.desktopTextExtraSmall(context)
-                                .copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textFieldActiveText,
-                                height: 1.8,
-                              )
-                            : STextStyles.field(context),
-                        decoration: standardInputDecoration(
-                          "Search...",
-                          searchFieldFocusNode,
-                          context,
-                          desktopMed: isDesktop,
-                        ).copyWith(
-                          prefixIcon: Padding(
-                            padding: EdgeInsets.symmetric(
-                              horizontal: isDesktop ? 12 : 10,
-                              vertical: isDesktop ? 18 : 16,
-                            ),
-                            child: SvgPicture.asset(
-                              Assets.svg.search,
-                              width: isDesktop ? 20 : 16,
-                              height: isDesktop ? 20 : 16,
-                            ),
-                          ),
-                          suffixIcon: _searchController.text.isNotEmpty
-                              ? Padding(
-                                  padding: const EdgeInsets.only(right: 0),
-                                  child: UnconstrainedBox(
-                                    child: Row(
-                                      children: [
-                                        TextFieldIconButton(
-                                          child: const XIcon(),
-                                          onTap: () async {
-                                            setState(() {
-                                              _searchController.text = "";
-                                              _searchString = "";
-                                            });
-                                          },
-                                        ),
-                                      ],
-                                    ),
-                                  ),
+                      child: ClipRRect(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                        child: TextField(
+                          autocorrect: !isDesktop,
+                          enableSuggestions: !isDesktop,
+                          controller: _searchController,
+                          focusNode: searchFieldFocusNode,
+                          onChanged: (value) {
+                            setState(() {
+                              _searchString = value;
+                            });
+                          },
+                          style: isDesktop
+                              ? STextStyles.desktopTextExtraSmall(context)
+                                  .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textFieldActiveText,
+                                  height: 1.8,
                                 )
-                              : null,
+                              : STextStyles.field(context),
+                          decoration: standardInputDecoration(
+                            "Search...",
+                            searchFieldFocusNode,
+                            context,
+                            desktopMed: isDesktop,
+                          ).copyWith(
+                            prefixIcon: Padding(
+                              padding: EdgeInsets.symmetric(
+                                horizontal: isDesktop ? 12 : 10,
+                                vertical: isDesktop ? 18 : 16,
+                              ),
+                              child: SvgPicture.asset(
+                                Assets.svg.search,
+                                width: isDesktop ? 20 : 16,
+                                height: isDesktop ? 20 : 16,
+                              ),
+                            ),
+                            suffixIcon: _searchController.text.isNotEmpty
+                                ? Padding(
+                                    padding: const EdgeInsets.only(right: 0),
+                                    child: UnconstrainedBox(
+                                      child: Row(
+                                        children: [
+                                          TextFieldIconButton(
+                                            child: const XIcon(),
+                                            onTap: () async {
+                                              setState(() {
+                                                _searchController.text = "";
+                                                _searchString = "";
+                                              });
+                                            },
+                                          ),
+                                        ],
+                                      ),
+                                    ),
+                                  )
+                                : null,
+                          ),
                         ),
                       ),
                     ),

From a6c380592e7e9a335ef033a13d9d0b5e2d21d6b1 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 4 Nov 2022 14:18:54 -0600
Subject: [PATCH 129/426] added conditional for desktop manual and restore
 backup

---
 .../create_backup_view.dart                   | 821 +++++++++---------
 .../restore_from_file_view.dart               | 537 ++++++------
 2 files changed, 695 insertions(+), 663 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 9242c0482..b710aacf4 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -15,6 +15,7 @@ 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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -93,426 +94,436 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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(
-          "Create backup",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      if (!Platform.isAndroid)
-                        Consumer(builder: (context, ref, __) {
-                          return Container(
-                            color: Colors.transparent,
-                            child: TextField(
-                              autocorrect: Util.isDesktop ? false : true,
-                              enableSuggestions: Util.isDesktop ? false : true,
-                              onTap: Platform.isAndroid
-                                  ? null
-                                  : () async {
-                                      try {
-                                        await stackFileSystem.prepareStorage();
+    final isDesktop = Util.isDesktop;
 
-                                        if (mounted) {
-                                          await stackFileSystem
-                                              .pickDir(context);
-                                        }
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            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(
+              "Create backup",
+              style: STextStyles.navBarTitle(context),
+            ),
+          ),
+          body: Padding(
+            padding: const EdgeInsets.all(16),
+            child: LayoutBuilder(
+              builder: (context, constraints) {
+                return SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight,
+                    ),
+                    child: IntrinsicHeight(
+                      child: child,
+                    ),
+                  ),
+                );
+              },
+            ),
+          ),
+        );
+      },
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) {
+          return Column(
+            children: [
+              Text(
+                "Choose file location",
+                style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.textDark3),
+              ),
+              // child,
+            ],
+          );
+        },
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: [
+            if (!Platform.isAndroid)
+              Consumer(builder: (context, ref, __) {
+                return Container(
+                  color: Colors.transparent,
+                  child: TextField(
+                    autocorrect: Util.isDesktop ? false : true,
+                    enableSuggestions: Util.isDesktop ? false : true,
+                    onTap: Platform.isAndroid
+                        ? null
+                        : () async {
+                            try {
+                              await stackFileSystem.prepareStorage();
 
-                                        if (mounted) {
-                                          setState(() {
-                                            fileLocationController.text =
-                                                stackFileSystem.dirPath ?? "";
-                                          });
-                                        }
-                                      } catch (e, s) {
-                                        Logging.instance.log("$e\n$s",
-                                            level: LogLevel.Error);
-                                      }
-                                    },
-                              controller: fileLocationController,
-                              style: STextStyles.field(context),
-                              decoration: InputDecoration(
-                                hintText: "Save to...",
-                                hintStyle: STextStyles.fieldLabel(context),
-                                suffixIcon: UnconstrainedBox(
-                                  child: Row(
-                                    children: [
-                                      const SizedBox(
-                                        width: 16,
-                                      ),
-                                      SvgPicture.asset(
-                                        Assets.svg.folder,
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textDark3,
-                                        width: 16,
-                                        height: 16,
-                                      ),
-                                      const SizedBox(
-                                        width: 12,
-                                      ),
-                                    ],
-                                  ),
-                                ),
-                              ),
-                              key: const Key(
-                                  "createBackupSaveToFileLocationTextFieldKey"),
-                              readOnly: true,
-                              toolbarOptions: const ToolbarOptions(
-                                copy: true,
-                                cut: false,
-                                paste: false,
-                                selectAll: false,
-                              ),
-                              onChanged: (newValue) {
-                                // ref.read(addressEntryDataProvider(widget.id)).address = newValue;
-                              },
+                              if (mounted) {
+                                await stackFileSystem.pickDir(context);
+                              }
+
+                              if (mounted) {
+                                setState(() {
+                                  fileLocationController.text =
+                                      stackFileSystem.dirPath ?? "";
+                                });
+                              }
+                            } catch (e, s) {
+                              Logging.instance
+                                  .log("$e\n$s", level: LogLevel.Error);
+                            }
+                          },
+                    controller: fileLocationController,
+                    style: STextStyles.field(context),
+                    decoration: InputDecoration(
+                      hintText: "Save to...",
+                      hintStyle: STextStyles.fieldLabel(context),
+                      suffixIcon: UnconstrainedBox(
+                        child: Row(
+                          children: [
+                            const SizedBox(
+                              width: 16,
                             ),
-                          );
-                        }),
-                      if (!Platform.isAndroid)
+                            SvgPicture.asset(
+                              Assets.svg.folder,
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark3,
+                              width: 16,
+                              height: 16,
+                            ),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                    key:
+                        const Key("createBackupSaveToFileLocationTextFieldKey"),
+                    readOnly: true,
+                    toolbarOptions: const ToolbarOptions(
+                      copy: true,
+                      cut: false,
+                      paste: false,
+                      selectAll: false,
+                    ),
+                    onChanged: (newValue) {
+                      // ref.read(addressEntryDataProvider(widget.id)).address = newValue;
+                    },
+                  ),
+                );
+              }),
+            if (!Platform.isAndroid)
+              const SizedBox(
+                height: 8,
+              ),
+            ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                key: const Key("createBackupPasswordFieldKey1"),
+                focusNode: passwordFocusNode,
+                controller: passwordController,
+                style: STextStyles.field(context),
+                obscureText: hidePassword,
+                enableSuggestions: false,
+                autocorrect: false,
+                decoration: standardInputDecoration(
+                  "Create passphrase",
+                  passwordFocusNode,
+                  context,
+                ).copyWith(
+                  suffixIcon: UnconstrainedBox(
+                    child: Row(
+                      children: [
                         const SizedBox(
-                          height: 8,
+                          width: 16,
                         ),
-                      ClipRRect(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
-                        ),
-                        child: TextField(
-                          key: const Key("createBackupPasswordFieldKey1"),
-                          focusNode: passwordFocusNode,
-                          controller: passwordController,
-                          style: STextStyles.field(context),
-                          obscureText: hidePassword,
-                          enableSuggestions: false,
-                          autocorrect: false,
-                          decoration: standardInputDecoration(
-                            "Create passphrase",
-                            passwordFocusNode,
-                            context,
-                          ).copyWith(
-                            suffixIcon: UnconstrainedBox(
-                              child: Row(
-                                children: [
-                                  const SizedBox(
-                                    width: 16,
-                                  ),
-                                  GestureDetector(
-                                    key: const Key(
-                                        "createBackupPasswordFieldShowPasswordButtonKey"),
-                                    onTap: () async {
-                                      setState(() {
-                                        hidePassword = !hidePassword;
-                                      });
-                                    },
-                                    child: SvgPicture.asset(
-                                      hidePassword
-                                          ? Assets.svg.eye
-                                          : Assets.svg.eyeSlash,
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textDark3,
-                                      width: 16,
-                                      height: 16,
-                                    ),
-                                  ),
-                                  const SizedBox(
-                                    width: 12,
-                                  ),
-                                ],
-                              ),
-                            ),
-                          ),
-                          onChanged: (newValue) {
-                            if (newValue.isEmpty) {
-                              setState(() {
-                                passwordFeedback = "";
-                              });
-                              return;
-                            }
-                            final result = zxcvbn.evaluate(newValue);
-                            String suggestionsAndTips = "";
-                            for (var sug
-                                in result.feedback.suggestions!.toSet()) {
-                              suggestionsAndTips += "$sug\n";
-                            }
-                            suggestionsAndTips += result.feedback.warning!;
-                            String feedback =
-                                // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
-                                suggestionsAndTips;
-
-                            passwordStrength = result.score! / 4;
-
-                            // hack fix to format back string returned from zxcvbn
-                            if (feedback.contains("phrasesNo need")) {
-                              feedback = feedback.replaceFirst(
-                                  "phrasesNo need", "phrases\nNo need");
-                            }
-
-                            if (feedback.endsWith("\n")) {
-                              feedback =
-                                  feedback.substring(0, feedback.length - 2);
-                            }
-
+                        GestureDetector(
+                          key: const Key(
+                              "createBackupPasswordFieldShowPasswordButtonKey"),
+                          onTap: () async {
                             setState(() {
-                              passwordFeedback = feedback;
+                              hidePassword = !hidePassword;
                             });
                           },
-                        ),
-                      ),
-                      if (passwordFocusNode.hasFocus ||
-                          passwordRepeatFocusNode.hasFocus ||
-                          passwordController.text.isNotEmpty)
-                        Padding(
-                          padding: EdgeInsets.only(
-                            left: 12,
-                            right: 12,
-                            top: passwordFeedback.isNotEmpty ? 4 : 0,
-                          ),
-                          child: passwordFeedback.isNotEmpty
-                              ? Text(
-                                  passwordFeedback,
-                                  style: STextStyles.infoSmall(context),
-                                )
-                              : null,
-                        ),
-                      if (passwordFocusNode.hasFocus ||
-                          passwordRepeatFocusNode.hasFocus ||
-                          passwordController.text.isNotEmpty)
-                        Padding(
-                          padding: const EdgeInsets.only(
-                            left: 12,
-                            right: 12,
-                            top: 10,
-                          ),
-                          child: ProgressBar(
-                            key: const Key("createStackBackUpProgressBar"),
-                            width: MediaQuery.of(context).size.width - 32 - 24,
-                            height: 5,
-                            fillColor: passwordStrength < 0.51
-                                ? Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorRed
-                                : passwordStrength < 1
-                                    ? Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .accentColorYellow
-                                    : Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .accentColorGreen,
-                            backgroundColor: Theme.of(context)
+                          child: SvgPicture.asset(
+                            hidePassword ? Assets.svg.eye : Assets.svg.eyeSlash,
+                            color: Theme.of(context)
                                 .extension<StackColors>()!
-                                .buttonBackSecondary,
-                            percent: passwordStrength < 0.25
-                                ? 0.03
-                                : passwordStrength,
+                                .textDark3,
+                            width: 16,
+                            height: 16,
                           ),
                         ),
-                      const SizedBox(
-                        height: 10,
-                      ),
-                      ClipRRect(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
+                        const SizedBox(
+                          width: 12,
                         ),
-                        child: TextField(
-                          key: const Key("createBackupPasswordFieldKey2"),
-                          focusNode: passwordRepeatFocusNode,
-                          controller: passwordRepeatController,
-                          style: STextStyles.field(context),
-                          obscureText: hidePassword,
-                          enableSuggestions: false,
-                          autocorrect: false,
-                          decoration: standardInputDecoration(
-                            "Confirm passphrase",
-                            passwordRepeatFocusNode,
-                            context,
-                          ).copyWith(
-                            suffixIcon: UnconstrainedBox(
-                              child: Row(
-                                children: [
-                                  const SizedBox(
-                                    width: 16,
-                                  ),
-                                  GestureDetector(
-                                    key: const Key(
-                                        "createBackupPasswordFieldShowPasswordButtonKey"),
-                                    onTap: () async {
-                                      setState(() {
-                                        hidePassword = !hidePassword;
-                                      });
-                                    },
-                                    child: SvgPicture.asset(
-                                      hidePassword
-                                          ? Assets.svg.eye
-                                          : Assets.svg.eyeSlash,
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textDark3,
-                                      width: 16,
-                                      height: 16,
-                                    ),
-                                  ),
-                                  const SizedBox(
-                                    width: 12,
-                                  ),
-                                ],
-                              ),
-                            ),
-                          ),
-                          onChanged: (newValue) {
-                            setState(() {});
-                            // TODO: ? check if passwords match?
-                          },
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 16,
-                      ),
-                      const Spacer(),
-                      TextButton(
-                        style: shouldEnableCreate
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .getPrimaryEnabledButtonColor(context)
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .getPrimaryDisabledButtonColor(context),
-                        onPressed: !shouldEnableCreate
-                            ? null
-                            : () async {
-                                final String pathToSave =
-                                    fileLocationController.text;
-                                final String passphrase =
-                                    passwordController.text;
-                                final String repeatPassphrase =
-                                    passwordRepeatController.text;
-
-                                if (pathToSave.isEmpty) {
-                                  unawaited(showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "Directory not chosen",
-                                    context: context,
-                                  ));
-                                  return;
-                                }
-                                if (!(await Directory(pathToSave).exists())) {
-                                  unawaited(showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "Directory does not exist",
-                                    context: context,
-                                  ));
-                                  return;
-                                }
-                                if (passphrase.isEmpty) {
-                                  unawaited(showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "A passphrase is required",
-                                    context: context,
-                                  ));
-                                  return;
-                                }
-                                if (passphrase != repeatPassphrase) {
-                                  unawaited(showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "Passphrase does not match",
-                                    context: context,
-                                  ));
-                                  return;
-                                }
-
-                                unawaited(showDialog<dynamic>(
-                                  context: context,
-                                  barrierDismissible: false,
-                                  builder: (_) => const StackDialog(
-                                    title: "Encrypting backup",
-                                    message: "This shouldn't take long",
-                                  ),
-                                ));
-                                // make sure the dialog is able to be displayed for at least 1 second
-                                await Future<void>.delayed(
-                                    const Duration(seconds: 1));
-
-                                final DateTime now = DateTime.now();
-                                final String fileToSave =
-                                    "$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
-
-                                final backup =
-                                    await SWB.createStackWalletJSON();
-
-                                bool result =
-                                    await SWB.encryptStackWalletWithPassphrase(
-                                  fileToSave,
-                                  passphrase,
-                                  jsonEncode(backup),
-                                );
-
-                                if (mounted) {
-                                  // pop encryption progress dialog
-                                  Navigator.of(context).pop();
-
-                                  if (result) {
-                                    await showDialog<dynamic>(
-                                      context: context,
-                                      barrierDismissible: false,
-                                      builder: (_) => Platform.isAndroid
-                                          ? StackOkDialog(
-                                              title: "Backup saved to:",
-                                              message: fileToSave,
-                                            )
-                                          : const StackOkDialog(
-                                              title:
-                                                  "Backup creation succeeded"),
-                                    );
-                                    passwordController.text = "";
-                                    passwordRepeatController.text = "";
-                                    setState(() {});
-                                  } else {
-                                    await showDialog<dynamic>(
-                                      context: context,
-                                      barrierDismissible: false,
-                                      builder: (_) => const StackOkDialog(
-                                          title: "Backup creation failed"),
-                                    );
-                                  }
-                                }
-                              },
-                        child: Text(
-                          "Create backup",
-                          style: STextStyles.button(context),
-                        ),
-                      ),
-                    ],
+                      ],
+                    ),
                   ),
                 ),
+                onChanged: (newValue) {
+                  if (newValue.isEmpty) {
+                    setState(() {
+                      passwordFeedback = "";
+                    });
+                    return;
+                  }
+                  final result = zxcvbn.evaluate(newValue);
+                  String suggestionsAndTips = "";
+                  for (var sug in result.feedback.suggestions!.toSet()) {
+                    suggestionsAndTips += "$sug\n";
+                  }
+                  suggestionsAndTips += result.feedback.warning!;
+                  String feedback =
+                      // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
+                      suggestionsAndTips;
+
+                  passwordStrength = result.score! / 4;
+
+                  // hack fix to format back string returned from zxcvbn
+                  if (feedback.contains("phrasesNo need")) {
+                    feedback = feedback.replaceFirst(
+                        "phrasesNo need", "phrases\nNo need");
+                  }
+
+                  if (feedback.endsWith("\n")) {
+                    feedback = feedback.substring(0, feedback.length - 2);
+                  }
+
+                  setState(() {
+                    passwordFeedback = feedback;
+                  });
+                },
               ),
-            );
-          },
+            ),
+            if (passwordFocusNode.hasFocus ||
+                passwordRepeatFocusNode.hasFocus ||
+                passwordController.text.isNotEmpty)
+              Padding(
+                padding: EdgeInsets.only(
+                  left: 12,
+                  right: 12,
+                  top: passwordFeedback.isNotEmpty ? 4 : 0,
+                ),
+                child: passwordFeedback.isNotEmpty
+                    ? Text(
+                        passwordFeedback,
+                        style: STextStyles.infoSmall(context),
+                      )
+                    : null,
+              ),
+            if (passwordFocusNode.hasFocus ||
+                passwordRepeatFocusNode.hasFocus ||
+                passwordController.text.isNotEmpty)
+              Padding(
+                padding: const EdgeInsets.only(
+                  left: 12,
+                  right: 12,
+                  top: 10,
+                ),
+                child: ProgressBar(
+                  key: const Key("createStackBackUpProgressBar"),
+                  width: MediaQuery.of(context).size.width - 32 - 24,
+                  height: 5,
+                  fillColor: passwordStrength < 0.51
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorRed
+                      : passwordStrength < 1
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorYellow
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorGreen,
+                  backgroundColor: Theme.of(context)
+                      .extension<StackColors>()!
+                      .buttonBackSecondary,
+                  percent: passwordStrength < 0.25 ? 0.03 : passwordStrength,
+                ),
+              ),
+            const SizedBox(
+              height: 10,
+            ),
+            ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                key: const Key("createBackupPasswordFieldKey2"),
+                focusNode: passwordRepeatFocusNode,
+                controller: passwordRepeatController,
+                style: STextStyles.field(context),
+                obscureText: hidePassword,
+                enableSuggestions: false,
+                autocorrect: false,
+                decoration: standardInputDecoration(
+                  "Confirm passphrase",
+                  passwordRepeatFocusNode,
+                  context,
+                ).copyWith(
+                  suffixIcon: UnconstrainedBox(
+                    child: Row(
+                      children: [
+                        const SizedBox(
+                          width: 16,
+                        ),
+                        GestureDetector(
+                          key: const Key(
+                              "createBackupPasswordFieldShowPasswordButtonKey"),
+                          onTap: () async {
+                            setState(() {
+                              hidePassword = !hidePassword;
+                            });
+                          },
+                          child: SvgPicture.asset(
+                            hidePassword ? Assets.svg.eye : Assets.svg.eyeSlash,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark3,
+                            width: 16,
+                            height: 16,
+                          ),
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                      ],
+                    ),
+                  ),
+                ),
+                onChanged: (newValue) {
+                  setState(() {});
+                  // TODO: ? check if passwords match?
+                },
+              ),
+            ),
+            const SizedBox(
+              height: 16,
+            ),
+            const Spacer(),
+            TextButton(
+              style: shouldEnableCreate
+                  ? Theme.of(context)
+                      .extension<StackColors>()!
+                      .getPrimaryEnabledButtonColor(context)
+                  : Theme.of(context)
+                      .extension<StackColors>()!
+                      .getPrimaryDisabledButtonColor(context),
+              onPressed: !shouldEnableCreate
+                  ? null
+                  : () async {
+                      final String pathToSave = fileLocationController.text;
+                      final String passphrase = passwordController.text;
+                      final String repeatPassphrase =
+                          passwordRepeatController.text;
+
+                      if (pathToSave.isEmpty) {
+                        unawaited(showFloatingFlushBar(
+                          type: FlushBarType.warning,
+                          message: "Directory not chosen",
+                          context: context,
+                        ));
+                        return;
+                      }
+                      if (!(await Directory(pathToSave).exists())) {
+                        unawaited(showFloatingFlushBar(
+                          type: FlushBarType.warning,
+                          message: "Directory does not exist",
+                          context: context,
+                        ));
+                        return;
+                      }
+                      if (passphrase.isEmpty) {
+                        unawaited(showFloatingFlushBar(
+                          type: FlushBarType.warning,
+                          message: "A passphrase is required",
+                          context: context,
+                        ));
+                        return;
+                      }
+                      if (passphrase != repeatPassphrase) {
+                        unawaited(showFloatingFlushBar(
+                          type: FlushBarType.warning,
+                          message: "Passphrase does not match",
+                          context: context,
+                        ));
+                        return;
+                      }
+
+                      unawaited(showDialog<dynamic>(
+                        context: context,
+                        barrierDismissible: false,
+                        builder: (_) => const StackDialog(
+                          title: "Encrypting backup",
+                          message: "This shouldn't take long",
+                        ),
+                      ));
+                      // make sure the dialog is able to be displayed for at least 1 second
+                      await Future<void>.delayed(const Duration(seconds: 1));
+
+                      final DateTime now = DateTime.now();
+                      final String fileToSave =
+                          "$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
+
+                      final backup = await SWB.createStackWalletJSON();
+
+                      bool result = await SWB.encryptStackWalletWithPassphrase(
+                        fileToSave,
+                        passphrase,
+                        jsonEncode(backup),
+                      );
+
+                      if (mounted) {
+                        // pop encryption progress dialog
+                        Navigator.of(context).pop();
+
+                        if (result) {
+                          await showDialog<dynamic>(
+                            context: context,
+                            barrierDismissible: false,
+                            builder: (_) => Platform.isAndroid
+                                ? StackOkDialog(
+                                    title: "Backup saved to:",
+                                    message: fileToSave,
+                                  )
+                                : const StackOkDialog(
+                                    title: "Backup creation succeeded"),
+                          );
+                          passwordController.text = "";
+                          passwordRepeatController.text = "";
+                          setState(() {});
+                        } else {
+                          await showDialog<dynamic>(
+                            context: context,
+                            barrierDismissible: false,
+                            builder: (_) => const StackOkDialog(
+                                title: "Backup creation failed"),
+                          );
+                        }
+                      }
+                    },
+              child: Text(
+                "Create backup",
+                style: STextStyles.button(context),
+              ),
+            ),
+          ],
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index 232be9028..16c3ea8e3 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -15,13 +15,13 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:tuple/tuple.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class RestoreFromFileView extends ConsumerStatefulWidget {
   const RestoreFromFileView({Key? key}) : super(key: key);
 
@@ -65,275 +65,296 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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(
-          "Restore from file",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      TextField(
-                        autocorrect: Util.isDesktop ? false : true,
-                        enableSuggestions: Util.isDesktop ? false : true,
-                        onTap: () async {
-                          try {
-                            await stackFileSystem.prepareStorage();
-                            if (mounted) {
-                              await stackFileSystem.openFile(context);
-                            }
+    final isDesktop = Util.isDesktop;
 
-                            if (mounted) {
+    return ConditionalParent(
+        condition: !isDesktop,
+        builder: (child) {
+          return Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              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(
+                "Restore from file",
+                style: STextStyles.navBarTitle(context),
+              ),
+            ),
+            body: Padding(
+              padding: const EdgeInsets.all(16),
+              child: LayoutBuilder(
+                builder: (context, constraints) {
+                  return SingleChildScrollView(
+                    child: ConstrainedBox(
+                      constraints: BoxConstraints(
+                        minHeight: constraints.maxHeight,
+                      ),
+                      child: IntrinsicHeight(
+                        child: child,
+                      ),
+                    ),
+                  );
+                },
+              ),
+            ),
+          );
+        },
+        child: ConditionalParent(
+          condition: isDesktop,
+          builder: (child) {
+            return Column(
+              children: [
+                Text(
+                  "Choose file location",
+                  style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textDark3),
+                ),
+                // child,
+              ],
+            );
+          },
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
+                onTap: () async {
+                  try {
+                    await stackFileSystem.prepareStorage();
+                    if (mounted) {
+                      await stackFileSystem.openFile(context);
+                    }
+
+                    if (mounted) {
+                      setState(() {
+                        fileLocationController.text =
+                            stackFileSystem.filePath ?? "";
+                      });
+                    }
+                  } catch (e, s) {
+                    Logging.instance.log("$e\n$s", level: LogLevel.Error);
+                  }
+                },
+                controller: fileLocationController,
+                style: STextStyles.field(context),
+                decoration: InputDecoration(
+                  hintText: "Choose file...",
+                  hintStyle: STextStyles.fieldLabel(context),
+                  suffixIcon: UnconstrainedBox(
+                    child: Row(
+                      children: [
+                        const SizedBox(
+                          width: 16,
+                        ),
+                        SvgPicture.asset(
+                          Assets.svg.folder,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark3,
+                          width: 16,
+                          height: 16,
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                      ],
+                    ),
+                  ),
+                ),
+                key: const Key("restoreFromFileLocationTextFieldKey"),
+                readOnly: true,
+                toolbarOptions: const ToolbarOptions(
+                  copy: true,
+                  cut: false,
+                  paste: false,
+                  selectAll: false,
+                ),
+                onChanged: (newValue) {},
+              ),
+              const SizedBox(
+                height: 8,
+              ),
+              ClipRRect(
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
+                child: TextField(
+                  key: const Key("restoreFromFilePasswordFieldKey"),
+                  focusNode: passwordFocusNode,
+                  controller: passwordController,
+                  style: STextStyles.field(context),
+                  obscureText: hidePassword,
+                  enableSuggestions: false,
+                  autocorrect: false,
+                  decoration: standardInputDecoration(
+                    "Enter password",
+                    passwordFocusNode,
+                    context,
+                  ).copyWith(
+                    suffixIcon: UnconstrainedBox(
+                      child: Row(
+                        children: [
+                          const SizedBox(
+                            width: 16,
+                          ),
+                          GestureDetector(
+                            key: const Key(
+                                "restoreFromFilePasswordFieldShowPasswordButtonKey"),
+                            onTap: () async {
                               setState(() {
-                                fileLocationController.text =
-                                    stackFileSystem.filePath ?? "";
+                                hidePassword = !hidePassword;
                               });
-                            }
-                          } catch (e, s) {
-                            Logging.instance
-                                .log("$e\n$s", level: LogLevel.Error);
-                          }
-                        },
-                        controller: fileLocationController,
-                        style: STextStyles.field(context),
-                        decoration: InputDecoration(
-                          hintText: "Choose file...",
-                          hintStyle: STextStyles.fieldLabel(context),
-                          suffixIcon: UnconstrainedBox(
-                            child: Row(
+                            },
+                            child: SvgPicture.asset(
+                              hidePassword
+                                  ? Assets.svg.eye
+                                  : Assets.svg.eyeSlash,
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark3,
+                              width: 16,
+                              height: 16,
+                            ),
+                          ),
+                          const SizedBox(
+                            width: 12,
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                  onChanged: (newValue) {
+                    setState(() {});
+                  },
+                ),
+              ),
+              const SizedBox(
+                height: 16,
+              ),
+              const Spacer(),
+              TextButton(
+                style: passwordController.text.isEmpty ||
+                        fileLocationController.text.isEmpty
+                    ? Theme.of(context)
+                        .extension<StackColors>()!
+                        .getPrimaryDisabledButtonColor(context)
+                    : Theme.of(context)
+                        .extension<StackColors>()!
+                        .getPrimaryEnabledButtonColor(context),
+                onPressed: passwordController.text.isEmpty ||
+                        fileLocationController.text.isEmpty
+                    ? null
+                    : () async {
+                        final String fileToRestore =
+                            fileLocationController.text;
+                        final String passphrase = passwordController.text;
+
+                        if (FocusScope.of(context).hasFocus) {
+                          FocusScope.of(context).unfocus();
+                          await Future<void>.delayed(
+                              const Duration(milliseconds: 75));
+                        }
+
+                        if (!(await File(fileToRestore).exists())) {
+                          showFloatingFlushBar(
+                            type: FlushBarType.warning,
+                            message: "Backup file does not exist",
+                            context: context,
+                          );
+                          return;
+                        }
+
+                        bool shouldPop = false;
+                        showDialog<dynamic>(
+                          barrierDismissible: false,
+                          context: context,
+                          builder: (_) => WillPopScope(
+                            onWillPop: () async {
+                              return shouldPop;
+                            },
+                            child: Column(
+                              crossAxisAlignment: CrossAxisAlignment.stretch,
+                              mainAxisAlignment: MainAxisAlignment.center,
                               children: [
-                                const SizedBox(
-                                  width: 16,
-                                ),
-                                SvgPicture.asset(
-                                  Assets.svg.folder,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark3,
-                                  width: 16,
-                                  height: 16,
+                                Material(
+                                  color: Colors.transparent,
+                                  child: Center(
+                                    child: Text(
+                                      "Decrypting Stack backup file",
+                                      style: STextStyles.pageTitleH2(context)
+                                          .copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textWhite,
+                                      ),
+                                    ),
+                                  ),
                                 ),
                                 const SizedBox(
-                                  width: 12,
+                                  height: 64,
+                                ),
+                                const Center(
+                                  child: LoadingIndicator(
+                                    width: 100,
+                                  ),
                                 ),
                               ],
                             ),
                           ),
-                        ),
-                        key: const Key("restoreFromFileLocationTextFieldKey"),
-                        readOnly: true,
-                        toolbarOptions: const ToolbarOptions(
-                          copy: true,
-                          cut: false,
-                          paste: false,
-                          selectAll: false,
-                        ),
-                        onChanged: (newValue) {},
-                      ),
-                      const SizedBox(
-                        height: 8,
-                      ),
-                      ClipRRect(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
-                        ),
-                        child: TextField(
-                          key: const Key("restoreFromFilePasswordFieldKey"),
-                          focusNode: passwordFocusNode,
-                          controller: passwordController,
-                          style: STextStyles.field(context),
-                          obscureText: hidePassword,
-                          enableSuggestions: false,
-                          autocorrect: false,
-                          decoration: standardInputDecoration(
-                            "Enter password",
-                            passwordFocusNode,
-                            context,
-                          ).copyWith(
-                            suffixIcon: UnconstrainedBox(
-                              child: Row(
-                                children: [
-                                  const SizedBox(
-                                    width: 16,
-                                  ),
-                                  GestureDetector(
-                                    key: const Key(
-                                        "restoreFromFilePasswordFieldShowPasswordButtonKey"),
-                                    onTap: () async {
-                                      setState(() {
-                                        hidePassword = !hidePassword;
-                                      });
-                                    },
-                                    child: SvgPicture.asset(
-                                      hidePassword
-                                          ? Assets.svg.eye
-                                          : Assets.svg.eyeSlash,
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textDark3,
-                                      width: 16,
-                                      height: 16,
-                                    ),
-                                  ),
-                                  const SizedBox(
-                                    width: 12,
-                                  ),
-                                ],
+                        );
+
+                        final String? jsonString = await compute(
+                          SWB.decryptStackWalletWithPassphrase,
+                          Tuple2(fileToRestore, passphrase),
+                          debugLabel: "stack wallet decryption compute",
+                        );
+
+                        if (mounted) {
+                          // pop LoadingIndicator
+                          shouldPop = true;
+                          Navigator.of(context).pop();
+
+                          passwordController.text = "";
+
+                          if (jsonString == null) {
+                            showFloatingFlushBar(
+                              type: FlushBarType.warning,
+                              message: "Failed to decrypt backup file",
+                              context: context,
+                            );
+                            return;
+                          }
+
+                          Navigator.of(context).push(
+                            RouteGenerator.getRoute(
+                              builder: (_) => StackRestoreProgressView(
+                                jsonString: jsonString,
                               ),
                             ),
-                          ),
-                          onChanged: (newValue) {
-                            setState(() {});
-                          },
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 16,
-                      ),
-                      const Spacer(),
-                      TextButton(
-                        style: passwordController.text.isEmpty ||
-                                fileLocationController.text.isEmpty
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .getPrimaryDisabledButtonColor(context)
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .getPrimaryEnabledButtonColor(context),
-                        onPressed: passwordController.text.isEmpty ||
-                                fileLocationController.text.isEmpty
-                            ? null
-                            : () async {
-                                final String fileToRestore =
-                                    fileLocationController.text;
-                                final String passphrase =
-                                    passwordController.text;
-
-                                if (FocusScope.of(context).hasFocus) {
-                                  FocusScope.of(context).unfocus();
-                                  await Future<void>.delayed(
-                                      const Duration(milliseconds: 75));
-                                }
-
-                                if (!(await File(fileToRestore).exists())) {
-                                  showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "Backup file does not exist",
-                                    context: context,
-                                  );
-                                  return;
-                                }
-
-                                bool shouldPop = false;
-                                showDialog<dynamic>(
-                                  barrierDismissible: false,
-                                  context: context,
-                                  builder: (_) => WillPopScope(
-                                    onWillPop: () async {
-                                      return shouldPop;
-                                    },
-                                    child: Column(
-                                      crossAxisAlignment:
-                                          CrossAxisAlignment.stretch,
-                                      mainAxisAlignment:
-                                          MainAxisAlignment.center,
-                                      children: [
-                                        Material(
-                                          color: Colors.transparent,
-                                          child: Center(
-                                            child: Text(
-                                              "Decrypting Stack backup file",
-                                              style: STextStyles.pageTitleH2(
-                                                      context)
-                                                  .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textWhite,
-                                              ),
-                                            ),
-                                          ),
-                                        ),
-                                        const SizedBox(
-                                          height: 64,
-                                        ),
-                                        const Center(
-                                          child: LoadingIndicator(
-                                            width: 100,
-                                          ),
-                                        ),
-                                      ],
-                                    ),
-                                  ),
-                                );
-
-                                final String? jsonString = await compute(
-                                  SWB.decryptStackWalletWithPassphrase,
-                                  Tuple2(fileToRestore, passphrase),
-                                  debugLabel: "stack wallet decryption compute",
-                                );
-
-                                if (mounted) {
-                                  // pop LoadingIndicator
-                                  shouldPop = true;
-                                  Navigator.of(context).pop();
-
-                                  passwordController.text = "";
-
-                                  if (jsonString == null) {
-                                    showFloatingFlushBar(
-                                      type: FlushBarType.warning,
-                                      message: "Failed to decrypt backup file",
-                                      context: context,
-                                    );
-                                    return;
-                                  }
-
-                                  Navigator.of(context).push(
-                                    RouteGenerator.getRoute(
-                                      builder: (_) => StackRestoreProgressView(
-                                        jsonString: jsonString,
-                                      ),
-                                    ),
-                                  );
-                                }
-                              },
-                        child: Text(
-                          "Restore",
-                          style: STextStyles.button(context),
-                        ),
-                      ),
-                    ],
-                  ),
+                          );
+                        }
+                      },
+                child: Text(
+                  "Restore",
+                  style: STextStyles.button(context),
                 ),
               ),
-            );
-          },
-        ),
-      ),
-    );
+            ],
+          ),
+        ));
   }
 }

From 2c935d65b6380a34a174b32db287190e52dd20e1 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 4 Nov 2022 14:19:53 -0600
Subject: [PATCH 130/426] WIP: showing textfields for backups

---
 .../backup_and_restore_settings.dart          | 341 +++++++++---------
 1 file changed, 179 insertions(+), 162 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 8b74f8d40..d5ad6e6c7 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -2,6 +2,8 @@ import 'package:flutter/gestures.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -24,193 +26,208 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
-    return ListView(
-      shrinkWrap: true,
-      scrollDirection: Axis.vertical,
-      children: [
-        Padding(
-          padding: const EdgeInsets.only(
-            right: 30,
-          ),
-          child: RoundedWhiteContainer(
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                SvgPicture.asset(
-                  Assets.svg.backupAuto,
-                  width: 48,
-                  height: 48,
-                ),
-                Center(
-                  child: Padding(
-                    padding: const EdgeInsets.all(10),
-                    child: RichText(
-                      textAlign: TextAlign.start,
-                      text: TextSpan(
+
+    return LayoutBuilder(builder: (context, constraints) {
+      return SingleChildScrollView(
+          scrollDirection: Axis.vertical,
+          child: ConstrainedBox(
+            constraints: BoxConstraints(
+              minHeight: constraints.maxHeight,
+            ),
+            child: IntrinsicHeight(
+              child: Column(
+                children: [
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      right: 30,
+                    ),
+                    child: RoundedWhiteContainer(
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
-                          TextSpan(
-                            text: "Auto Backup",
-                            style: STextStyles.desktopTextSmall(context),
+                          SvgPicture.asset(
+                            Assets.svg.backupAuto,
+                            width: 48,
+                            height: 48,
                           ),
-                          TextSpan(
-                            text:
-                                "\n\nAuto backup is a custom Stack Wallet feature that offers a convenient backup of your data."
-                                "To ensure maximum security, we recommend using a unique password that you haven't used anywhere "
-                                "else on the internet before. Your password is not stored.",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
+                          Center(
+                            child: Padding(
+                              padding: const EdgeInsets.all(10),
+                              child: RichText(
+                                textAlign: TextAlign.start,
+                                text: TextSpan(
+                                  children: [
+                                    TextSpan(
+                                      text: "Auto Backup",
+                                      style:
+                                          STextStyles.desktopTextSmall(context),
+                                    ),
+                                    TextSpan(
+                                      text:
+                                          "\n\nAuto backup is a custom Stack Wallet feature that offers a convenient backup of your data."
+                                          "To ensure maximum security, we recommend using a unique password that you haven't used anywhere "
+                                          "else on the internet before. Your password is not stored.",
+                                      style: STextStyles
+                                          .desktopTextExtraExtraSmall(context),
+                                    ),
+                                    TextSpan(
+                                      text:
+                                          "\n\nFor more information, please see our website ",
+                                      style: STextStyles
+                                          .desktopTextExtraExtraSmall(context),
+                                    ),
+                                    TextSpan(
+                                      text: "stackwallet.com",
+                                      style: STextStyles.richLink(context)
+                                          .copyWith(fontSize: 14),
+                                      recognizer: TapGestureRecognizer()
+                                        ..onTap = () {
+                                          launchUrl(
+                                            Uri.parse(
+                                                "https://stackwallet.com/"),
+                                            mode:
+                                                LaunchMode.externalApplication,
+                                          );
+                                        },
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            ),
                           ),
-                          TextSpan(
-                            text:
-                                "\n\nFor more information, please see our website ",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
-                          ),
-                          TextSpan(
-                            text: "stackwallet.com",
-                            style: STextStyles.richLink(context)
-                                .copyWith(fontSize: 14),
-                            recognizer: TapGestureRecognizer()
-                              ..onTap = () {
-                                launchUrl(
-                                  Uri.parse("https://stackwallet.com/"),
-                                  mode: LaunchMode.externalApplication,
-                                );
-                              },
+                          Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: const [
+                              Padding(
+                                padding: EdgeInsets.all(
+                                  10,
+                                ),
+                                child: AutoBackupButton(),
+                              ),
+                            ],
                           ),
                         ],
                       ),
                     ),
                   ),
-                ),
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
-                    Padding(
-                      padding: EdgeInsets.all(
-                        10,
-                      ),
-                      child: AutoBackupButton(),
+                  const SizedBox(
+                    height: 25,
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      right: 30,
                     ),
-                  ],
-                ),
-              ],
-            ),
-          ),
-        ),
-        const SizedBox(
-          height: 25,
-        ),
-        Padding(
-          padding: const EdgeInsets.only(
-            right: 30,
-          ),
-          child: RoundedWhiteContainer(
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                SvgPicture.asset(
-                  Assets.svg.backupAdd,
-                  width: 48,
-                  height: 48,
-                  alignment: Alignment.topLeft,
-                ),
-                Center(
-                  child: Padding(
-                    padding: const EdgeInsets.all(10),
-                    child: RichText(
-                      textAlign: TextAlign.start,
-                      text: TextSpan(
+                    child: RoundedWhiteContainer(
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
-                          TextSpan(
-                            text: "Manual Backup",
-                            style: STextStyles.desktopTextSmall(context),
+                          SvgPicture.asset(
+                            Assets.svg.backupAdd,
+                            width: 48,
+                            height: 48,
+                            alignment: Alignment.topLeft,
                           ),
-                          TextSpan(
-                            text:
-                                "\n\nCreate manual backup to easily transfer your data between devices. "
-                                "You will create a backup file that can be later used in the Restore option. "
-                                "Use a strong password to encrypt your data.",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
+                          Center(
+                            child: Padding(
+                              padding: const EdgeInsets.all(10),
+                              child: RichText(
+                                textAlign: TextAlign.start,
+                                text: TextSpan(
+                                  children: [
+                                    TextSpan(
+                                      text: "Manual Backup",
+                                      style:
+                                          STextStyles.desktopTextSmall(context),
+                                    ),
+                                    TextSpan(
+                                      text:
+                                          "\n\nCreate manual backup to easily transfer your data between devices. "
+                                          "You will create a backup file that can be later used in the Restore option. "
+                                          "Use a strong password to encrypt your data.",
+                                      style: STextStyles
+                                          .desktopTextExtraExtraSmall(context),
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            ),
+                          ),
+                          Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: const [
+                              Padding(
+                                padding: EdgeInsets.all(
+                                  10,
+                                ),
+                                child: CreateBackupView(),
+                              ),
+                            ],
                           ),
                         ],
                       ),
                     ),
                   ),
-                ),
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
-                    Padding(
-                      padding: EdgeInsets.all(
-                        10,
-                      ),
-                      child: ManualBackupButton(),
+                  const SizedBox(
+                    height: 25,
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      right: 30,
                     ),
-                  ],
-                ),
-              ],
-            ),
-          ),
-        ),
-        const SizedBox(
-          height: 25,
-        ),
-        Padding(
-          padding: const EdgeInsets.only(
-            right: 30,
-          ),
-          child: RoundedWhiteContainer(
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                SvgPicture.asset(
-                  Assets.svg.backupRestore,
-                  width: 48,
-                  height: 48,
-                  alignment: Alignment.topLeft,
-                ),
-                Center(
-                  child: Padding(
-                    padding: const EdgeInsets.all(10),
-                    child: RichText(
-                      textAlign: TextAlign.start,
-                      text: TextSpan(
+                    child: RoundedWhiteContainer(
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
-                          TextSpan(
-                            text: "Restore Backup",
-                            style: STextStyles.desktopTextSmall(context),
+                          SvgPicture.asset(
+                            Assets.svg.backupRestore,
+                            width: 48,
+                            height: 48,
+                            alignment: Alignment.topLeft,
                           ),
-                          TextSpan(
-                            text:
-                                "\n\nUse your Stack Wallet backup file to restore your wallets, address book "
-                                "and wallet preferences.",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
+                          Center(
+                            child: Padding(
+                              padding: const EdgeInsets.all(10),
+                              child: RichText(
+                                textAlign: TextAlign.start,
+                                text: TextSpan(
+                                  children: [
+                                    TextSpan(
+                                      text: "Restore Backup",
+                                      style:
+                                          STextStyles.desktopTextSmall(context),
+                                    ),
+                                    TextSpan(
+                                      text:
+                                          "\n\nUse your Stack Wallet backup file to restore your wallets, address book "
+                                          "and wallet preferences.",
+                                      style: STextStyles
+                                          .desktopTextExtraExtraSmall(context),
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            ),
+                          ),
+                          Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: const [
+                              Padding(
+                                padding: EdgeInsets.all(
+                                  10,
+                                ),
+                                child: RestoreFromFileView(),
+                              ),
+                            ],
                           ),
                         ],
                       ),
                     ),
                   ),
-                ),
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
-                    Padding(
-                      padding: EdgeInsets.all(
-                        10,
-                      ),
-                      child: RestoreBackupButton(),
-                    ),
-                  ],
-                ),
-              ],
+                ],
+              ),
             ),
-          ),
-        ),
-      ],
-    );
+          ));
+    });
   }
 }
 

From 905e396a17f06813224dc2278df8a0ef37fdba20 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 4 Nov 2022 14:21:09 -0600
Subject: [PATCH 131/426] implemented clear logs on press

---
 .../advanced_settings/debug_info_dialog.dart  | 21 ++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
index 0406a059f..cf687e3e7 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
@@ -1,10 +1,14 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/isar/models/log.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/providers/global/debug_service_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/enums/log_level_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -105,7 +109,7 @@ class _DebugInfoDialog extends ConsumerState<DebugInfoDialog> {
             ],
           ),
           Expanded(
-            flex: 24,
+            // flex: 24,
             child: NestedScrollView(
               floatHeaderSlivers: true,
               headerSliverBuilder: (context, innerBoxIsScrolled) {
@@ -314,7 +318,7 @@ class _DebugInfoDialog extends ConsumerState<DebugInfoDialog> {
               ),
             ),
           ),
-          const Spacer(),
+          // const Spacer(),
           Padding(
             padding: const EdgeInsets.all(32),
             child: Row(
@@ -322,7 +326,18 @@ class _DebugInfoDialog extends ConsumerState<DebugInfoDialog> {
                 Expanded(
                   child: SecondaryButton(
                     label: "Clear logs",
-                    onPressed: () {},
+                    onPressed: () async {
+                      await ref.read(debugServiceProvider).deleteAllMessages();
+                      await ref.read(debugServiceProvider).updateRecentLogs();
+
+                      if (mounted) {
+                        Navigator.pop(context);
+                        unawaited(showFloatingFlushBar(
+                            type: FlushBarType.info,
+                            context: context,
+                            message: 'Logs cleared!'));
+                      }
+                    },
                   ),
                 ),
                 const SizedBox(

From ac0d4191c6a2a6fd62da1a02b9fde9679be8aee9 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 4 Nov 2022 16:34:36 -0600
Subject: [PATCH 132/426] added button widgets and some containers to restore
 dialog

---
 assets/svg/framed-address-book.svg            |   4 +
 assets/svg/framed-gear.svg                    |   4 +
 .../backup_and_restore_settings.dart          | 154 ++++--------
 .../restore_backup_dialog.dart                | 230 ++++++++++++------
 lib/utilities/assets.dart                     |   2 +
 pubspec.yaml                                  |   2 +
 6 files changed, 217 insertions(+), 179 deletions(-)
 create mode 100644 assets/svg/framed-address-book.svg
 create mode 100644 assets/svg/framed-gear.svg

diff --git a/assets/svg/framed-address-book.svg b/assets/svg/framed-address-book.svg
new file mode 100644
index 000000000..157117097
--- /dev/null
+++ b/assets/svg/framed-address-book.svg
@@ -0,0 +1,4 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="40" height="40" rx="8" fill="#E0E3E3"/>
+<path d="M26 8H12.5C10.843 8 9.5 9.34297 9.5 11V29C9.5 30.657 10.843 32 12.5 32H26C27.657 32 29 30.657 29 29V11C29 9.34297 27.6547 8 26 8ZM19.25 14C20.907 14 22.25 15.343 22.25 17C22.25 18.657 20.907 20 19.25 20C17.5934 20 16.25 18.657 16.25 17C16.25 15.343 17.5953 14 19.25 14ZM23.75 26H14.75C14.3375 26 14 25.6625 14 25.25C14 23.1781 15.6781 21.5 17.75 21.5H20.75C22.8209 21.5 24.5 23.1791 24.5 25.25C24.5 25.6625 24.1625 26 23.75 26ZM31.25 11H30.5V15.5H31.25C31.6625 15.5 32 15.1625 32 14.75V11.75C32 11.3356 31.6625 11 31.25 11ZM31.25 17H30.5V21.5H31.25C31.6625 21.5 32 21.1625 32 20.75V17.75C32 17.3375 31.6625 17 31.25 17ZM31.25 23H30.5V27.5H31.25C31.6642 27.5 32 27.1642 32 26.75V23.75C32 23.3375 31.6625 23 31.25 23Z" fill="#232323"/>
+</svg>
diff --git a/assets/svg/framed-gear.svg b/assets/svg/framed-gear.svg
new file mode 100644
index 000000000..749d9803d
--- /dev/null
+++ b/assets/svg/framed-gear.svg
@@ -0,0 +1,4 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="40" height="40" rx="8" fill="#E0E3E3"/>
+<path d="M30.6765 16.1586C30.8183 16.5281 30.698 16.9449 30.4058 17.2156L28.5452 18.9086C28.5925 19.2652 28.6183 19.6305 28.6183 19.9613C28.6183 20.3695 28.5925 20.7348 28.5452 21.0914L30.4058 22.7844C30.698 23.0551 30.8183 23.4676 30.6765 23.8414C30.4874 24.3527 30.2597 24.8469 30.0019 25.3152L29.7999 25.6633C29.5163 26.1359 29.1984 26.5828 28.8503 27.0082C28.5925 27.3133 28.1757 27.4207 27.7976 27.3004L25.4042 26.5355C24.8284 26.9781 24.1538 27.3477 23.5136 27.6313L22.9765 30.0848C22.8906 30.4715 22.5898 30.7465 22.1945 30.8496C21.6015 30.9484 20.9913 31 20.3296 31C19.7452 31 19.1351 30.9484 18.5421 30.8496C18.1468 30.7465 17.846 30.4715 17.7601 30.0848L17.223 27.6313C16.5441 27.3477 15.9081 26.9781 15.3323 26.5355L12.9407 27.3004C12.5609 27.4207 12.1419 27.3133 11.8875 27.0082C11.5391 26.5828 11.2211 26.1359 10.9375 25.6633L10.7364 25.3152C10.4756 24.8469 10.2487 24.3527 10.0584 23.8414C9.91914 23.4719 10.0364 23.0551 10.3312 22.7844L12.19 21.0914C12.1428 20.7348 12.1183 20.3695 12.1183 20C12.1183 19.6305 12.1428 19.2652 12.19 18.9086L10.3312 17.2156C10.0364 16.9449 9.91914 16.5324 10.0584 16.1586C10.2487 15.6473 10.476 15.1531 10.7364 14.6848L10.9371 14.3367C11.2207 13.8641 11.5391 13.4172 11.8875 12.9939C12.1419 12.6867 12.5609 12.5802 12.9407 12.7013L15.3323 13.4645C15.9081 13.0202 16.5441 12.6506 17.223 12.37L17.7601 9.91652C17.846 9.52637 18.1468 9.21656 18.5421 9.15082C19.1351 9.05161 19.7452 9 20.3296 9C20.9913 9 21.6015 9.05161 22.1945 9.15082C22.5898 9.21656 22.8906 9.52637 22.9765 9.91652L23.5136 12.37C24.1538 12.6506 24.8284 13.0202 25.4042 13.4645L27.7976 12.7013C28.1757 12.5802 28.5925 12.6867 28.8503 12.9939C29.1984 13.4172 29.5163 13.8641 29.7999 14.3367L30.0019 14.6848C30.2597 15.1531 30.4874 15.6473 30.6765 16.1586ZM20.3683 23.4375C22.2675 23.4375 23.8058 21.8992 23.8058 19.9613C23.8058 18.1008 22.2675 16.5238 20.3683 16.5238C18.4691 16.5238 16.9308 18.1008 16.9308 19.9613C16.9308 21.8992 18.4691 23.4375 20.3683 23.4375Z" fill="#232323"/>
+</svg>
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index d5ad6e6c7..b59206f17 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -5,10 +5,9 @@ import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:url_launcher/url_launcher.dart';
 
@@ -23,6 +22,20 @@ class BackupRestoreSettings extends ConsumerStatefulWidget {
 }
 
 class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
+  late bool createBackup = false;
+  late bool restoreBackup = false;
+
+  Future<void> enableAutoBackup(BuildContext context) async {
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) {
+        return const EnableBackupDialog();
+      },
+    );
+  }
+
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
@@ -97,12 +110,19 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                           ),
                           Column(
                             crossAxisAlignment: CrossAxisAlignment.start,
-                            children: const [
+                            children: [
                               Padding(
                                 padding: EdgeInsets.all(
                                   10,
                                 ),
-                                child: AutoBackupButton(),
+                                child: PrimaryButton(
+                                  desktopMed: true,
+                                  width: 200,
+                                  label: "Enable auto backup",
+                                  onPressed: () {
+                                    enableAutoBackup(context);
+                                  },
+                                ),
                               ),
                             ],
                           ),
@@ -154,12 +174,23 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                           ),
                           Column(
                             crossAxisAlignment: CrossAxisAlignment.start,
-                            children: const [
+                            children: [
                               Padding(
                                 padding: EdgeInsets.all(
                                   10,
                                 ),
-                                child: CreateBackupView(),
+                                child: createBackup
+                                    ? const CreateBackupView()
+                                    : PrimaryButton(
+                                        desktopMed: true,
+                                        width: 200,
+                                        label: "Create manual backup",
+                                        onPressed: () {
+                                          setState(() {
+                                            createBackup = true;
+                                          });
+                                        },
+                                      ),
                               ),
                             ],
                           ),
@@ -173,6 +204,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                   Padding(
                     padding: const EdgeInsets.only(
                       right: 30,
+                      bottom: 40,
                     ),
                     child: RoundedWhiteContainer(
                       child: Column(
@@ -210,12 +242,23 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                           ),
                           Column(
                             crossAxisAlignment: CrossAxisAlignment.start,
-                            children: const [
+                            children: [
                               Padding(
                                 padding: EdgeInsets.all(
                                   10,
                                 ),
-                                child: RestoreFromFileView(),
+                                child: restoreBackup
+                                    ? RestoreFromFileView()
+                                    : PrimaryButton(
+                                        desktopMed: true,
+                                        width: 200,
+                                        label: "Restore backup",
+                                        onPressed: () {
+                                          setState(() {
+                                            restoreBackup = true;
+                                          });
+                                        },
+                                      ),
                               ),
                             ],
                           ),
@@ -230,98 +273,3 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
     });
   }
 }
-
-class AutoBackupButton extends ConsumerWidget {
-  const AutoBackupButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    Future<void> enableAutoBackup() async {
-      await showDialog<dynamic>(
-        context: context,
-        useSafeArea: false,
-        barrierDismissible: true,
-        builder: (context) {
-          return const EnableBackupDialog();
-        },
-      );
-    }
-
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {
-          enableAutoBackup();
-        },
-        child: Text(
-          "Enable auto backup",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
-
-class ManualBackupButton extends ConsumerWidget {
-  const ManualBackupButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
-        child: Text(
-          "Create manual backup",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
-
-class RestoreBackupButton extends ConsumerWidget {
-  const RestoreBackupButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    Future<void> restoreBackup() async {
-      await showDialog<dynamic>(
-        context: context,
-        useSafeArea: false,
-        barrierDismissible: true,
-        builder: (context) {
-          return const RestoreBackupDialog();
-        },
-      );
-    }
-
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {
-          restoreBackup();
-        },
-        child: Text(
-          "Restore",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart
index 07d49274a..7f944847d 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart
@@ -1,10 +1,12 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
-import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class RestoreBackupDialog extends StatelessWidget {
   const RestoreBackupDialog({Key? key}) : super(key: key);
@@ -12,82 +14,158 @@ class RestoreBackupDialog extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return DesktopDialog(
-      child: Column(
-        mainAxisAlignment: MainAxisAlignment.start,
-        children: [
-          Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            children: [
-              Padding(
-                padding: const EdgeInsets.all(32),
-                child: Text(
-                  "Restoring Stack Wallet",
-                  style: STextStyles.desktopH3(context),
-                  textAlign: TextAlign.center,
+        maxHeight: 750,
+        maxWidth: 600,
+        child: LayoutBuilder(
+          builder: (context, constraints) {
+            return SingleChildScrollView(
+              child: ConstrainedBox(
+                constraints: BoxConstraints(
+                  minHeight: constraints.maxHeight,
+                ),
+                child: IntrinsicHeight(
+                  child: Column(
+                    mainAxisAlignment: MainAxisAlignment.start,
+                    children: [
+                      Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Padding(
+                            padding: const EdgeInsets.all(32),
+                            child: Text(
+                              "Restoring Stack Wallet",
+                              style: STextStyles.desktopH3(context),
+                              textAlign: TextAlign.center,
+                            ),
+                          ),
+                          const DesktopDialogCloseButton(),
+                        ],
+                      ),
+                      const SizedBox(
+                        height: 30,
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.symmetric(horizontal: 32),
+                        child: Row(
+                          children: [
+                            Text(
+                              "Settings",
+                              style: STextStyles.desktopTextExtraSmall(context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark3,
+                              ),
+                              textAlign: TextAlign.left,
+                            ),
+                          ],
+                        ),
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.symmetric(
+                            horizontal: 32, vertical: 12),
+                        child: RoundedWhiteContainer(
+                          borderColor: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                          child: Row(
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            children: [
+                              Row(
+                                children: [
+                                  SvgPicture.asset(
+                                    Assets.svg.framedAddressBook,
+                                    width: 40,
+                                    height: 40,
+                                  ),
+                                  const SizedBox(width: 12),
+                                  Text(
+                                    "Address Book",
+                                    style:
+                                        STextStyles.desktopTextSmall(context),
+                                  ),
+                                ],
+                              ),
+
+                              ///TODO: CHECKMARK ANIMATION
+                            ],
+                          ),
+                        ),
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.symmetric(
+                            horizontal: 32, vertical: 12),
+                        child: RoundedWhiteContainer(
+                          borderColor: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                          child: Row(
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            children: [
+                              Row(
+                                children: [
+                                  SvgPicture.asset(
+                                    Assets.svg.framedGear,
+                                    width: 40,
+                                    height: 40,
+                                  ),
+                                  const SizedBox(width: 12),
+                                  Text(
+                                    "Preferences",
+                                    style:
+                                        STextStyles.desktopTextSmall(context),
+                                  ),
+                                ],
+                              ),
+
+                              ///TODO: CHECKMARK ANIMATION
+                            ],
+                          ),
+                        ),
+                      ),
+                      const SizedBox(
+                        height: 30,
+                      ),
+                      Padding(
+                        padding: const EdgeInsets.symmetric(horizontal: 32),
+                        child: Row(
+                          children: [
+                            Text(
+                              "Wallets",
+                              style: STextStyles.desktopTextExtraSmall(context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark3,
+                              ),
+                              textAlign: TextAlign.left,
+                            ),
+                          ],
+                        ),
+                      ),
+                      const Spacer(),
+                      Padding(
+                        padding: const EdgeInsets.all(32),
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.end,
+                          children: [
+                            SecondaryButton(
+                              desktopMed: true,
+                              width: 200,
+                              label: "Cancel restore process",
+                              onPressed: () {
+                                Navigator.of(context).pop();
+                              },
+                            ),
+                          ],
+                        ),
+                      ),
+                    ],
+                  ),
                 ),
               ),
-              const DesktopDialogCloseButton(),
-            ],
-          ),
-          const SizedBox(
-            height: 30,
-          ),
-          Padding(
-            padding: const EdgeInsets.only(
-              left: 32,
-              right: 32,
-            ),
-            child: Row(
-              children: [
-                Text(
-                  "Settings",
-                  style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                    color:
-                        Theme.of(context).extension<StackColors>()!.textDark3,
-                  ),
-                  textAlign: TextAlign.left,
-                ),
-              ],
-            ),
-          ),
-          // RoundedWhiteContainer(
-          //   child: Column(
-          //     crossAxisAlignment: CrossAxisAlignment.start,
-          //     children: [
-          //       Row(),
-          //     ],
-          //   ),
-          // ),
-          const Spacer(),
-          Padding(
-            padding: const EdgeInsets.all(32),
-            child: Row(
-              children: [
-                Expanded(
-                  child: SecondaryButton(
-                    label: "Cancel",
-                    onPressed: () {
-                      Navigator.of(context).pop();
-                    },
-                  ),
-                ),
-                const SizedBox(
-                  width: 16,
-                ),
-                Expanded(
-                  child: PrimaryButton(
-                    label: "Continue",
-                    onPressed: () {
-                      // Navigator.of(context).pop();
-                      // onConfirm.call();
-                    },
-                  ),
-                )
-              ],
-            ),
-          ),
-        ],
-      ),
-    );
+            );
+          },
+        ));
   }
 }
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 386ea1cd8..b0c6b3bf9 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -59,6 +59,8 @@ class _SVG {
   String txExchangeFailed(BuildContext context) =>
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
 
+  String get framedGear => "assets/svg/framed-gear.svg";
+  String get framedAddressBook => "assets/svg/framed-address-book.svg";
   String get themeLight => "assets/svg/light/light-mode.svg";
   String get themeDark => "assets/svg/dark/dark-theme.svg";
   String get circleNode => "assets/svg/node-circle.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index 9ba6d4eb9..1e5c80e76 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -338,6 +338,8 @@ flutter:
     - assets/svg/message-question-1.svg
     - assets/svg/drd-icon.svg
     - assets/svg/box-auto.svg
+    - assets/svg/framed-address-book.svg
+    - assets/svg/framed-gear.svg
     # exchange icons
     - assets/svg/exchange_icons/change_now_logo_1.svg
     - assets/svg/exchange_icons/simpleswap-icon.svg

From 21f18326d80ba4a7572536f4f051528dee2b03a3 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 4 Nov 2022 10:08:29 -0600
Subject: [PATCH 133/426] update swb lib dependency

---
 crypto_plugins/flutter_libmonero | 2 +-
 pubspec.lock                     | 4 ++--
 pubspec.yaml                     | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index 51f74f05d..277d922c3 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit 51f74f05d465a92e0118cf7c2bcfb049df21af42
+Subproject commit 277d922c3b1d637c1ccda25f51395c618d293015
diff --git a/pubspec.lock b/pubspec.lock
index 20992d827..2f7770d3a 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1378,8 +1378,8 @@ packages:
     dependency: "direct main"
     description:
       path: "."
-      ref: b7b184ec36466f2a24104a7056de88881cb0c1e9
-      resolved-ref: b7b184ec36466f2a24104a7056de88881cb0c1e9
+      ref: "011dc9ce3d29f5fdeeaf711d58b5122f055c146d"
+      resolved-ref: "011dc9ce3d29f5fdeeaf711d58b5122f055c146d"
       url: "https://github.com/cypherstack/stack_wallet_backup.git"
     source: git
     version: "0.0.1"
diff --git a/pubspec.yaml b/pubspec.yaml
index 1e5c80e76..86f24330b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -54,7 +54,7 @@ dependencies:
   stack_wallet_backup:
     git:
       url: https://github.com/cypherstack/stack_wallet_backup.git
-      ref: b7b184ec36466f2a24104a7056de88881cb0c1e9
+      ref: 011dc9ce3d29f5fdeeaf711d58b5122f055c146d
 
   # Utility plugins
 #  provider: ^6.0.1

From 4dd8ae23c5ab89d3baccec1053c347ca6bef7d17 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 4 Nov 2022 13:32:02 -0600
Subject: [PATCH 134/426] WIP: desktop password

---
 lib/main.dart                                 | 29 +++---
 .../create_password/create_password_view.dart | 20 +++--
 .../desktop_login_view.dart                   | 47 ++++++++++
 .../storage_crypto_handler_provider.dart      |  4 +
 lib/utilities/desktop_password_service.dart   | 89 +++++++++++++++++++
 5 files changed, 174 insertions(+), 15 deletions(-)
 create mode 100644 lib/pages_desktop_specific/desktop_login_view.dart
 create mode 100644 lib/providers/desktop/storage_crypto_handler_provider.dart
 create mode 100644 lib/utilities/desktop_password_service.dart

diff --git a/lib/main.dart b/lib/main.dart
index 58a287b31..77a8b1441 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -30,7 +30,8 @@ import 'package:stackwallet/pages/loading_view.dart';
 import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
 import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart';
-import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_login_view.dart';
+import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
 import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
 import 'package:stackwallet/providers/global/base_currencies_provider.dart';
 // import 'package:stackwallet/providers/global/has_authenticated_start_state_provider.dart';
@@ -207,6 +208,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
   late final Completer<void> loadingCompleter;
 
   bool didLoad = false;
+  bool _desktopHasPassword = false;
 
   Future<void> load() async {
     try {
@@ -218,6 +220,11 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
       await DB.instance.init();
       await _prefs.init();
 
+      if (Util.isDesktop) {
+        _desktopHasPassword =
+            await ref.read(storageCryptoHandlerProvider).hasPassword();
+      }
+
       _notificationsService = ref.read(notificationsProvider);
       _nodeService = ref.read(nodeServiceChangeNotifierProvider);
       _tradesService = ref.read(tradesServiceProvider);
@@ -545,21 +552,23 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
         builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
           if (snapshot.connectionState == ConnectionState.done) {
             // FlutterNativeSplash.remove();
-            if (_wallets.hasWallets || _prefs.hasPin) {
-              // return HomeView();
-
+            if (Util.isDesktop &&
+                (_wallets.hasWallets || _desktopHasPassword)) {
               String? startupWalletId;
               if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) {
                 startupWalletId =
                     ref.read(prefsChangeNotifierProvider).startupWalletId;
               }
 
-              // TODO proper desktop auth view
-              if (Util.isDesktop) {
-                Future<void>.delayed(Duration.zero).then((value) =>
-                    Navigator.of(context).pushNamedAndRemoveUntil(
-                        DesktopHomeView.routeName, (route) => false));
-                return Container();
+              return DesktopLoginView(startupWalletId: startupWalletId);
+            } else if (!Util.isDesktop &&
+                (_wallets.hasWallets || _prefs.hasPin)) {
+              // return HomeView();
+
+              String? startupWalletId;
+              if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) {
+                startupWalletId =
+                    ref.read(prefsChangeNotifierProvider).startupWalletId;
               }
 
               return LockscreenView(
diff --git a/lib/pages_desktop_specific/create_password/create_password_view.dart b/lib/pages_desktop_specific/create_password/create_password_view.dart
index 2391a22f6..0a8429058 100644
--- a/lib/pages_desktop_specific/create_password/create_password_view.dart
+++ b/lib/pages_desktop_specific/create_password/create_password_view.dart
@@ -1,10 +1,12 @@
 import 'dart:async';
 
 import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
+import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@@ -18,7 +20,7 @@ import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:zxcvbn/zxcvbn.dart';
 
-class CreatePasswordView extends StatefulWidget {
+class CreatePasswordView extends ConsumerStatefulWidget {
   const CreatePasswordView({
     Key? key,
     this.secureStore = const SecureStorageWrapper(
@@ -31,10 +33,10 @@ class CreatePasswordView extends StatefulWidget {
   final FlutterSecureStorageInterface secureStore;
 
   @override
-  State<CreatePasswordView> createState() => _CreatePasswordViewState();
+  ConsumerState<CreatePasswordView> createState() => _CreatePasswordViewState();
 }
 
-class _CreatePasswordViewState extends State<CreatePasswordView> {
+class _CreatePasswordViewState extends ConsumerState<CreatePasswordView> {
   late final TextEditingController passwordController;
   late final TextEditingController passwordRepeatController;
 
@@ -76,8 +78,16 @@ class _CreatePasswordViewState extends State<CreatePasswordView> {
       return;
     }
 
-    await widget.secureStore
-        .write(key: "stackDesktopPassword", value: passphrase);
+    try {
+      await ref.read(storageCryptoHandlerProvider).initFromNew(passphrase);
+    } catch (e) {
+      unawaited(showFloatingFlushBar(
+        type: FlushBarType.warning,
+        message: "Error: $e",
+        context: context,
+      ));
+      return;
+    }
 
     if (mounted) {
       unawaited(Navigator.of(context)
diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
new file mode 100644
index 000000000..c986bffde
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -0,0 +1,47 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+
+class DesktopLoginView extends StatefulWidget {
+  const DesktopLoginView({
+    Key? key,
+    this.startupWalletId,
+  }) : super(key: key);
+
+  static const String routeName = "/desktopLogin";
+
+  final String? startupWalletId;
+
+  @override
+  State<DesktopLoginView> createState() => _DesktopLoginViewState();
+}
+
+class _DesktopLoginViewState extends State<DesktopLoginView> {
+  @override
+  Widget build(BuildContext context) {
+    return Material(
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.center,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        children: [
+          Text(
+            "Login",
+            style: STextStyles.desktopH3(context),
+          ),
+          PrimaryButton(
+            label: "Login",
+            onPressed: () {
+              // todo auth
+
+              Navigator.of(context).pushNamedAndRemoveUntil(
+                DesktopHomeView.routeName,
+                (route) => false,
+              );
+            },
+          )
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/providers/desktop/storage_crypto_handler_provider.dart b/lib/providers/desktop/storage_crypto_handler_provider.dart
new file mode 100644
index 000000000..5b15ccaf3
--- /dev/null
+++ b/lib/providers/desktop/storage_crypto_handler_provider.dart
@@ -0,0 +1,4 @@
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/utilities/desktop_password_service.dart';
+
+final storageCryptoHandlerProvider = Provider<DPS>((ref) => DPS());
diff --git a/lib/utilities/desktop_password_service.dart b/lib/utilities/desktop_password_service.dart
new file mode 100644
index 000000000..da537b3c2
--- /dev/null
+++ b/lib/utilities/desktop_password_service.dart
@@ -0,0 +1,89 @@
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:stack_wallet_backup/secure_storage.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
+import 'package:stackwallet/utilities/logger.dart';
+
+const String _kKeyBlobKey = "swbKeyBlobKeyStringID";
+
+String _getMessageFromException(Object exception) {
+  if (exception is IncorrectPassphrase) {
+    return exception.errMsg();
+  }
+  if (exception is BadDecryption) {
+    return exception.errMsg();
+  }
+  if (exception is InvalidLength) {
+    return exception.errMsg();
+  }
+  if (exception is EncodingError) {
+    return exception.errMsg();
+  }
+
+  return exception.toString();
+}
+
+class DPS {
+  StorageCryptoHandler? _handler;
+  final SecureStorageWrapper secureStorageWrapper;
+
+  StorageCryptoHandler get handler {
+    if (_handler == null) {
+      throw Exception(
+          "DPS: attempted to access handler without proper authentication");
+    }
+    return _handler!;
+  }
+
+  DPS({
+    this.secureStorageWrapper = const SecureStorageWrapper(
+      FlutterSecureStorage(),
+    ),
+  });
+
+  Future<void> initFromNew(String passphrase) async {
+    if (_handler != null) {
+      throw Exception("DPS: attempted to re initialize with new passphrase");
+    }
+
+    try {
+      _handler = await StorageCryptoHandler.fromNewPassphrase(passphrase);
+      await secureStorageWrapper.write(
+        key: _kKeyBlobKey,
+        value: await _handler!.getKeyBlob(),
+      );
+    } catch (e, s) {
+      Logging.instance.log(
+        "${_getMessageFromException(e)}\n$s",
+        level: LogLevel.Error,
+      );
+      rethrow;
+    }
+  }
+
+  Future<void> initFromExisting(String passphrase) async {
+    if (_handler != null) {
+      throw Exception(
+          "DPS: attempted to re initialize with existing passphrase");
+    }
+    final keyBlob = await secureStorageWrapper.read(key: _kKeyBlobKey);
+
+    if (keyBlob == null) {
+      throw Exception(
+          "DPS: failed to find keyBlob while attempting to initialize with existing passphrase");
+    }
+
+    try {
+      _handler = await StorageCryptoHandler.fromExisting(passphrase, keyBlob);
+    } catch (e, s) {
+      Logging.instance.log(
+        "${_getMessageFromException(e)}\n$s",
+        level: LogLevel.Error,
+      );
+      rethrow;
+    }
+  }
+
+  Future<bool> hasPassword() async {
+    return (await secureStorageWrapper.read(key: _kKeyBlobKey)) != null;
+  }
+}

From 039a9a68f6e96ae9b2033ac8279005a03f93fa97 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 4 Nov 2022 13:55:13 -0600
Subject: [PATCH 135/426] bch clean up linter warnings and unused variables

---
 .../coins/bitcoincash/bitcoincash_wallet.dart | 209 ++++++++++--------
 1 file changed, 119 insertions(+), 90 deletions(-)

diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index 3a5cebdec..c01ff6248 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -6,7 +6,7 @@ import 'dart:typed_data';
 import 'package:bech32/bech32.dart';
 import 'package:bip32/bip32.dart' as bip32;
 import 'package:bip39/bip39.dart' as bip39;
-import 'package:bitbox/bitbox.dart' as Bitbox;
+import 'package:bitbox/bitbox.dart' as bitbox;
 import 'package:bitcoindart/bitcoindart.dart';
 import 'package:bs58check/bs58check.dart' as bs58check;
 import 'package:crypto/crypto.dart';
@@ -258,7 +258,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
   }
 
   Future<void> updateStoredChainHeight({required int newHeight}) async {
-    DB.instance.put<dynamic>(
+    await DB.instance.put<dynamic>(
         boxName: walletId, key: "storedChainHeight", value: newHeight);
   }
 
@@ -266,8 +266,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
     Uint8List? decodeBase58;
     Segwit? decodeBech32;
     try {
-      if (Bitbox.Address.detectFormat(address) == 0) {
-        address = Bitbox.Address.toLegacyAddress(address);
+      if (bitbox.Address.detectFormat(address) == 0) {
+        address = bitbox.Address.toLegacyAddress(address);
       }
     } catch (e, s) {}
     try {
@@ -609,7 +609,9 @@ class BitcoinCashWallet extends CoinServiceAPI {
 
       // get address tx counts
       final counts = await _getBatchTxCount(addresses: txCountCallArgs);
-      print("Counts $counts");
+      if (kDebugMode) {
+        print("Counts $counts");
+      }
       // check and add appropriate addresses
       for (int k = 0; k < txCountBatchSize; k++) {
         int count = counts["${_id}_$k"]!;
@@ -745,31 +747,35 @@ class BitcoinCashWallet extends CoinServiceAPI {
     // notify on new incoming transaction
     for (final tx in unconfirmedTxnsToNotifyPending) {
       if (tx.txType == "Received") {
-        NotificationApi.showNotification(
-          title: "Incoming transaction",
-          body: walletName,
-          walletId: walletId,
-          iconAssetName: Assets.svg.iconFor(coin: coin),
-          date: DateTime.now(),
-          shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS,
-          coinName: coin.name,
-          txid: tx.txid,
-          confirmations: tx.confirmations,
-          requiredConfirmations: MINIMUM_CONFIRMATIONS,
+        unawaited(
+          NotificationApi.showNotification(
+            title: "Incoming transaction",
+            body: walletName,
+            walletId: walletId,
+            iconAssetName: Assets.svg.iconFor(coin: coin),
+            date: DateTime.now(),
+            shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS,
+            coinName: coin.name,
+            txid: tx.txid,
+            confirmations: tx.confirmations,
+            requiredConfirmations: MINIMUM_CONFIRMATIONS,
+          ),
         );
         await txTracker.addNotifiedPending(tx.txid);
       } else if (tx.txType == "Sent") {
-        NotificationApi.showNotification(
-          title: "Sending transaction",
-          body: walletName,
-          walletId: walletId,
-          iconAssetName: Assets.svg.iconFor(coin: coin),
-          date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
-          shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS,
-          coinName: coin.name,
-          txid: tx.txid,
-          confirmations: tx.confirmations,
-          requiredConfirmations: MINIMUM_CONFIRMATIONS,
+        unawaited(
+          NotificationApi.showNotification(
+            title: "Sending transaction",
+            body: walletName,
+            walletId: walletId,
+            iconAssetName: Assets.svg.iconFor(coin: coin),
+            date: DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000),
+            shouldWatchForUpdates: tx.confirmations < MINIMUM_CONFIRMATIONS,
+            coinName: coin.name,
+            txid: tx.txid,
+            confirmations: tx.confirmations,
+            requiredConfirmations: MINIMUM_CONFIRMATIONS,
+          ),
         );
         await txTracker.addNotifiedPending(tx.txid);
       }
@@ -778,26 +784,30 @@ class BitcoinCashWallet extends CoinServiceAPI {
     // notify on confirmed
     for (final tx in unconfirmedTxnsToNotifyConfirmed) {
       if (tx.txType == "Received") {
-        NotificationApi.showNotification(
-          title: "Incoming transaction confirmed",
-          body: walletName,
-          walletId: walletId,
-          iconAssetName: Assets.svg.iconFor(coin: coin),
-          date: DateTime.now(),
-          shouldWatchForUpdates: false,
-          coinName: coin.name,
+        unawaited(
+          NotificationApi.showNotification(
+            title: "Incoming transaction confirmed",
+            body: walletName,
+            walletId: walletId,
+            iconAssetName: Assets.svg.iconFor(coin: coin),
+            date: DateTime.now(),
+            shouldWatchForUpdates: false,
+            coinName: coin.name,
+          ),
         );
 
         await txTracker.addNotifiedConfirmed(tx.txid);
       } else if (tx.txType == "Sent") {
-        NotificationApi.showNotification(
-          title: "Outgoing transaction confirmed",
-          body: walletName,
-          walletId: walletId,
-          iconAssetName: Assets.svg.iconFor(coin: coin),
-          date: DateTime.now(),
-          shouldWatchForUpdates: false,
-          coinName: coin.name,
+        unawaited(
+          NotificationApi.showNotification(
+            title: "Outgoing transaction confirmed",
+            body: walletName,
+            walletId: walletId,
+            iconAssetName: Assets.svg.iconFor(coin: coin),
+            date: DateTime.now(),
+            shouldWatchForUpdates: false,
+            coinName: coin.name,
+          ),
         );
         await txTracker.addNotifiedConfirmed(tx.txid);
       }
@@ -862,7 +872,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
       if (currentHeight != storedHeight) {
         if (currentHeight != -1) {
           // -1 failed to fetch current height
-          updateStoredChainHeight(newHeight: currentHeight);
+          await updateStoredChainHeight(newHeight: currentHeight);
         }
 
         GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.2, walletId));
@@ -1147,10 +1157,12 @@ class BitcoinCashWallet extends CoinServiceAPI {
   bool validateAddress(String address) {
     try {
       // 0 for bitcoincash: address scheme, 1 for legacy address
-      final format = Bitbox.Address.detectFormat(address);
-      print("format $format");
+      final format = bitbox.Address.detectFormat(address);
+      if (kDebugMode) {
+        print("format $format");
+      }
       return true;
-    } catch (e, s) {
+    } catch (e) {
       return false;
     }
   }
@@ -1226,7 +1238,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
     );
 
     if (shouldRefresh) {
-      refresh();
+      unawaited(refresh());
     }
   }
 
@@ -1522,12 +1534,14 @@ class BitcoinCashWallet extends CoinServiceAPI {
         break;
     }
 
-    print("Array key is ${jsonEncode(arrayKey)}");
+    if (kDebugMode) {
+      print("Array key is ${jsonEncode(arrayKey)}");
+    }
     final internalChainArray =
         DB.instance.get<dynamic>(boxName: walletId, key: arrayKey);
     if (derivePathType == DerivePathType.bip44) {
-      if (Bitbox.Address.detectFormat(internalChainArray.last as String) == 1) {
-        return Bitbox.Address.toCashAddress(internalChainArray.last as String);
+      if (bitbox.Address.detectFormat(internalChainArray.last as String) == 1) {
+        return bitbox.Address.toCashAddress(internalChainArray.last as String);
       }
     }
     return internalChainArray.last as String;
@@ -1642,7 +1656,9 @@ class BitcoinCashWallet extends CoinServiceAPI {
           batches[batchNumber] = {};
         }
         final scripthash = _convertToScriptHash(allAddresses[i], _network);
-        print("SCRIPT_HASH_FOR_ADDRESS ${allAddresses[i]} IS $scripthash");
+        if (kDebugMode) {
+          print("SCRIPT_HASH_FOR_ADDRESS ${allAddresses[i]} IS $scripthash");
+        }
         batches[batchNumber]!.addAll({
           scripthash: [scripthash]
         });
@@ -1818,20 +1834,28 @@ class BitcoinCashWallet extends CoinServiceAPI {
   }) async {
     try {
       final Map<String, List<dynamic>> args = {};
-      print("Address $addresses");
+      if (kDebugMode) {
+        print("Address $addresses");
+      }
       for (final entry in addresses.entries) {
         args[entry.key] = [_convertToScriptHash(entry.value, _network)];
       }
 
-      print("Args ${jsonEncode(args)}");
+      if (kDebugMode) {
+        print("Args ${jsonEncode(args)}");
+      }
 
       final response = await electrumXClient.getBatchHistory(args: args);
-      print("Response ${jsonEncode(response)}");
+      if (kDebugMode) {
+        print("Response ${jsonEncode(response)}");
+      }
       final Map<String, int> result = {};
       for (final entry in response.entries) {
         result[entry.key] = entry.value.length;
       }
-      print("result ${jsonEncode(result)}");
+      if (kDebugMode) {
+        print("result ${jsonEncode(result)}");
+      }
       return result;
     } catch (e, s) {
       Logging.instance.log(
@@ -1995,8 +2019,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
   /// Returns the scripthash or throws an exception on invalid bch address
   String _convertToScriptHash(String bchAddress, NetworkType network) {
     try {
-      if (Bitbox.Address.detectFormat(bchAddress) == 0) {
-        bchAddress = Bitbox.Address.toLegacyAddress(bchAddress);
+      if (bitbox.Address.detectFormat(bchAddress) == 0) {
+        bchAddress = bitbox.Address.toLegacyAddress(bchAddress);
       }
       final output = Address.addressToOutputScript(bchAddress, network);
       final hash = sha256.convert(output.toList(growable: false)).toString();
@@ -2073,8 +2097,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
     List<String> allAddressesOld = await _fetchAllOwnAddresses();
     List<String> allAddresses = [];
     for (String address in allAddressesOld) {
-      if (Bitbox.Address.detectFormat(address) == 1) {
-        allAddresses.add(Bitbox.Address.toCashAddress(address));
+      if (bitbox.Address.detectFormat(address) == 1) {
+        allAddresses.add(bitbox.Address.toCashAddress(address));
       } else {
         allAddresses.add(address);
       }
@@ -2085,8 +2109,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
             as List<dynamic>;
     List<dynamic> changeAddressesP2PKH = [];
     for (var address in changeAddressesP2PKHOld) {
-      if (Bitbox.Address.detectFormat(address as String) == 1) {
-        changeAddressesP2PKH.add(Bitbox.Address.toCashAddress(address));
+      if (bitbox.Address.detectFormat(address as String) == 1) {
+        changeAddressesP2PKH.add(bitbox.Address.toCashAddress(address));
       } else {
         changeAddressesP2PKH.add(address);
       }
@@ -2108,21 +2132,26 @@ class BitcoinCashWallet extends CoinServiceAPI {
     unconfirmedCachedTransactions
         .removeWhere((key, value) => value.confirmedStatus);
 
-    print("CACHED_TRANSACTIONS_IS $cachedTransactions");
+    if (kDebugMode) {
+      print("CACHED_TRANSACTIONS_IS $cachedTransactions");
+    }
     if (cachedTransactions != null) {
       for (final tx in allTxHashes.toList(growable: false)) {
         final txHeight = tx["height"] as int;
         if (txHeight > 0 &&
             txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) {
           if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) {
-            print(cachedTransactions.findTransaction(tx["tx_hash"] as String));
-            print(unconfirmedCachedTransactions[tx["tx_hash"] as String]);
+            if (kDebugMode) {
+              print(
+                  cachedTransactions.findTransaction(tx["tx_hash"] as String));
+              print(unconfirmedCachedTransactions[tx["tx_hash"] as String]);
+            }
             final cachedTx =
                 cachedTransactions.findTransaction(tx["tx_hash"] as String);
             if (!(cachedTx != null &&
                 addressType(address: cachedTx.address) ==
                     DerivePathType.bip44 &&
-                Bitbox.Address.detectFormat(cachedTx.address) == 1)) {
+                bitbox.Address.detectFormat(cachedTx.address) == 1)) {
               allTxHashes.remove(tx);
             }
           }
@@ -2782,8 +2811,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
           final n = output["n"];
           if (n != null && n == utxosToUse[i].vout) {
             String address = output["scriptPubKey"]["addresses"][0] as String;
-            if (Bitbox.Address.detectFormat(address) == 0) {
-              address = Bitbox.Address.toLegacyAddress(address);
+            if (bitbox.Address.detectFormat(address) == 0) {
+              address = bitbox.Address.toLegacyAddress(address);
             }
             if (!addressTxid.containsKey(address)) {
               addressTxid[address] = <String>[];
@@ -2814,8 +2843,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
         );
         for (int i = 0; i < p2pkhLength; i++) {
           String address = addressesP2PKH[i];
-          if (Bitbox.Address.detectFormat(address) == 0) {
-            address = Bitbox.Address.toLegacyAddress(address);
+          if (bitbox.Address.detectFormat(address) == 0) {
+            address = bitbox.Address.toLegacyAddress(address);
           }
 
           // receives
@@ -2950,36 +2979,36 @@ class BitcoinCashWallet extends CoinServiceAPI {
     required List<String> recipients,
     required List<int> satoshiAmounts,
   }) async {
-    final builder = Bitbox.Bitbox.transactionBuilder();
+    final builder = bitbox.Bitbox.transactionBuilder();
 
     // retrieve address' utxos from the rest api
-    List<Bitbox.Utxo> _utxos =
+    List<bitbox.Utxo> _utxos =
         []; // await Bitbox.Address.utxo(address) as List<Bitbox.Utxo>;
-    utxosToUse.forEach((element) {
-      _utxos.add(Bitbox.Utxo(
+    for (var element in utxosToUse) {
+      _utxos.add(bitbox.Utxo(
           element.txid,
           element.vout,
-          Bitbox.BitcoinCash.fromSatoshi(element.value),
+          bitbox.BitcoinCash.fromSatoshi(element.value),
           element.value,
           0,
           MINIMUM_CONFIRMATIONS + 1));
-    });
-    Logger.print("bch utxos: ${_utxos}");
+    }
+    Logger.print("bch utxos: $_utxos");
 
     // placeholder for input signatures
-    final signatures = <Map>[];
+    final List<Map<dynamic, dynamic>> signatures = [];
 
     // placeholder for total input balance
-    int totalBalance = 0;
+    // int totalBalance = 0;
 
     // iterate through the list of address _utxos and use them as inputs for the
     // withdrawal transaction
-    _utxos.forEach((Bitbox.Utxo utxo) {
+    for (var utxo in _utxos) {
       // add the utxo as an input for the transaction
       builder.addInput(utxo.txid, utxo.vout);
       final ec = utxoSigningData[utxo.txid]["keyPair"] as ECPair;
 
-      final bitboxEC = Bitbox.ECPair.fromWIF(ec.toWIF());
+      final bitboxEC = bitbox.ECPair.fromWIF(ec.toWIF());
 
       // add a signature to the list to be used later
       signatures.add({
@@ -2988,15 +3017,15 @@ class BitcoinCashWallet extends CoinServiceAPI {
         "original_amount": utxo.satoshis
       });
 
-      totalBalance += utxo.satoshis;
-    });
+      // totalBalance += utxo.satoshis;
+    }
 
     // calculate the fee based on number of inputs and one expected output
-    final fee =
-        Bitbox.BitcoinCash.getByteCount(signatures.length, recipients.length);
+    // final fee =
+    //     bitbox.BitcoinCash.getByteCount(signatures.length, recipients.length);
 
     // calculate how much balance will be left over to spend after the fee
-    final sendAmount = totalBalance - fee;
+    // final sendAmount = totalBalance - fee;
 
     // add the output based on the address provided in the testing data
     for (int i = 0; i < recipients.length; i++) {
@@ -3006,12 +3035,12 @@ class BitcoinCashWallet extends CoinServiceAPI {
     }
 
     // sign all inputs
-    signatures.forEach((signature) {
+    for (var signature in signatures) {
       builder.sign(
           signature["vin"] as int,
-          signature["key_pair"] as Bitbox.ECPair,
+          signature["key_pair"] as bitbox.ECPair,
           signature["original_amount"] as int);
-    });
+    }
 
     // build the transaction
     final tx = builder.build();
@@ -3038,7 +3067,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
     );
 
     // clear cache
-    _cachedElectrumXClient.clearSharedTransactionCache(coin: coin);
+    await _cachedElectrumXClient.clearSharedTransactionCache(coin: coin);
 
     // back up data
     await _rescanBackup();

From ccd94fcf86601e03d995d170611b5888694d38a0 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 4 Nov 2022 14:10:30 -0600
Subject: [PATCH 136/426] bch compare address type to constant names instead of
 int literals

---
 .../coins/bitcoincash/bitcoincash_wallet.dart | 23 ++++++++++++-------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index c01ff6248..0a72cea99 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -266,7 +266,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
     Uint8List? decodeBase58;
     Segwit? decodeBech32;
     try {
-      if (bitbox.Address.detectFormat(address) == 0) {
+      if (bitbox.Address.detectFormat(address) ==
+          bitbox.Address.formatCashAddr) {
         address = bitbox.Address.toLegacyAddress(address);
       }
     } catch (e, s) {}
@@ -1540,7 +1541,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
     final internalChainArray =
         DB.instance.get<dynamic>(boxName: walletId, key: arrayKey);
     if (derivePathType == DerivePathType.bip44) {
-      if (bitbox.Address.detectFormat(internalChainArray.last as String) == 1) {
+      if (bitbox.Address.detectFormat(internalChainArray.last as String) ==
+          bitbox.Address.formatLegacy) {
         return bitbox.Address.toCashAddress(internalChainArray.last as String);
       }
     }
@@ -2019,7 +2021,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
   /// Returns the scripthash or throws an exception on invalid bch address
   String _convertToScriptHash(String bchAddress, NetworkType network) {
     try {
-      if (bitbox.Address.detectFormat(bchAddress) == 0) {
+      if (bitbox.Address.detectFormat(bchAddress) ==
+          bitbox.Address.formatCashAddr) {
         bchAddress = bitbox.Address.toLegacyAddress(bchAddress);
       }
       final output = Address.addressToOutputScript(bchAddress, network);
@@ -2097,7 +2100,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
     List<String> allAddressesOld = await _fetchAllOwnAddresses();
     List<String> allAddresses = [];
     for (String address in allAddressesOld) {
-      if (bitbox.Address.detectFormat(address) == 1) {
+      if (bitbox.Address.detectFormat(address) == bitbox.Address.formatLegacy) {
         allAddresses.add(bitbox.Address.toCashAddress(address));
       } else {
         allAddresses.add(address);
@@ -2109,7 +2112,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
             as List<dynamic>;
     List<dynamic> changeAddressesP2PKH = [];
     for (var address in changeAddressesP2PKHOld) {
-      if (bitbox.Address.detectFormat(address as String) == 1) {
+      if (bitbox.Address.detectFormat(address as String) ==
+          bitbox.Address.formatLegacy) {
         changeAddressesP2PKH.add(bitbox.Address.toCashAddress(address));
       } else {
         changeAddressesP2PKH.add(address);
@@ -2151,7 +2155,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
             if (!(cachedTx != null &&
                 addressType(address: cachedTx.address) ==
                     DerivePathType.bip44 &&
-                bitbox.Address.detectFormat(cachedTx.address) == 1)) {
+                bitbox.Address.detectFormat(cachedTx.address) ==
+                    bitbox.Address.formatLegacy)) {
               allTxHashes.remove(tx);
             }
           }
@@ -2811,7 +2816,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
           final n = output["n"];
           if (n != null && n == utxosToUse[i].vout) {
             String address = output["scriptPubKey"]["addresses"][0] as String;
-            if (bitbox.Address.detectFormat(address) == 0) {
+            if (bitbox.Address.detectFormat(address) ==
+                bitbox.Address.formatCashAddr) {
               address = bitbox.Address.toLegacyAddress(address);
             }
             if (!addressTxid.containsKey(address)) {
@@ -2843,7 +2849,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
         );
         for (int i = 0; i < p2pkhLength; i++) {
           String address = addressesP2PKH[i];
-          if (bitbox.Address.detectFormat(address) == 0) {
+          if (bitbox.Address.detectFormat(address) ==
+              bitbox.Address.formatCashAddr) {
             address = bitbox.Address.toLegacyAddress(address);
           }
 

From 74b075328f856de25dca0a5f54d43f59627a07a0 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 4 Nov 2022 17:22:22 -0600
Subject: [PATCH 137/426] temp bch send fix

---
 .../coins/bitcoincash/bitcoincash_wallet.dart        | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index 0a72cea99..09578c1ca 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -1162,7 +1162,17 @@ class BitcoinCashWallet extends CoinServiceAPI {
       if (kDebugMode) {
         print("format $format");
       }
-      return true;
+
+      if (format == bitbox.Address.formatCashAddr) {
+        String addr = address;
+        if (address.contains(":")) {
+          addr = address.split(":").last;
+        }
+
+        return addr.startsWith("q");
+      } else {
+        return address.startsWith("1");
+      }
     } catch (e) {
       return false;
     }

From a5d7723deee4e932f3070cc3ec63dd9f8c5d92c4 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 4 Nov 2022 17:49:36 -0600
Subject: [PATCH 138/426] added buttons and restore dialog

---
 .../create_backup_view.dart                   | 36 +++++++++++--
 .../restore_from_file_view.dart               | 52 ++++++++++++++++---
 2 files changed, 77 insertions(+), 11 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index b710aacf4..2d2ed4960 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -17,6 +17,8 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
@@ -142,14 +144,38 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
         condition: isDesktop,
         builder: (child) {
           return Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
             children: [
-              Text(
-                "Choose file location",
-                style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                    color:
-                        Theme.of(context).extension<StackColors>()!.textDark3),
+              Padding(
+                padding: const EdgeInsets.all(10.0),
+                child: Text(
+                  "Choose file location",
+                  style: STextStyles.desktopTextExtraExtraSmall(context)
+                      .copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark3),
+                ),
               ),
               // child,
+              const SizedBox(height: 20),
+              Row(
+                children: [
+                  PrimaryButton(
+                    desktopMed: true,
+                    width: 200,
+                    label: "Create backup",
+                    onPressed: () {},
+                  ),
+                  const SizedBox(width: 16),
+                  SecondaryButton(
+                    desktopMed: true,
+                    width: 200,
+                    label: "Cancel",
+                    onPressed: () {},
+                  ),
+                ],
+              ),
             ],
           );
         },
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index 16c3ea8e3..9f2796415 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -8,6 +8,7 @@ import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -18,6 +19,8 @@ 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/custom_buttons/app_bar_icon_button.dart';
+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/stack_text_field.dart';
 import 'package:tuple/tuple.dart';
@@ -42,6 +45,17 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
 
   bool hidePassword = true;
 
+  Future<void> restoreBackupPopup(BuildContext context) async {
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) {
+        return const RestoreBackupDialog();
+      },
+    );
+  }
+
   @override
   void initState() {
     stackFileSystem = StackFileSystem();
@@ -114,15 +128,41 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
           condition: isDesktop,
           builder: (child) {
             return Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
               children: [
-                Text(
-                  "Choose file location",
-                  style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .textDark3),
+                Padding(
+                  padding: const EdgeInsets.all(10.0),
+                  child: Text(
+                    "Choose file location",
+                    style: STextStyles.desktopTextExtraExtraSmall(context)
+                        .copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark3),
+                    textAlign: TextAlign.left,
+                  ),
                 ),
                 // child,
+                const SizedBox(height: 20),
+                Row(
+                  children: [
+                    PrimaryButton(
+                      desktopMed: true,
+                      width: 200,
+                      label: "Restore",
+                      onPressed: () {
+                        restoreBackupPopup(context);
+                      },
+                    ),
+                    const SizedBox(width: 16),
+                    SecondaryButton(
+                      desktopMed: true,
+                      width: 200,
+                      label: "Cancel",
+                      onPressed: () {},
+                    ),
+                  ],
+                ),
               ],
             );
           },

From e06910a34a68451d00cb337dcf7d194eb19d34cd Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 4 Nov 2022 17:50:51 -0600
Subject: [PATCH 139/426] WIP: theme change

---
 .../settings_menu/appearance_settings.dart    | 216 ++++++++++--------
 1 file changed, 125 insertions(+), 91 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
index d524453e2..b5f239ab1 100644
--- a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
@@ -23,6 +23,19 @@ class AppearanceOptionSettings extends ConsumerStatefulWidget {
 
 class _AppearanceOptionSettings
     extends ConsumerState<AppearanceOptionSettings> {
+  // late bool isLight;
+
+  // @override
+  // void initState() {
+  //
+  //   super.initState();
+  // }
+  //
+  // @override
+  // void dispose() {
+  //   super.dispose();
+  // }
+
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
@@ -127,13 +140,7 @@ class _AppearanceOptionSettings
                     ],
                   ),
                 ),
-                const Padding(
-                  padding: EdgeInsets.only(
-                    left: 10,
-                    right: 10,
-                  ),
-                  child: ThemeToggle(),
-                ),
+                ThemeToggle(),
               ],
             ),
           ),
@@ -169,95 +176,38 @@ class _ThemeToggle extends State<ThemeToggle> {
             elevation: 0,
             hoverColor: Colors.transparent,
             shape: RoundedRectangleBorder(
+              side: BorderSide(
+                color:
+                    Theme.of(context).extension<StackColors>()!.infoItemIcons,
+                width: 2,
+              ),
+              // side: !externalCallsEnabled
+              //     ? BorderSide.none
+              //     : BorderSide(
+              //         color: Theme.of(context)
+              //             .extension<StackColors>()!
+              //             .infoItemIcons,
+              //         width: 2,
+              //       ),
               borderRadius: BorderRadius.circular(
                 Constants.size.circularBorderRadius * 2,
               ),
             ),
             onPressed: () {}, //onPressed
-            child: Stack(
-              children: [
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
-                    Padding(
-                      padding: const EdgeInsets.only(
-                        left: 24,
-                      ),
-                      child: SvgPicture.asset(
-                        Assets.svg.themeLight,
-                      ),
-                    ),
-                    Padding(
-                      padding: const EdgeInsets.only(
-                        left: 50,
-                        top: 12,
-                      ),
-                      child: Text(
-                        "Light",
-                        style:
-                            STextStyles.desktopTextExtraSmall(context).copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .textDark,
-                        ),
-                      ),
-                    )
-                  ],
-                ),
-                // if (externalCallsEnabled)
-                Positioned(
-                  bottom: 0,
-                  left: 6,
-                  child: SvgPicture.asset(
-                    Assets.svg.checkCircle,
-                    width: 20,
-                    height: 20,
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .infoItemIcons,
-                  ),
-                ),
-                // if (!externalCallsEnabled)
-                //   Positioned(
-                //     top: 4,
-                //     right: 4,
-                //     child: Container(
-                //       width: 20,
-                //       height: 20,
-                //       decoration: BoxDecoration(
-                //         borderRadius: BorderRadius.circular(1000),
-                //         color: Theme.of(context)
-                //             .extension<StackColors>()!
-                //             .textFieldDefaultBG,
-                //       ),
-                //     ),
-                //   ),
-              ],
-            ),
-          ),
-        ),
-        const SizedBox(
-          width: 1,
-        ),
-        Expanded(
-          child: Padding(
-            padding: const EdgeInsets.all(8.0),
-            child: RawMaterialButton(
-              elevation: 0,
-              hoverColor: Colors.transparent,
-              shape: RoundedRectangleBorder(
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius * 2,
-                ),
-              ),
-              onPressed: () {}, //onPressed
+            child: Padding(
+              padding: const EdgeInsets.all(8.0),
               child: Stack(
                 children: [
                   Column(
                     crossAxisAlignment: CrossAxisAlignment.start,
                     children: [
-                      SvgPicture.asset(
-                        Assets.svg.themeDark,
+                      Padding(
+                        padding: const EdgeInsets.only(
+                          left: 24,
+                        ),
+                        child: SvgPicture.asset(
+                          Assets.svg.themeLight,
+                        ),
                       ),
                       Padding(
                         padding: const EdgeInsets.only(
@@ -265,7 +215,7 @@ class _ThemeToggle extends State<ThemeToggle> {
                           top: 12,
                         ),
                         child: Text(
-                          "Dark",
+                          "Light",
                           style: STextStyles.desktopTextExtraSmall(context)
                               .copyWith(
                             color: Theme.of(context)
@@ -273,13 +223,13 @@ class _ThemeToggle extends State<ThemeToggle> {
                                 .textDark,
                           ),
                         ),
-                      ),
+                      )
                     ],
                   ),
                   // if (externalCallsEnabled)
                   Positioned(
                     bottom: 0,
-                    left: 0,
+                    left: 6,
                     child: SvgPicture.asset(
                       Assets.svg.checkCircle,
                       width: 20,
@@ -291,8 +241,8 @@ class _ThemeToggle extends State<ThemeToggle> {
                   ),
                   // if (!externalCallsEnabled)
                   //   Positioned(
-                  //     top: 4,
-                  //     right: 4,
+                  //     bottom: 0,
+                  //     left: 6,
                   //     child: Container(
                   //       width: 20,
                   //       height: 20,
@@ -309,6 +259,90 @@ class _ThemeToggle extends State<ThemeToggle> {
             ),
           ),
         ),
+        const SizedBox(
+          width: 1,
+        ),
+        Expanded(
+          child: Padding(
+            padding: const EdgeInsets.all(8.0),
+            child: RawMaterialButton(
+              elevation: 0,
+              hoverColor: Colors.transparent,
+              shape: RoundedRectangleBorder(
+                // side: !externalCallsEnabled
+                //     ? BorderSide.none
+                //     : BorderSide(
+                //         color: Theme.of(context)
+                //             .extension<StackColors>()!
+                //             .infoItemIcons,
+                //         width: 2,
+                //       ),
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius * 2,
+                ),
+              ),
+              onPressed: () {}, //onPressed
+              child: Padding(
+                padding: const EdgeInsets.all(8.0),
+                child: Stack(
+                  children: [
+                    Column(
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      children: [
+                        SvgPicture.asset(
+                          Assets.svg.themeDark,
+                        ),
+                        Padding(
+                          padding: const EdgeInsets.only(
+                            left: 45,
+                            top: 12,
+                          ),
+                          child: Text(
+                            "Dark",
+                            style: STextStyles.desktopTextExtraSmall(context)
+                                .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark,
+                            ),
+                          ),
+                        ),
+                      ],
+                    ),
+                    // if (externalCallsEnabled)
+                    //   Positioned(
+                    //     bottom: 0,
+                    //     left: 0,
+                    //     child: SvgPicture.asset(
+                    //       Assets.svg.checkCircle,
+                    //       width: 20,
+                    //       height: 20,
+                    //       color: Theme.of(context)
+                    //           .extension<StackColors>()!
+                    //           .infoItemIcons,
+                    //     ),
+                    //   ),
+                    // if (!externalCallsEnabled)
+                    Positioned(
+                      bottom: 0,
+                      left: 0,
+                      child: Container(
+                        width: 20,
+                        height: 20,
+                        decoration: BoxDecoration(
+                          borderRadius: BorderRadius.circular(1000),
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textFieldDefaultBG,
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+              ),
+            ),
+          ),
+        ),
       ],
     );
   }

From 7dbc9d270b1e3d62fed837179241b9350a7234d9 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 4 Nov 2022 18:18:25 -0600
Subject: [PATCH 140/426] temp bch send fix testnet and fix tests

---
 lib/services/coins/bitcoincash/bitcoincash_wallet.dart       | 4 ++++
 test/services/coins/bitcoincash/bitcoincash_wallet_test.dart | 3 +--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index 09578c1ca..b96aa160c 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -1163,6 +1163,10 @@ class BitcoinCashWallet extends CoinServiceAPI {
         print("format $format");
       }
 
+      if (_coin == Coin.bitcoincashTestnet) {
+        return true;
+      }
+
       if (format == bitbox.Address.formatCashAddr) {
         String addr = address;
         if (address.contains(":")) {
diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart
index 4c392fe81..50ff8f741 100644
--- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart
+++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart
@@ -1,4 +1,3 @@
-import 'package:bitcoindart/bitcoindart.dart';
 import 'package:decimal/decimal.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:hive/hive.dart';
@@ -140,7 +139,7 @@ void main() {
     test("invalid mainnet bitcoincash legacy/p2pkh address", () {
       expect(
           mainnetWallet?.validateAddress("mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"),
-          true);
+          false);
       expect(secureStore?.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);

From b4d97e86cc1c6d3a00e62e0d614729aa1ea3c324 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 4 Nov 2022 18:26:23 -0600
Subject: [PATCH 141/426] long address fix

---
 .../transaction_details_view.dart             | 141 +++++++++---------
 1 file changed, 73 insertions(+), 68 deletions(-)

diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
index 6f23f2e01..1c2fb8e5d 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -471,75 +471,80 @@ class _TransactionDetailsViewState
                                     MainAxisAlignment.spaceBetween,
                                 crossAxisAlignment: CrossAxisAlignment.start,
                                 children: [
-                                  Column(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.start,
-                                    children: [
-                                      Text(
+                                  Expanded(
+                                    child: Column(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        Text(
+                                          _transaction.txType.toLowerCase() ==
+                                                  "sent"
+                                              ? "Sent to"
+                                              : "Receiving address",
+                                          style: isDesktop
+                                              ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              : STextStyles.itemSubtitle(
+                                                  context),
+                                        ),
+                                        const SizedBox(
+                                          height: 8,
+                                        ),
                                         _transaction.txType.toLowerCase() ==
-                                                "sent"
-                                            ? "Sent to"
-                                            : "Receiving address",
-                                        style: isDesktop
-                                            ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            : STextStyles.itemSubtitle(context),
-                                      ),
-                                      const SizedBox(
-                                        height: 8,
-                                      ),
-                                      _transaction.txType.toLowerCase() ==
-                                              "received"
-                                          ? FutureBuilder(
-                                              future: fetchContactNameFor(
-                                                  _transaction.address),
-                                              builder: (builderContext,
-                                                  AsyncSnapshot<String>
-                                                      snapshot) {
-                                                String addressOrContactName =
-                                                    _transaction.address;
-                                                if (snapshot.connectionState ==
-                                                        ConnectionState.done &&
-                                                    snapshot.hasData) {
-                                                  addressOrContactName =
-                                                      snapshot.data!;
-                                                }
-                                                return SelectableText(
-                                                  addressOrContactName,
-                                                  style: isDesktop
-                                                      ? STextStyles
-                                                              .desktopTextExtraExtraSmall(
-                                                                  context)
-                                                          .copyWith(
-                                                          color: Theme.of(
-                                                                  context)
-                                                              .extension<
-                                                                  StackColors>()!
-                                                              .textDark,
-                                                        )
-                                                      : STextStyles
-                                                          .itemSubtitle12(
-                                                              context),
-                                                );
-                                              },
-                                            )
-                                          : SelectableText(
-                                              _transaction.address,
-                                              style: isDesktop
-                                                  ? STextStyles
-                                                          .desktopTextExtraExtraSmall(
-                                                              context)
-                                                      .copyWith(
-                                                      color: Theme.of(context)
-                                                          .extension<
-                                                              StackColors>()!
-                                                          .textDark,
-                                                    )
-                                                  : STextStyles.itemSubtitle12(
-                                                      context),
-                                            ),
-                                    ],
+                                                "received"
+                                            ? FutureBuilder(
+                                                future: fetchContactNameFor(
+                                                    _transaction.address),
+                                                builder: (builderContext,
+                                                    AsyncSnapshot<String>
+                                                        snapshot) {
+                                                  String addressOrContactName =
+                                                      _transaction.address;
+                                                  if (snapshot.connectionState ==
+                                                          ConnectionState
+                                                              .done &&
+                                                      snapshot.hasData) {
+                                                    addressOrContactName =
+                                                        snapshot.data!;
+                                                  }
+                                                  return SelectableText(
+                                                    addressOrContactName,
+                                                    style: isDesktop
+                                                        ? STextStyles
+                                                                .desktopTextExtraExtraSmall(
+                                                                    context)
+                                                            .copyWith(
+                                                            color: Theme.of(
+                                                                    context)
+                                                                .extension<
+                                                                    StackColors>()!
+                                                                .textDark,
+                                                          )
+                                                        : STextStyles
+                                                            .itemSubtitle12(
+                                                                context),
+                                                  );
+                                                },
+                                              )
+                                            : SelectableText(
+                                                _transaction.address,
+                                                style: isDesktop
+                                                    ? STextStyles
+                                                            .desktopTextExtraExtraSmall(
+                                                                context)
+                                                        .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .textDark,
+                                                      )
+                                                    : STextStyles
+                                                        .itemSubtitle12(
+                                                            context),
+                                              ),
+                                      ],
+                                    ),
                                   ),
                                   if (isDesktop)
                                     IconCopyButton(

From e87aa64e1b79c9671f9ba888cd4188c78fca2fb1 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 5 Nov 2022 09:40:28 -0600
Subject: [PATCH 142/426] isFavorite bandaid fix for
 https://github.com/cypherstack/stack_wallet/issues/203

---
 lib/services/coins/bitcoin/bitcoin_wallet.dart         | 7 ++++---
 lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 7 ++++---
 lib/services/coins/dogecoin/dogecoin_wallet.dart       | 7 ++++---
 lib/services/coins/epiccash/epiccash_wallet.dart       | 7 ++++---
 lib/services/coins/firo/firo_wallet.dart               | 7 ++++---
 lib/services/coins/litecoin/litecoin_wallet.dart       | 7 ++++---
 lib/services/coins/monero/monero_wallet.dart           | 7 ++++---
 lib/services/coins/namecoin/namecoin_wallet.dart       | 7 ++++---
 lib/services/coins/wownero/wownero_wallet.dart         | 7 ++++---
 9 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart
index da3bdfed0..391beb909 100644
--- a/lib/services/coins/bitcoin/bitcoin_wallet.dart
+++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart
@@ -174,9 +174,10 @@ class BitcoinWallet extends CoinServiceAPI {
       return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
           as bool;
     } catch (e, s) {
-      Logging.instance
-          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
-      rethrow;
+      Logging.instance.log(
+          "isFavorite fetch failed (returning false by default): $e\n$s",
+          level: LogLevel.Error);
+      return false;
     }
   }
 
diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index b96aa160c..fa88b3f2f 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -3376,9 +3376,10 @@ class BitcoinCashWallet extends CoinServiceAPI {
       return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
           as bool;
     } catch (e, s) {
-      Logging.instance
-          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
-      rethrow;
+      Logging.instance.log(
+          "isFavorite fetch failed (returning false by default): $e\n$s",
+          level: LogLevel.Error);
+      return false;
     }
   }
 
diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart
index 0235a0c02..fbb551dcd 100644
--- a/lib/services/coins/dogecoin/dogecoin_wallet.dart
+++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart
@@ -2983,9 +2983,10 @@ class DogecoinWallet extends CoinServiceAPI {
       return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
           as bool;
     } catch (e, s) {
-      Logging.instance
-          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
-      rethrow;
+      Logging.instance.log(
+          "isFavorite fetch failed (returning false by default): $e\n$s",
+          level: LogLevel.Error);
+      return false;
     }
   }
 
diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart
index 7ccb7feaf..b98854e61 100644
--- a/lib/services/coins/epiccash/epiccash_wallet.dart
+++ b/lib/services/coins/epiccash/epiccash_wallet.dart
@@ -558,9 +558,10 @@ class EpicCashWallet extends CoinServiceAPI {
       return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
           as bool;
     } catch (e, s) {
-      Logging.instance
-          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
-      rethrow;
+      Logging.instance.log(
+          "isFavorite fetch failed (returning false by default): $e\n$s",
+          level: LogLevel.Error);
+      return false;
     }
   }
 
diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart
index 61ef2e9de..2a2102e7c 100644
--- a/lib/services/coins/firo/firo_wallet.dart
+++ b/lib/services/coins/firo/firo_wallet.dart
@@ -821,9 +821,10 @@ class FiroWallet extends CoinServiceAPI {
       return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
           as bool;
     } catch (e, s) {
-      Logging.instance
-          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
-      rethrow;
+      Logging.instance.log(
+          "isFavorite fetch failed (returning false by default): $e\n$s",
+          level: LogLevel.Error);
+      return false;
     }
   }
 
diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart
index 0ab3a92a8..c07cca1f3 100644
--- a/lib/services/coins/litecoin/litecoin_wallet.dart
+++ b/lib/services/coins/litecoin/litecoin_wallet.dart
@@ -174,9 +174,10 @@ class LitecoinWallet extends CoinServiceAPI {
       return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
           as bool;
     } catch (e, s) {
-      Logging.instance
-          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
-      rethrow;
+      Logging.instance.log(
+          "isFavorite fetch failed (returning false by default): $e\n$s",
+          level: LogLevel.Error);
+      return false;
     }
   }
 
diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index b0ebac4e6..9bcc3515f 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -1376,9 +1376,10 @@ class MoneroWallet extends CoinServiceAPI {
       return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
           as bool;
     } catch (e, s) {
-      Logging.instance
-          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
-      rethrow;
+      Logging.instance.log(
+          "isFavorite fetch failed (returning false by default): $e\n$s",
+          level: LogLevel.Error);
+      return false;
     }
   }
 
diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart
index e9cae1ab2..893db69e0 100644
--- a/lib/services/coins/namecoin/namecoin_wallet.dart
+++ b/lib/services/coins/namecoin/namecoin_wallet.dart
@@ -170,9 +170,10 @@ class NamecoinWallet extends CoinServiceAPI {
       return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
           as bool;
     } catch (e, s) {
-      Logging.instance
-          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
-      rethrow;
+      Logging.instance.log(
+          "isFavorite fetch failed (returning false by default): $e\n$s",
+          level: LogLevel.Error);
+      return false;
     }
   }
 
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index d3aba5bbb..342e5d84a 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -1382,9 +1382,10 @@ class WowneroWallet extends CoinServiceAPI {
       return DB.instance.get<dynamic>(boxName: walletId, key: "isFavorite")
           as bool;
     } catch (e, s) {
-      Logging.instance
-          .log("isFavorite fetch failed: $e\n$s", level: LogLevel.Error);
-      rethrow;
+      Logging.instance.log(
+          "isFavorite fetch failed (returning false by default): $e\n$s",
+          level: LogLevel.Error);
+      return false;
     }
   }
 

From 1e61a779ecd8620aa44c472dcd94ab49ba00d73a Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 7 Nov 2022 08:15:44 -0700
Subject: [PATCH 143/426] desktop support view route added

---
 lib/pages_desktop_specific/home/desktop_home_view.dart     | 7 +++++--
 .../home/support_and_about_view/desktop_support_view.dart  | 0
 lib/route_generator.dart                                   | 7 +++++++
 3 files changed, 12 insertions(+), 2 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart

diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index 6aa104081..e9f6f2b4b 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_menu.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
@@ -37,8 +38,10 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: DesktopSettingsView.routeName,
     ),
-    Container(
-      color: Colors.blue,
+    const Navigator(
+      key: Key("desktopSupportHomeKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: DesktopSupportView.routeName,
     ),
     Container(
       color: Colors.pink,
diff --git a/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart b/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart
new file mode 100644
index 000000000..e69de29bb
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index a6f23ffdc..47a84f07c 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -99,6 +99,7 @@ import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_sett
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
 import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
@@ -1084,6 +1085,12 @@ class RouteGenerator {
             builder: (_) => const AdvancedSettings(),
             settings: RouteSettings(name: settings.name));
 
+      case DesktopSupportView.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const DesktopSupportView(),
+            settings: RouteSettings(name: settings.name));
+
       case WalletKeysDesktopPopup.routeName:
         if (args is List<String>) {
           return FadePageRoute(

From dbb2b309ca243e650660bd13af1551cfe8f94f0c Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 7 Nov 2022 09:15:02 -0700
Subject: [PATCH 144/426] blue link text added to desktop

---
 .../global_settings_view/support_view.dart    | 535 +++++++++++-------
 .../desktop_support_view.dart                 |  50 ++
 2 files changed, 366 insertions(+), 219 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/support_view.dart b/lib/pages/settings_views/global_settings_view/support_view.dart
index fdfa6f404..20aeedf61 100644
--- a/lib/pages/settings_views/global_settings_view/support_view.dart
+++ b/lib/pages/settings_views/global_settings_view/support_view.dart
@@ -4,7 +4,10 @@ import 'package:stackwallet/utilities/assets.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/conditional_parent.dart';
 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/rounded_white_container.dart';
 import 'package:url_launcher/url_launcher.dart';
 
@@ -18,269 +21,363 @@ class SupportView extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
+    final isDesktop = Util.isDesktop;
+
     debugPrint("BUILD: $runtimeType");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Support",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            RoundedWhiteContainer(
-              child: Text(
-                "If you need support or want to report a bug, reach out to us on any of our socials!",
-                style: STextStyles.smallMed12(context),
-              ),
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
             ),
-            const SizedBox(
-              height: 12,
+            title: Text(
+              "Support",
+              style: STextStyles.navBarTitle(context),
             ),
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
+          ),
+          body: Padding(
+            padding: const EdgeInsets.all(16),
+            child: child,
+          ),
+        );
+      },
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.stretch,
+        children: [
+          RoundedWhiteContainer(
+            child: Text(
+              "If you need support or want to report a bug, reach out to us on any of our socials!",
+              style: STextStyles.smallMed12(context),
+            ),
+          ),
+          isDesktop
+              ? const SizedBox(
+                  height: 24,
+                )
+              : const SizedBox(
+                  height: 12,
                 ),
-                onPressed: () {
+          RoundedWhiteContainer(
+            padding: const EdgeInsets.all(0),
+            child: RawMaterialButton(
+              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+              shape: RoundedRectangleBorder(
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
+              ),
+              onPressed: () {
+                if (!isDesktop) {
                   launchUrl(
                     Uri.parse("https://t.me/stackwallet"),
                     mode: LaunchMode.externalApplication,
                   );
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    children: [
-                      SvgPicture.asset(
-                        Assets.socials.telegram,
-                        width: iconSize,
-                        height: iconSize,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .accentColorDark,
-                      ),
-                      const SizedBox(
-                        width: 12,
-                      ),
-                      Text(
-                        "Telegram",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                    ],
-                  ),
+                }
+              },
+              child: Padding(
+                padding: const EdgeInsets.symmetric(
+                  horizontal: 12,
+                  vertical: 20,
+                ),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Row(
+                      children: [
+                        SvgPicture.asset(
+                          Assets.socials.telegram,
+                          width: iconSize,
+                          height: iconSize,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorDark,
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                        Text(
+                          "Telegram",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
+                    BlueTextButton(
+                      text: isDesktop ? "@stackwallet" : "",
+                      onTap: () {
+                        launchUrl(
+                          Uri.parse("https://t.me/stackwallet"),
+                          mode: LaunchMode.externalApplication,
+                        );
+                      },
+                    ),
+                  ],
                 ),
               ),
             ),
-            const SizedBox(
-              height: 8,
-            ),
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
+          ),
+          const SizedBox(
+            height: 8,
+          ),
+          RoundedWhiteContainer(
+            padding: const EdgeInsets.all(0),
+            child: RawMaterialButton(
+              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+              shape: RoundedRectangleBorder(
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
                 ),
-                onPressed: () {
+              ),
+              onPressed: () {
+                if (!isDesktop) {
                   launchUrl(
                     Uri.parse("https://discord.gg/RZMG3yUm"),
                     mode: LaunchMode.externalApplication,
                   );
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    children: [
-                      SvgPicture.asset(
-                        Assets.socials.discord,
-                        width: iconSize,
-                        height: iconSize,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .accentColorDark,
-                      ),
-                      const SizedBox(
-                        width: 12,
-                      ),
-                      Text(
-                        "Discord",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                    ],
-                  ),
+                }
+              },
+              child: Padding(
+                padding: const EdgeInsets.symmetric(
+                  horizontal: 12,
+                  vertical: 20,
+                ),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Row(
+                      children: [
+                        SvgPicture.asset(
+                          Assets.socials.discord,
+                          width: iconSize,
+                          height: iconSize,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorDark,
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                        Text(
+                          "Discord",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
+                    BlueTextButton(
+                      text: isDesktop ? "Stack Wallet" : "",
+                      onTap: () {
+                        launchUrl(
+                          Uri.parse(
+                              "https://discord.gg/RZMG3yUm"), //expired link?
+                          mode: LaunchMode.externalApplication,
+                        );
+                      },
+                    ),
+                  ],
                 ),
               ),
             ),
-            const SizedBox(
-              height: 8,
-            ),
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
+          ),
+          const SizedBox(
+            height: 8,
+          ),
+          RoundedWhiteContainer(
+            padding: const EdgeInsets.all(0),
+            child: RawMaterialButton(
+              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+              shape: RoundedRectangleBorder(
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
                 ),
-                onPressed: () {
+              ),
+              onPressed: () {
+                if (!isDesktop) {
                   launchUrl(
                     Uri.parse("https://www.reddit.com/r/stackwallet/"),
                     mode: LaunchMode.externalApplication,
                   );
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    children: [
-                      SvgPicture.asset(
-                        Assets.socials.reddit,
-                        width: iconSize,
-                        height: iconSize,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .accentColorDark,
-                      ),
-                      const SizedBox(
-                        width: 12,
-                      ),
-                      Text(
-                        "Reddit",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                    ],
-                  ),
+                }
+              },
+              child: Padding(
+                padding: const EdgeInsets.symmetric(
+                  horizontal: 12,
+                  vertical: 20,
+                ),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Row(
+                      children: [
+                        SvgPicture.asset(
+                          Assets.socials.reddit,
+                          width: iconSize,
+                          height: iconSize,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorDark,
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                        Text(
+                          "Reddit",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
+                    BlueTextButton(
+                      text: isDesktop ? "r/stackwallet" : "",
+                      onTap: () {
+                        launchUrl(
+                          Uri.parse("https://www.reddit.com/r/stackwallet/"),
+                          mode: LaunchMode.externalApplication,
+                        );
+                      },
+                    ),
+                  ],
                 ),
               ),
             ),
-            const SizedBox(
-              height: 8,
-            ),
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
+          ),
+          const SizedBox(
+            height: 8,
+          ),
+          RoundedWhiteContainer(
+            padding: const EdgeInsets.all(0),
+            child: RawMaterialButton(
+              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+              shape: RoundedRectangleBorder(
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
                 ),
-                onPressed: () {
+              ),
+              onPressed: () {
+                if (!isDesktop) {
                   launchUrl(
                     Uri.parse("https://twitter.com/stack_wallet"),
                     mode: LaunchMode.externalApplication,
                   );
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    children: [
-                      SvgPicture.asset(
-                        Assets.socials.twitter,
-                        width: iconSize,
-                        height: iconSize,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .accentColorDark,
-                      ),
-                      const SizedBox(
-                        width: 12,
-                      ),
-                      Text(
-                        "Twitter",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                    ],
-                  ),
+                }
+              },
+              child: Padding(
+                padding: const EdgeInsets.symmetric(
+                  horizontal: 12,
+                  vertical: 20,
+                ),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Row(
+                      children: [
+                        SvgPicture.asset(
+                          Assets.socials.twitter,
+                          width: iconSize,
+                          height: iconSize,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorDark,
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                        Text(
+                          "Twitter",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
+                    BlueTextButton(
+                      text: isDesktop ? "@stack_wallet" : "",
+                      onTap: () {
+                        launchUrl(
+                          Uri.parse("https://twitter.com/stack_wallet"),
+                          mode: LaunchMode.externalApplication,
+                        );
+                      },
+                    ),
+                  ],
                 ),
               ),
             ),
-            const SizedBox(
-              height: 8,
-            ),
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
+          ),
+          const SizedBox(
+            height: 8,
+          ),
+          RoundedWhiteContainer(
+            padding: const EdgeInsets.all(0),
+            child: RawMaterialButton(
+              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+              shape: RoundedRectangleBorder(
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
                 ),
-                onPressed: () {
+              ),
+              onPressed: () {
+                if (!isDesktop) {
                   launchUrl(
                     Uri.parse("mailto://support@stackwallet.com"),
                     mode: LaunchMode.externalApplication,
                   );
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    children: [
-                      SvgPicture.asset(
-                        Assets.svg.envelope,
-                        width: iconSize,
-                        height: iconSize,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .accentColorDark,
-                      ),
-                      const SizedBox(
-                        width: 12,
-                      ),
-                      Text(
-                        "Email",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                    ],
-                  ),
+                }
+              },
+              child: Padding(
+                padding: const EdgeInsets.symmetric(
+                  horizontal: 12,
+                  vertical: 20,
+                ),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Row(
+                      children: [
+                        SvgPicture.asset(
+                          Assets.svg.envelope,
+                          width: iconSize,
+                          height: iconSize,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorDark,
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                        Text(
+                          "Email",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
+                    BlueTextButton(
+                      text: isDesktop ? "support@stackwallet.com" : "",
+                      onTap: () {
+                        launchUrl(
+                          Uri.parse("mailto://support@stackwallet.com"),
+                          mode: LaunchMode.externalApplication,
+                        );
+                      },
+                    ),
+                  ],
                 ),
               ),
             ),
-          ],
-        ),
+          ),
+        ],
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart b/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart
index e69de29bb..8e9d709d1 100644
--- a/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart
+++ b/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart
@@ -0,0 +1,50 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+
+import '../../../pages/settings_views/global_settings_view/support_view.dart';
+
+class DesktopSupportView extends ConsumerStatefulWidget {
+  const DesktopSupportView({Key? key}) : super(key: key);
+
+  static const String routeName = "/desktopSupportView";
+
+  @override
+  ConsumerState<DesktopSupportView> createState() => _DesktopSupportView();
+}
+
+class _DesktopSupportView extends ConsumerState<DesktopSupportView> {
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    return DesktopScaffold(
+      background: Theme.of(context).extension<StackColors>()!.background,
+      appBar: DesktopAppBar(
+        isCompactHeight: true,
+        leading: Row(
+          children: [
+            const SizedBox(
+              width: 24,
+              height: 24,
+            ),
+            Text(
+              "Support",
+              style: STextStyles.desktopH3(context),
+            )
+          ],
+        ),
+      ),
+      body: Column(
+        children: const [
+          Padding(
+            padding: EdgeInsets.fromLTRB(24, 10, 377, 270),
+            child: SupportView(),
+          ),
+        ],
+      ),
+    );
+  }
+}

From 786831bcef80f10660f8f73d8708e1c57dffd497 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 7 Nov 2022 08:31:27 -0600
Subject: [PATCH 145/426] alphabetically sort contacts

---
 lib/services/address_book_service.dart | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/services/address_book_service.dart b/lib/services/address_book_service.dart
index 6f7d2b9bd..f51eefbba 100644
--- a/lib/services/address_book_service.dart
+++ b/lib/services/address_book_service.dart
@@ -20,10 +20,13 @@ class AddressBookService extends ChangeNotifier {
   List<Contact> get contacts {
     final keys = List<String>.from(
         DB.instance.keys<dynamic>(boxName: DB.boxNameAddressBook));
-    return keys
+    final _contacts = keys
         .map((id) => Contact.fromJson(Map<String, dynamic>.from(DB.instance
             .get<dynamic>(boxName: DB.boxNameAddressBook, key: id) as Map)))
         .toList(growable: false);
+    _contacts
+        .sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));
+    return _contacts;
   }
 
   Future<List<Contact>>? _addressBookEntries;

From f6bad974e6915338ce94c22ea356833b8cb8c8c8 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 7 Nov 2022 10:14:47 -0600
Subject: [PATCH 146/426] address book tests updated

---
 test/address_book_service_test.dart | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/test/address_book_service_test.dart b/test/address_book_service_test.dart
index 1059f7fc3..c5effd223 100644
--- a/test/address_book_service_test.dart
+++ b/test/address_book_service_test.dart
@@ -94,19 +94,19 @@ void main() {
     test("get contacts", () {
       final service = AddressBookService();
       expect(service.contacts.toString(),
-          [contactA, contactB, contactC].toString());
+          [contactC, contactB, contactA].toString());
     });
 
     test("get addressBookEntries", () async {
       final service = AddressBookService();
       expect((await service.addressBookEntries).toString(),
-          [contactA, contactB, contactC].toString());
+          [contactC, contactB, contactA].toString());
     });
 
     test("search contacts", () async {
       final service = AddressBookService();
       final results = await service.search("j");
-      expect(results.toString(), [contactA, contactB].toString());
+      expect(results.toString(), [contactB, contactA].toString());
 
       final results2 = await service.search("ja");
       expect(results2.toString(), [contactB].toString());
@@ -118,7 +118,7 @@ void main() {
       expect(results4.toString(), <Contact>[].toString());
 
       final results5 = await service.search("");
-      expect(results5.toString(), [contactA, contactB, contactC].toString());
+      expect(results5.toString(), [contactC, contactB, contactA].toString());
 
       final results6 = await service.search("epic address");
       expect(results6.toString(), [contactC].toString());
@@ -140,7 +140,7 @@ void main() {
       expect(result, false);
       expect(service.contacts.length, 3);
       expect(service.contacts.toString(),
-          [contactA, contactB, contactC].toString());
+          [contactC, contactB, contactA].toString());
     });
 
     test("edit contact", () async {
@@ -149,14 +149,14 @@ void main() {
       expect(await service.editContact(editedContact), true);
       expect(service.contacts.length, 3);
       expect(service.contacts.toString(),
-          [contactA, editedContact, contactC].toString());
+          [contactC, contactA, editedContact].toString());
     });
 
     test("remove existing contact", () async {
       final service = AddressBookService();
       await service.removeContact(contactB.id);
       expect(service.contacts.length, 2);
-      expect(service.contacts.toString(), [contactA, contactC].toString());
+      expect(service.contacts.toString(), [contactC, contactA].toString());
     });
 
     test("remove non existing contact", () async {
@@ -164,7 +164,7 @@ void main() {
       await service.removeContact("some id");
       expect(service.contacts.length, 3);
       expect(service.contacts.toString(),
-          [contactA, contactB, contactC].toString());
+          [contactC, contactB, contactA].toString());
     });
 
     tearDown(() async {

From bb260e3a23b7e0c1ddd4509d16a95db3a51305c0 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 7 Nov 2022 10:24:08 -0600
Subject: [PATCH 147/426] hacky fix (due to current persistence design) to get
 sent transactions showing up right away for electrumx coins

---
 .../send_view/confirm_transaction_view.dart   |  4 +-
 .../coins/bitcoin/bitcoin_wallet.dart         | 50 +++++++++++++++++++
 .../coins/bitcoincash/bitcoincash_wallet.dart | 50 +++++++++++++++++++
 lib/services/coins/coin_service.dart          |  5 +-
 .../coins/dogecoin/dogecoin_wallet.dart       | 50 +++++++++++++++++++
 .../coins/epiccash/epiccash_wallet.dart       |  8 +++
 lib/services/coins/firo/firo_wallet.dart      | 50 +++++++++++++++++++
 .../coins/litecoin/litecoin_wallet.dart       | 50 +++++++++++++++++++
 lib/services/coins/manager.dart               |  3 ++
 lib/services/coins/monero/monero_wallet.dart  |  8 +++
 .../coins/namecoin/namecoin_wallet.dart       | 50 +++++++++++++++++++
 .../coins/wownero/wownero_wallet.dart         |  8 +++
 .../services/coins/fake_coin_service_api.dart |  6 +++
 13 files changed, 339 insertions(+), 3 deletions(-)

diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index 81d5a3da2..26d1231f0 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -87,13 +87,13 @@ class _ConfirmTransactionViewState
         txid = await manager.confirmSend(txData: transactionInfo);
       }
 
-      unawaited(manager.refresh());
-
       // save note
       await ref
           .read(notesServiceChangeNotifierProvider(walletId))
           .editOrAddNote(txid: txid, note: note);
 
+      unawaited(manager.refresh());
+
       // pop back to wallet
       if (mounted) {
         Navigator.of(context).popUntil(ModalRoute.withName(routeOnSuccessName));
diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart
index 391beb909..d0920075d 100644
--- a/lib/services/coins/bitcoin/bitcoin_wallet.dart
+++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart
@@ -10,6 +10,7 @@ import 'package:bitcoindart/bitcoindart.dart';
 import 'package:bs58check/bs58check.dart' as bs58check;
 import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
+import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
@@ -1283,6 +1284,54 @@ class BitcoinWallet extends CoinServiceAPI {
       _transactionData ??= _fetchTransactionData();
   Future<TransactionData>? _transactionData;
 
+  TransactionData? cachedTxData;
+
+  // hack to add tx to txData before refresh completes
+  // required based on current app architecture where we don't properly store
+  // 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 = await Devicelocale.currentLocale;
+    final String worthNow = Format.localizedStringAsFixed(
+        value:
+            ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
+                    Decimal.fromInt(Constants.satsPerCoin))
+                .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!);
+  }
+
   @override
   bool validateAddress(String address) {
     return Address.validateAddress(address, _network);
@@ -2661,6 +2710,7 @@ class BitcoinWallet extends CoinServiceAPI {
     await DB.instance.put<dynamic>(
         boxName: walletId, key: 'latest_tx_model', value: txModel);
 
+    cachedTxData = txModel;
     return txModel;
   }
 
diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index fa88b3f2f..98a31ee0c 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -11,6 +11,7 @@ import 'package:bitcoindart/bitcoindart.dart';
 import 'package:bs58check/bs58check.dart' as bs58check;
 import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
+import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
@@ -1154,6 +1155,54 @@ class BitcoinCashWallet extends CoinServiceAPI {
       _transactionData ??= _fetchTransactionData();
   Future<TransactionData>? _transactionData;
 
+  TransactionData? cachedTxData;
+
+  // hack to add tx to txData before refresh completes
+  // required based on current app architecture where we don't properly store
+  // 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 = await Devicelocale.currentLocale;
+    final String worthNow = Format.localizedStringAsFixed(
+        value:
+            ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
+                    Decimal.fromInt(Constants.satsPerCoin))
+                .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!);
+  }
+
   @override
   bool validateAddress(String address) {
     try {
@@ -2449,6 +2498,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
     await DB.instance.put<dynamic>(
         boxName: walletId, key: 'latest_tx_model', value: txModel);
 
+    cachedTxData = txModel;
     return txModel;
   }
 
diff --git a/lib/services/coins/coin_service.dart b/lib/services/coins/coin_service.dart
index c36fa9eee..655865494 100644
--- a/lib/services/coins/coin_service.dart
+++ b/lib/services/coins/coin_service.dart
@@ -9,8 +9,8 @@ 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/coins/monero/monero_wallet.dart';
-import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
 import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
+import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
 import 'package:stackwallet/services/transaction_notification_tracker.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/prefs.dart';
@@ -277,4 +277,7 @@ abstract class CoinServiceAPI {
   Future<int> estimateFeeFor(int satoshiAmount, int feeRate);
 
   Future<bool> generateNewAddress();
+
+  // used for electrumx coins
+  Future<void> updateSentCachedTxData(Map<String, dynamic> txData);
 }
diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart
index fbb551dcd..67be291a2 100644
--- a/lib/services/coins/dogecoin/dogecoin_wallet.dart
+++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart
@@ -10,6 +10,7 @@ import 'package:bitcoindart/bitcoindart.dart';
 import 'package:bs58check/bs58check.dart' as bs58check;
 import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
+import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
@@ -1051,6 +1052,54 @@ class DogecoinWallet extends CoinServiceAPI {
       _transactionData ??= _fetchTransactionData();
   Future<TransactionData>? _transactionData;
 
+  TransactionData? cachedTxData;
+
+  // hack to add tx to txData before refresh completes
+  // required based on current app architecture where we don't properly store
+  // 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 = await Devicelocale.currentLocale;
+    final String worthNow = Format.localizedStringAsFixed(
+        value:
+            ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
+                    Decimal.fromInt(Constants.satsPerCoin))
+                .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!);
+  }
+
   @override
   bool validateAddress(String address) {
     return Address.validateAddress(address, _network);
@@ -2273,6 +2322,7 @@ class DogecoinWallet extends CoinServiceAPI {
     await DB.instance.put<dynamic>(
         boxName: walletId, key: 'latest_tx_model', value: txModel);
 
+    cachedTxData = txModel;
     return txModel;
   }
 
diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart
index b98854e61..3702a9158 100644
--- a/lib/services/coins/epiccash/epiccash_wallet.dart
+++ b/lib/services/coins/epiccash/epiccash_wallet.dart
@@ -2259,6 +2259,14 @@ class EpicCashWallet extends CoinServiceAPI {
       _transactionData ??= _fetchTransactionData();
   Future<TransactionData>? _transactionData;
 
+  // not used in epic
+  TransactionData? cachedTxData;
+
+  @override
+  Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async {
+    // not used in epic
+  }
+
   @override
   Future<List<UtxoObject>> get unspentOutputs => throw UnimplementedError();
 
diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart
index 2a2102e7c..d19c4f1ab 100644
--- a/lib/services/coins/firo/firo_wallet.dart
+++ b/lib/services/coins/firo/firo_wallet.dart
@@ -908,6 +908,52 @@ class FiroWallet extends CoinServiceAPI {
   Future<models.TransactionData> get _txnData =>
       _transactionData ??= _fetchTransactionData();
 
+  models.TransactionData? cachedTxData;
+
+  // hack to add tx to txData before refresh completes
+  // required based on current app architecture where we don't properly store
+  // transactions locally in a good way
+  @override
+  Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async {
+    final currentPrice = await firoPrice;
+    final locale = await Devicelocale.currentLocale;
+    final String worthNow = Format.localizedStringAsFixed(
+        value:
+            ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
+                    Decimal.fromInt(Constants.satsPerCoin))
+                .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!);
+  }
+
   /// Holds wallet lelantus transaction data
   Future<models.TransactionData>? _lelantusTransactionData;
   Future<models.TransactionData> get lelantusTransactionData =>
@@ -1110,6 +1156,9 @@ class FiroWallet extends CoinServiceAPI {
       final txHash = await _electrumXClient.broadcastTransaction(
           rawTx: txData["hex"] as String);
       Logging.instance.log("Sent txHash: $txHash", level: LogLevel.Info);
+      txData["txid"] = txHash;
+      // dirty ui update hack
+      await updateSentCachedTxData(txData as Map<String, dynamic>);
       return txHash;
     } catch (e, s) {
       Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s",
@@ -3465,6 +3514,7 @@ class FiroWallet extends CoinServiceAPI {
     await DB.instance.put<dynamic>(
         boxName: walletId, key: 'latest_tx_model', value: txModel);
 
+    cachedTxData = txModel;
     return txModel;
   }
 
diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart
index c07cca1f3..4551325f7 100644
--- a/lib/services/coins/litecoin/litecoin_wallet.dart
+++ b/lib/services/coins/litecoin/litecoin_wallet.dart
@@ -10,6 +10,7 @@ import 'package:bitcoindart/bitcoindart.dart';
 import 'package:bs58check/bs58check.dart' as bs58check;
 import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
+import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
@@ -1285,6 +1286,54 @@ class LitecoinWallet extends CoinServiceAPI {
       _transactionData ??= _fetchTransactionData();
   Future<TransactionData>? _transactionData;
 
+  TransactionData? cachedTxData;
+
+  // hack to add tx to txData before refresh completes
+  // required based on current app architecture where we don't properly store
+  // 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 = await Devicelocale.currentLocale;
+    final String worthNow = Format.localizedStringAsFixed(
+        value:
+            ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
+                    Decimal.fromInt(Constants.satsPerCoin))
+                .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!);
+  }
+
   @override
   bool validateAddress(String address) {
     return Address.validateAddress(address, _network, _network.bech32!);
@@ -2673,6 +2722,7 @@ class LitecoinWallet extends CoinServiceAPI {
     await DB.instance.put<dynamic>(
         boxName: walletId, key: 'latest_tx_model', value: txModel);
 
+    cachedTxData = txModel;
     return txModel;
   }
 
diff --git a/lib/services/coins/manager.dart b/lib/services/coins/manager.dart
index c8329ec28..8054fe168 100644
--- a/lib/services/coins/manager.dart
+++ b/lib/services/coins/manager.dart
@@ -108,6 +108,9 @@ class Manager with ChangeNotifier {
     try {
       final txid = await _currentWallet.confirmSend(txData: txData);
 
+      txData["txid"] = txid;
+      await _currentWallet.updateSentCachedTxData(txData);
+
       notifyListeners();
       return txid;
     } catch (e) {
diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index 9bcc3515f..662d4077b 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -1190,6 +1190,14 @@ class MoneroWallet extends CoinServiceAPI {
       _transactionData ??= _fetchTransactionData();
   Future<TransactionData>? _transactionData;
 
+  // not used in monero
+  TransactionData? cachedTxData;
+
+  @override
+  Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async {
+    // not used in monero
+  }
+
   Future<TransactionData> _fetchTransactionData() async {
     final transactions = walletBase?.transactionHistory!.transactions;
 
diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart
index 893db69e0..8a4b26012 100644
--- a/lib/services/coins/namecoin/namecoin_wallet.dart
+++ b/lib/services/coins/namecoin/namecoin_wallet.dart
@@ -10,6 +10,7 @@ import 'package:bitcoindart/bitcoindart.dart';
 import 'package:bs58check/bs58check.dart' as bs58check;
 import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
+import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
@@ -1276,6 +1277,54 @@ class NamecoinWallet extends CoinServiceAPI {
       _transactionData ??= _fetchTransactionData();
   Future<TransactionData>? _transactionData;
 
+  TransactionData? cachedTxData;
+
+  // hack to add tx to txData before refresh completes
+  // required based on current app architecture where we don't properly store
+  // 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 = await Devicelocale.currentLocale;
+    final String worthNow = Format.localizedStringAsFixed(
+        value:
+            ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
+                    Decimal.fromInt(Constants.satsPerCoin))
+                .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!);
+  }
+
   @override
   bool validateAddress(String address) {
     return Address.validateAddress(address, _network, namecoin.bech32!);
@@ -2673,6 +2722,7 @@ class NamecoinWallet extends CoinServiceAPI {
     await DB.instance.put<dynamic>(
         boxName: walletId, key: 'latest_tx_model', value: txModel);
 
+    cachedTxData = txModel;
     return txModel;
   }
 
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 342e5d84a..72f43eac8 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -1195,6 +1195,14 @@ class WowneroWallet extends CoinServiceAPI {
       _transactionData ??= _fetchTransactionData();
   Future<TransactionData>? _transactionData;
 
+  // not used in wownero
+  TransactionData? cachedTxData;
+
+  @override
+  Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async {
+    // not used in wownero
+  }
+
   Future<TransactionData> _fetchTransactionData() async {
     final transactions = walletBase?.transactionHistory!.transactions;
 
diff --git a/test/services/coins/fake_coin_service_api.dart b/test/services/coins/fake_coin_service_api.dart
index a3ae28a4b..c5f300c16 100644
--- a/test/services/coins/fake_coin_service_api.dart
+++ b/test/services/coins/fake_coin_service_api.dart
@@ -182,4 +182,10 @@ class FakeCoinServiceAPI extends CoinServiceAPI {
     // TODO: implement generateNewAddress
     throw UnimplementedError();
   }
+
+  @override
+  Future<void> updateSentCachedTxData(Map<String, dynamic> txData) {
+    // TODO: implement updateSentCachedTxData
+    throw UnimplementedError();
+  }
 }

From 6223df54320afea50d258580d4780b820491d35d Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Mon, 7 Nov 2022 11:21:10 -0600
Subject: [PATCH 148/426] specify tests for 14 word seeds and add more error
 checking code to test

and update ref to flutter_libmonero enabling tests (mocked storage, etc)
---
 crypto_plugins/flutter_libmonero              |  2 +-
 .../coins/wownero/wownero_wallet_test.dart    | 45 +++++++++++--------
 .../wownero/wownero_wallet_test_data.dart     |  4 +-
 3 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index 277d922c3..d92fea3e6 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit 277d922c3b1d637c1ccda25f51395c618d293015
+Subproject commit d92fea3e6b915b79697deafbd5710fb4c15bfc76
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index e64dd772c..83b4844c7 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -83,13 +83,13 @@ void main() async {
   _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
   walletService = wownero.createWowneroWalletService(_walletInfoSource);
 
-  group("Wownero tests", () {
+  group("Wownero 14 word tests", () {
     setUp(() async {
       try {
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
         credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
-            name: name, height: 465760, mnemonic: testMnemonic);
+            name: name, height: 465760, mnemonic: testMnemonic14);
 
         walletInfo = WalletInfo.external(
             id: WalletBase.idFor(name, type),
@@ -116,27 +116,36 @@ void main() async {
       }
     });
 
-    test("Test mainnet address generation from seed", () async {
+    test("Test mainnet address generation from 14 word seed", () async {
       final wallet = await _walletCreationService.restoreFromSeed(credentials);
       walletInfo.address = wallet.walletAddresses.address;
 
-      await _walletInfoSource.add(walletInfo);
+      bool hasThrown = false;
+      try {
+        await _walletInfoSource.add(walletInfo);
+        walletBase?.close();
+          walletBase = wallet as WowneroWalletBase;
+
+        expect(walletInfo.address, mainnetTestData14[0][0]);
+        expect(
+            await walletBase!.getTransactionAddress(0, 0), mainnetTestData14[0][0]);
+        expect(
+            await walletBase!.getTransactionAddress(0, 1), mainnetTestData14[0][1]);
+        expect(
+            await walletBase!.getTransactionAddress(0, 2), mainnetTestData14[0][2]);
+        expect(
+            await walletBase!.getTransactionAddress(1, 0), mainnetTestData14[1][0]);
+        expect(
+            await walletBase!.getTransactionAddress(1, 1), mainnetTestData14[1][1]);
+        expect(
+            await walletBase!.getTransactionAddress(1, 2), mainnetTestData14[1][2]);
+      } catch (_) {
+        hasThrown = true;
+      }
+      expect(hasThrown, false);
+
       walletBase?.close();
       walletBase = wallet as WowneroWalletBase;
-
-      expect(walletInfo.address, mainnetTestData[0][0]);
-      expect(
-          await walletBase!.getTransactionAddress(0, 0), mainnetTestData[0][0]);
-      expect(
-          await walletBase!.getTransactionAddress(0, 1), mainnetTestData[0][1]);
-      expect(
-          await walletBase!.getTransactionAddress(0, 2), mainnetTestData[0][2]);
-      expect(
-          await walletBase!.getTransactionAddress(1, 0), mainnetTestData[1][0]);
-      expect(
-          await walletBase!.getTransactionAddress(1, 1), mainnetTestData[1][1]);
-      expect(
-          await walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]);
     });
   });
 }
diff --git a/test/services/coins/wownero/wownero_wallet_test_data.dart b/test/services/coins/wownero/wownero_wallet_test_data.dart
index b0d93a448..8ab825dfa 100644
--- a/test/services/coins/wownero/wownero_wallet_test_data.dart
+++ b/test/services/coins/wownero/wownero_wallet_test_data.dart
@@ -1,6 +1,6 @@
-String testMnemonic =
+String testMnemonic14 =
     'weather cruise school such silly profit clerk wage reduce obtain ill sand episode shadow';
-var mainnetTestData = [
+var mainnetTestData14 = [
   [
     'Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi',
     'WW3K54QzmMFB1uTZh3LVvgQYqANLmX1FkJHLJ4sU1E7BQmp8nGizyBnjNXSgsjCa4BQ3Rw3GG5jw1ByUkaUjSywm2KmHAbFvK',

From c88971ebd6eaf7e278591eef2925c1fe6b8a2081 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 7 Nov 2022 11:46:17 -0600
Subject: [PATCH 149/426] firo pub/priv balance send from choice on exchange
 flow

---
 .../confirm_change_now_send.dart              |  13 +-
 lib/pages/exchange_view/send_from_view.dart   | 559 ++++++++++++------
 2 files changed, 404 insertions(+), 168 deletions(-)

diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index d77ad6b8c..e99cf2df4 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -10,6 +10,7 @@ import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
 import 'package:stackwallet/providers/exchange/trade_sent_from_stack_lookup_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/route_generator.dart';
+import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -27,6 +28,7 @@ class ConfirmChangeNowSendView extends ConsumerStatefulWidget {
     required this.walletId,
     this.routeOnSuccessName = WalletView.routeName,
     required this.trade,
+    this.shouldSendPublicFiroFunds,
   }) : super(key: key);
 
   static const String routeName = "/confirmChangeNowSend";
@@ -35,6 +37,7 @@ class ConfirmChangeNowSendView extends ConsumerStatefulWidget {
   final String walletId;
   final String routeOnSuccessName;
   final Trade trade;
+  final bool? shouldSendPublicFiroFunds;
 
   @override
   ConsumerState<ConfirmChangeNowSendView> createState() =>
@@ -63,7 +66,15 @@ class _ConfirmChangeNowSendViewState
         ref.read(walletsChangeNotifierProvider).getManager(walletId);
 
     try {
-      final txid = await manager.confirmSend(txData: transactionInfo);
+      late final String txid;
+
+      if (widget.shouldSendPublicFiroFunds == true) {
+        txid = await (manager.wallet as FiroWallet)
+            .confirmSendPublic(txData: transactionInfo);
+      } else {
+        txid = await manager.confirmSend(txData: transactionInfo);
+      }
+
       unawaited(manager.refresh());
 
       // save note
diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart
index 20fc81903..c87175955 100644
--- a/lib/pages/exchange_view/send_from_view.dart
+++ b/lib/pages/exchange_view/send_from_view.dart
@@ -10,6 +10,8 @@ import 'package:stackwallet/pages/home_view/home_view.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart';
 import 'package:stackwallet/providers/providers.dart';
 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/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
@@ -18,7 +20,9 @@ import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/animated_text.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/expandable.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
@@ -162,6 +166,130 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
   late final String address;
   late final Trade trade;
 
+  Future<void> _send(Manager manager, {bool? shouldSendPublicFiroFunds}) async {
+    final _amount = Format.decimalAmountToSatoshis(amount);
+
+    try {
+      bool wasCancelled = false;
+
+      unawaited(
+        showDialog<dynamic>(
+          context: context,
+          useSafeArea: false,
+          barrierDismissible: false,
+          builder: (context) {
+            return BuildingTransactionDialog(
+              onCancel: () {
+                wasCancelled = true;
+
+                Navigator.of(context).pop();
+              },
+            );
+          },
+        ),
+      );
+
+      late Map<String, dynamic> txData;
+
+      // if not firo then do normal send
+      if (shouldSendPublicFiroFunds == null) {
+        txData = await manager.prepareSend(
+          address: address,
+          satoshiAmount: _amount,
+          args: {
+            "feeRate": FeeRateType.average,
+            // ref.read(feeRateTypeStateProvider)
+          },
+        );
+      } else {
+        final firoWallet = manager.wallet as FiroWallet;
+        // otherwise do firo send based on balance selected
+        if (shouldSendPublicFiroFunds) {
+          txData = await firoWallet.prepareSendPublic(
+            address: address,
+            satoshiAmount: _amount,
+            args: {
+              "feeRate": FeeRateType.average,
+              // ref.read(feeRateTypeStateProvider)
+            },
+          );
+        } else {
+          txData = await firoWallet.prepareSend(
+            address: address,
+            satoshiAmount: _amount,
+            args: {
+              "feeRate": FeeRateType.average,
+              // ref.read(feeRateTypeStateProvider)
+            },
+          );
+        }
+      }
+
+      if (!wasCancelled) {
+        // pop building dialog
+
+        if (mounted) {
+          Navigator.of(context).pop();
+        }
+
+        txData["note"] =
+            "${trade.payInCurrency.toUpperCase()}/${trade.payOutCurrency.toUpperCase()} exchange";
+        txData["address"] = address;
+
+        if (mounted) {
+          await Navigator.of(context).push(
+            RouteGenerator.getRoute(
+              shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
+              builder: (_) => ConfirmChangeNowSendView(
+                transactionInfo: txData,
+                walletId: walletId,
+                routeOnSuccessName: HomeView.routeName,
+                trade: trade,
+                shouldSendPublicFiroFunds: shouldSendPublicFiroFunds,
+              ),
+              settings: const RouteSettings(
+                name: ConfirmChangeNowSendView.routeName,
+              ),
+            ),
+          );
+        }
+      }
+    } catch (e) {
+      // if (mounted) {
+      // pop building dialog
+      Navigator.of(context).pop();
+
+      await 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>()!
+                  .getSecondaryEnabledButtonColor(context),
+              child: Text(
+                "Ok",
+                style: STextStyles.button(context).copyWith(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .buttonTextSecondary,
+                ),
+              ),
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
+            ),
+          );
+        },
+      );
+      // }
+    }
+  }
+
   @override
   void initState() {
     walletId = widget.walletId;
@@ -182,181 +310,278 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
 
     final coin = manager.coin;
 
+    final isFiro = coin == Coin.firoTestNet || coin == Coin.firo;
+
     return RoundedWhiteContainer(
       padding: const EdgeInsets.all(0),
-      child: MaterialButton(
-        splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-        key: Key("walletsSheetItemButtonKey_$walletId"),
-        padding: const EdgeInsets.all(8),
-        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-        shape: RoundedRectangleBorder(
-          borderRadius: BorderRadius.circular(
-            Constants.size.circularBorderRadius,
+      child: ConditionalParent(
+        condition: isFiro,
+        builder: (child) => Expandable(
+          header: Container(
+            color: Colors.transparent,
+            child: Padding(
+              padding: const EdgeInsets.all(12),
+              child: child,
+            ),
+          ),
+          body: Column(
+            mainAxisSize: MainAxisSize.min,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              MaterialButton(
+                splashColor:
+                    Theme.of(context).extension<StackColors>()!.highlight,
+                key: Key("walletsSheetItemButtonFiroPrivateKey_$walletId"),
+                padding: const EdgeInsets.all(0),
+                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                shape: RoundedRectangleBorder(
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
+                ),
+                onPressed: () => _send(
+                  manager,
+                  shouldSendPublicFiroFunds: false,
+                ),
+                child: Container(
+                  color: Colors.transparent,
+                  child: Padding(
+                    padding: const EdgeInsets.only(
+                      top: 6,
+                      left: 16,
+                      right: 16,
+                      bottom: 6,
+                    ),
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Column(
+                          mainAxisSize: MainAxisSize.min,
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            Text(
+                              "Use private balance",
+                              style: STextStyles.itemSubtitle(context),
+                            ),
+                            FutureBuilder(
+                              future: (manager.wallet as FiroWallet)
+                                  .availablePrivateBalance(),
+                              builder: (builderContext,
+                                  AsyncSnapshot<Decimal> snapshot) {
+                                if (snapshot.connectionState ==
+                                        ConnectionState.done &&
+                                    snapshot.hasData) {
+                                  return Text(
+                                    "${Format.localizedStringAsFixed(
+                                      value: snapshot.data!,
+                                      locale: locale,
+                                      decimalPlaces: Constants.decimalPlaces,
+                                    )} ${coin.ticker}",
+                                    style: STextStyles.itemSubtitle(context),
+                                  );
+                                } else {
+                                  return AnimatedText(
+                                    stringsToLoopThrough: const [
+                                      "Loading balance",
+                                      "Loading balance.",
+                                      "Loading balance..",
+                                      "Loading balance..."
+                                    ],
+                                    style: STextStyles.itemSubtitle(context),
+                                  );
+                                }
+                              },
+                            ),
+                          ],
+                        ),
+                        SvgPicture.asset(
+                          Assets.svg.chevronRight,
+                          height: 14,
+                          width: 7,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .infoItemLabel,
+                        ),
+                      ],
+                    ),
+                  ),
+                ),
+              ),
+              MaterialButton(
+                splashColor:
+                    Theme.of(context).extension<StackColors>()!.highlight,
+                key: Key("walletsSheetItemButtonFiroPublicKey_$walletId"),
+                padding: const EdgeInsets.all(0),
+                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                shape: RoundedRectangleBorder(
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
+                ),
+                onPressed: () => _send(
+                  manager,
+                  shouldSendPublicFiroFunds: true,
+                ),
+                child: Container(
+                  color: Colors.transparent,
+                  child: Padding(
+                    padding: const EdgeInsets.only(
+                      top: 6,
+                      left: 16,
+                      right: 16,
+                      bottom: 6,
+                    ),
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Column(
+                          mainAxisSize: MainAxisSize.min,
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            Text(
+                              "Use public balance",
+                              style: STextStyles.itemSubtitle(context),
+                            ),
+                            FutureBuilder(
+                              future: (manager.wallet as FiroWallet)
+                                  .availablePublicBalance(),
+                              builder: (builderContext,
+                                  AsyncSnapshot<Decimal> snapshot) {
+                                if (snapshot.connectionState ==
+                                        ConnectionState.done &&
+                                    snapshot.hasData) {
+                                  return Text(
+                                    "${Format.localizedStringAsFixed(
+                                      value: snapshot.data!,
+                                      locale: locale,
+                                      decimalPlaces: Constants.decimalPlaces,
+                                    )} ${coin.ticker}",
+                                    style: STextStyles.itemSubtitle(context),
+                                  );
+                                } else {
+                                  return AnimatedText(
+                                    stringsToLoopThrough: const [
+                                      "Loading balance",
+                                      "Loading balance.",
+                                      "Loading balance..",
+                                      "Loading balance..."
+                                    ],
+                                    style: STextStyles.itemSubtitle(context),
+                                  );
+                                }
+                              },
+                            ),
+                          ],
+                        ),
+                        SvgPicture.asset(
+                          Assets.svg.chevronRight,
+                          height: 14,
+                          width: 7,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .infoItemLabel,
+                        ),
+                      ],
+                    ),
+                  ),
+                ),
+              ),
+              const SizedBox(
+                height: 6,
+              ),
+            ],
           ),
         ),
-        onPressed: () async {
-          final _amount = Format.decimalAmountToSatoshis(amount);
-
-          try {
-            bool wasCancelled = false;
-
-            unawaited(showDialog<dynamic>(
-              context: context,
-              useSafeArea: false,
-              barrierDismissible: false,
-              builder: (context) {
-                return BuildingTransactionDialog(
-                  onCancel: () {
-                    wasCancelled = true;
-
-                    Navigator.of(context).pop();
-                  },
-                );
-              },
-            ));
-
-            final txData = await manager.prepareSend(
-              address: address,
-              satoshiAmount: _amount,
-              args: {
-                "feeRate": FeeRateType.average,
-                // ref.read(feeRateTypeStateProvider)
-              },
-            );
-
-            if (!wasCancelled) {
-              // pop building dialog
-
-              if (mounted) {
-                Navigator.of(context).pop();
-              }
-
-              txData["note"] =
-                  "${trade.payInCurrency.toUpperCase()}/${trade.payOutCurrency.toUpperCase()} exchange";
-              txData["address"] = address;
-
-              if (mounted) {
-                await Navigator.of(context).push(
-                  RouteGenerator.getRoute(
-                    shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
-                    builder: (_) => ConfirmChangeNowSendView(
-                      transactionInfo: txData,
-                      walletId: walletId,
-                      routeOnSuccessName: HomeView.routeName,
-                      trade: trade,
-                    ),
-                    settings: const RouteSettings(
-                      name: ConfirmChangeNowSendView.routeName,
-                    ),
+        child: ConditionalParent(
+          condition: !isFiro,
+          builder: (child) => MaterialButton(
+            splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+            key: Key("walletsSheetItemButtonKey_$walletId"),
+            padding: const EdgeInsets.all(8),
+            materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+            shape: RoundedRectangleBorder(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+            ),
+            onPressed: () => _send(manager),
+            child: child,
+          ),
+          child: Row(
+            children: [
+              Container(
+                decoration: BoxDecoration(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .colorForCoin(manager.coin)
+                      .withOpacity(0.5),
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
                   ),
-                );
-              }
-            }
-          } catch (e) {
-            // if (mounted) {
-            // pop building dialog
-            Navigator.of(context).pop();
-
-            await 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>()!
-                        .getSecondaryEnabledButtonColor(context),
-                    child: Text(
-                      "Ok",
-                      style: STextStyles.button(context).copyWith(
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .buttonTextSecondary,
+                ),
+                child: Padding(
+                  padding: const EdgeInsets.all(6),
+                  child: SvgPicture.asset(
+                    Assets.svg.iconFor(coin: coin),
+                    width: 24,
+                    height: 24,
+                  ),
+                ),
+              ),
+              const SizedBox(
+                width: 12,
+              ),
+              Expanded(
+                child: Column(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Text(
+                      manager.walletName,
+                      style: STextStyles.titleBold12(context),
+                    ),
+                    if (!isFiro)
+                      const SizedBox(
+                        height: 2,
                       ),
-                    ),
-                    onPressed: () {
-                      Navigator.of(context).pop();
-                    },
-                  ),
-                );
-              },
-            );
-            // }
-          }
-        },
-        child: Row(
-          children: [
-            Container(
-              decoration: BoxDecoration(
-                color: Theme.of(context)
-                    .extension<StackColors>()!
-                    .colorForCoin(manager.coin)
-                    .withOpacity(0.5),
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius,
+                    if (!isFiro)
+                      FutureBuilder(
+                        future: manager.totalBalance,
+                        builder:
+                            (builderContext, AsyncSnapshot<Decimal> snapshot) {
+                          if (snapshot.connectionState ==
+                                  ConnectionState.done &&
+                              snapshot.hasData) {
+                            return Text(
+                              "${Format.localizedStringAsFixed(
+                                value: snapshot.data!,
+                                locale: locale,
+                                decimalPlaces: coin == Coin.monero
+                                    ? Constants.decimalPlacesMonero
+                                    : coin == Coin.wownero
+                                        ? Constants.decimalPlacesWownero
+                                        : Constants.decimalPlaces,
+                              )} ${coin.ticker}",
+                              style: STextStyles.itemSubtitle(context),
+                            );
+                          } else {
+                            return AnimatedText(
+                              stringsToLoopThrough: const [
+                                "Loading balance",
+                                "Loading balance.",
+                                "Loading balance..",
+                                "Loading balance..."
+                              ],
+                              style: STextStyles.itemSubtitle(context),
+                            );
+                          }
+                        },
+                      ),
+                  ],
                 ),
               ),
-              child: Padding(
-                padding: const EdgeInsets.all(6),
-                child: SvgPicture.asset(
-                  Assets.svg.iconFor(coin: coin),
-                  width: 24,
-                  height: 24,
-                ),
-              ),
-            ),
-            const SizedBox(
-              width: 12,
-            ),
-            Expanded(
-              child: Column(
-                mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  Text(
-                    manager.walletName,
-                    style: STextStyles.titleBold12(context),
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  FutureBuilder(
-                    future: manager.totalBalance,
-                    builder: (builderContext, AsyncSnapshot<Decimal> snapshot) {
-                      if (snapshot.connectionState == ConnectionState.done &&
-                          snapshot.hasData) {
-                        return Text(
-                          "${Format.localizedStringAsFixed(
-                            value: snapshot.data!,
-                            locale: locale,
-                            decimalPlaces: coin == Coin.monero
-                                ? Constants.decimalPlacesMonero
-                                : coin == Coin.wownero
-                                    ? Constants.decimalPlacesWownero
-                                    : Constants.decimalPlaces,
-                          )} ${coin.ticker}",
-                          style: STextStyles.itemSubtitle(context),
-                        );
-                      } else {
-                        return AnimatedText(
-                          stringsToLoopThrough: const [
-                            "Loading balance",
-                            "Loading balance.",
-                            "Loading balance..",
-                            "Loading balance..."
-                          ],
-                          style: STextStyles.itemSubtitle(context),
-                        );
-                      }
-                    },
-                  ),
-                ],
-              ),
-            ),
-          ],
+            ],
+          ),
         ),
       ),
     );

From 9fe9ee3a1236011d2e6c96147af82b1aa8874390 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 7 Nov 2022 10:42:55 -0700
Subject: [PATCH 150/426] desktop about view route added

---
 lib/pages_desktop_specific/home/desktop_home_view.dart     | 7 +++++--
 .../home/support_and_about_view/desktop_about_view.dart    | 0
 lib/route_generator.dart                                   | 7 +++++++
 3 files changed, 12 insertions(+), 2 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart

diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index e9f6f2b4b..14d2dae03 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_menu.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -43,8 +44,10 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: DesktopSupportView.routeName,
     ),
-    Container(
-      color: Colors.pink,
+    const Navigator(
+      key: Key("desktopAboutHomeKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: DesktopAboutView.routeName,
     ),
   ];
 
diff --git a/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart b/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart
new file mode 100644
index 000000000..e69de29bb
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 47a84f07c..40f11dc57 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -99,6 +99,7 @@ import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_sett
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
@@ -1091,6 +1092,12 @@ class RouteGenerator {
             builder: (_) => const DesktopSupportView(),
             settings: RouteSettings(name: settings.name));
 
+      case DesktopAboutView.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const DesktopAboutView(),
+            settings: RouteSettings(name: settings.name));
+
       case WalletKeysDesktopPopup.routeName:
         if (args is List<String>) {
           return FadePageRoute(

From 48a0e3a5ca89528a1bdca69e8c027967c7957e1d Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 7 Nov 2022 12:31:49 -0700
Subject: [PATCH 151/426] desktop about view added

---
 .../desktop_about_view.dart                   | 655 ++++++++++++++++++
 1 file changed, 655 insertions(+)

diff --git a/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart b/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart
index e69de29bb..86fcf78e0 100644
--- a/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart
+++ b/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart
@@ -0,0 +1,655 @@
+import 'dart:convert';
+
+import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_libepiccash/git_versions.dart' as EPIC_VERSIONS;
+import 'package:flutter_libmonero/git_versions.dart' as MONERO_VERSIONS;
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:http/http.dart';
+import 'package:lelantus/git_versions.dart' as FIRO_VERSIONS;
+import 'package:package_info_plus/package_info_plus.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/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+const kGithubAPI = "https://api.github.com";
+const kGithubSearch = "/search/commits";
+const kGithubHead = "/repos";
+
+enum CommitStatus { isHead, isOldCommit, notACommit, notLoaded }
+
+Future<bool> doesCommitExist(
+  String organization,
+  String project,
+  String commit,
+) async {
+  Logging.instance.log("doesCommitExist", level: LogLevel.Info);
+  final Client client = Client();
+  try {
+    final uri = Uri.parse(
+        "$kGithubAPI$kGithubHead/$organization/$project/commits/$commit");
+
+    final commitQuery = await client.get(
+      uri,
+      headers: {'Content-Type': 'application/json'},
+    );
+
+    final response = jsonDecode(commitQuery.body.toString());
+    Logging.instance.log("doesCommitExist $project $commit $response",
+        level: LogLevel.Info);
+    bool isThereCommit;
+    try {
+      isThereCommit = response['sha'] == commit;
+      Logging.instance
+          .log("isThereCommit $isThereCommit", level: LogLevel.Info);
+      return isThereCommit;
+    } catch (e, s) {
+      return false;
+    }
+  } catch (e, s) {
+    Logging.instance.log("$e $s", level: LogLevel.Error);
+    return false;
+  }
+}
+
+Future<bool> isHeadCommit(
+  String organization,
+  String project,
+  String branch,
+  String commit,
+) async {
+  Logging.instance.log("doesCommitExist", level: LogLevel.Info);
+  final Client client = Client();
+  try {
+    final uri = Uri.parse(
+        "$kGithubAPI$kGithubHead/$organization/$project/commits/$branch");
+
+    final commitQuery = await client.get(
+      uri,
+      headers: {'Content-Type': 'application/json'},
+    );
+
+    final response = jsonDecode(commitQuery.body.toString());
+    Logging.instance.log("isHeadCommit $project $commit $branch $response",
+        level: LogLevel.Info);
+    bool isHead;
+    try {
+      isHead = response['sha'] == commit;
+      Logging.instance.log("isHead $isHead", level: LogLevel.Info);
+      return isHead;
+    } catch (e, s) {
+      return false;
+    }
+  } catch (e, s) {
+    Logging.instance.log("$e $s", level: LogLevel.Error);
+    return false;
+  }
+}
+
+class DesktopAboutView extends ConsumerWidget {
+  const DesktopAboutView({Key? key}) : super(key: key);
+
+  static const String routeName = "/desktopAboutView";
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    String firoCommit = FIRO_VERSIONS.getPluginVersion();
+    String epicCashCommit = EPIC_VERSIONS.getPluginVersion();
+    String moneroCommit = MONERO_VERSIONS.getPluginVersion();
+    List<Future> futureFiroList = [
+      doesCommitExist("cypherstack", "flutter_liblelantus", firoCommit),
+      isHeadCommit("cypherstack", "flutter_liblelantus", "main", firoCommit),
+    ];
+    Future commitFiroFuture = Future.wait(futureFiroList);
+    List<Future> futureEpicList = [
+      doesCommitExist("cypherstack", "flutter_libepiccash", epicCashCommit),
+      isHeadCommit(
+          "cypherstack", "flutter_libepiccash", "main", epicCashCommit),
+    ];
+    Future commitEpicFuture = Future.wait(futureEpicList);
+    List<Future> futureMoneroList = [
+      doesCommitExist("cypherstack", "flutter_libmonero", moneroCommit),
+      isHeadCommit("cypherstack", "flutter_libmonero", "main", moneroCommit),
+    ];
+    Future commitMoneroFuture = Future.wait(futureMoneroList);
+
+    debugPrint("BUILD: $runtimeType");
+    return DesktopScaffold(
+      background: Theme.of(context).extension<StackColors>()!.background,
+      appBar: DesktopAppBar(
+        isCompactHeight: true,
+        leading: Row(
+          children: [
+            const SizedBox(
+              width: 24,
+              height: 24,
+            ),
+            Text(
+              "About",
+              style: STextStyles.desktopH3(context),
+            )
+          ],
+        ),
+      ),
+      body: Column(
+        children: [
+          Padding(
+            padding: const EdgeInsets.fromLTRB(24, 10, 24, 35),
+            child: RoundedWhiteContainer(
+              width: 929,
+              height: 411,
+              child: Padding(
+                padding: const EdgeInsets.only(left: 10, top: 10),
+                child: Column(
+                  // mainAxisAlignment: MainAxisAlignment.start,
+                  children: [
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.start,
+                      children: [
+                        Text(
+                          "Stack Wallet",
+                          style: STextStyles.desktopH3(context),
+                          textAlign: TextAlign.start,
+                        ),
+                      ],
+                    ),
+                    const SizedBox(height: 16),
+                    Row(
+                      children: [
+                        RichText(
+                          textAlign: TextAlign.start,
+                          text: TextSpan(
+                            style: STextStyles.label(context),
+                            children: [
+                              TextSpan(
+                                text:
+                                    "By using Stack Wallet, you agree to the ",
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                        context)
+                                    .copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textDark3),
+                              ),
+                              TextSpan(
+                                text: "Terms of service",
+                                style: STextStyles.richLink(context)
+                                    .copyWith(fontSize: 14),
+                                recognizer: TapGestureRecognizer()
+                                  ..onTap = () {
+                                    launchUrl(
+                                      Uri.parse(
+                                          "https://stackwallet.com/terms-of-service.html"),
+                                      mode: LaunchMode.externalApplication,
+                                    );
+                                  },
+                              ),
+                              TextSpan(
+                                text: " and ",
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                        context)
+                                    .copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textDark3),
+                              ),
+                              TextSpan(
+                                text: "Privacy policy",
+                                style: STextStyles.richLink(context)
+                                    .copyWith(fontSize: 14),
+                                recognizer: TapGestureRecognizer()
+                                  ..onTap = () {
+                                    launchUrl(
+                                      Uri.parse(
+                                          "https://stackwallet.com/privacy-policy.html"),
+                                      mode: LaunchMode.externalApplication,
+                                    );
+                                  },
+                              ),
+                            ],
+                          ),
+                        ),
+                      ],
+                    ),
+                    const SizedBox(height: 32),
+                    Padding(
+                      padding: const EdgeInsets.only(right: 10, bottom: 10),
+                      child: Column(
+                        children: [
+                          FutureBuilder(
+                            future: PackageInfo.fromPlatform(),
+                            builder:
+                                (context, AsyncSnapshot<PackageInfo> snapshot) {
+                              String version = "";
+                              String signature = "";
+                              String build = "";
+
+                              if (snapshot.connectionState ==
+                                      ConnectionState.done &&
+                                  snapshot.hasData) {
+                                version = snapshot.data!.version;
+                                build = snapshot.data!.buildNumber;
+                                signature = snapshot.data!.buildSignature;
+                              }
+
+                              return Column(
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
+                                children: [
+                                  Row(
+                                    children: [
+                                      Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          Text(
+                                            "Version",
+                                            style: STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark),
+                                          ),
+                                          const SizedBox(
+                                            height: 2,
+                                          ),
+                                          SelectableText(
+                                            version,
+                                            style: STextStyles.itemSubtitle(
+                                                context),
+                                          ),
+                                        ],
+                                      ),
+                                      const SizedBox(
+                                        width: 400,
+                                      ),
+                                      Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          Text(
+                                            "Build number",
+                                            style: STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark),
+                                          ),
+                                          const SizedBox(
+                                            height: 2,
+                                          ),
+                                          SelectableText(
+                                            build,
+                                            style: STextStyles.itemSubtitle(
+                                                context),
+                                          ),
+                                        ],
+                                      ),
+                                    ],
+                                  ),
+                                  const SizedBox(height: 32),
+                                  Row(
+                                    children: [
+                                      Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          Text(
+                                            "Build signature",
+                                            style: STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark),
+                                          ),
+                                          const SizedBox(
+                                            height: 2,
+                                          ),
+                                          SelectableText(
+                                            signature,
+                                            style: STextStyles.itemSubtitle(
+                                                context),
+                                          ),
+                                        ],
+                                      ),
+                                      const SizedBox(
+                                        width: 350,
+                                      ),
+                                      FutureBuilder(
+                                          future: commitFiroFuture,
+                                          builder: (context,
+                                              AsyncSnapshot<dynamic> snapshot) {
+                                            bool commitExists = false;
+                                            bool isHead = false;
+                                            CommitStatus stateOfCommit =
+                                                CommitStatus.notLoaded;
+
+                                            if (snapshot.connectionState ==
+                                                    ConnectionState.done &&
+                                                snapshot.hasData) {
+                                              commitExists =
+                                                  snapshot.data![0] as bool;
+                                              isHead =
+                                                  snapshot.data![1] as bool;
+                                              if (commitExists && isHead) {
+                                                stateOfCommit =
+                                                    CommitStatus.isHead;
+                                              } else if (commitExists) {
+                                                stateOfCommit =
+                                                    CommitStatus.isOldCommit;
+                                              } else {
+                                                stateOfCommit =
+                                                    CommitStatus.notACommit;
+                                              }
+                                            }
+                                            TextStyle indicationStyle =
+                                                STextStyles.itemSubtitle(
+                                                    context);
+                                            switch (stateOfCommit) {
+                                              case CommitStatus.isHead:
+                                                indicationStyle = STextStyles
+                                                        .itemSubtitle(context)
+                                                    .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .accentColorGreen);
+                                                break;
+                                              case CommitStatus.isOldCommit:
+                                                indicationStyle = STextStyles
+                                                        .itemSubtitle(context)
+                                                    .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .accentColorYellow);
+                                                break;
+                                              case CommitStatus.notACommit:
+                                                indicationStyle = STextStyles
+                                                        .itemSubtitle(context)
+                                                    .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .accentColorRed);
+                                                break;
+                                              default:
+                                                break;
+                                            }
+                                            return Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.start,
+                                              children: [
+                                                Text(
+                                                  "Firo Build Commit",
+                                                  style: STextStyles
+                                                          .desktopTextExtraExtraSmall(
+                                                              context)
+                                                      .copyWith(
+                                                          color: Theme.of(
+                                                                  context)
+                                                              .extension<
+                                                                  StackColors>()!
+                                                              .textDark),
+                                                ),
+                                                const SizedBox(
+                                                  height: 2,
+                                                ),
+                                                SelectableText(
+                                                  firoCommit,
+                                                  style: indicationStyle,
+                                                ),
+                                              ],
+                                            );
+                                          }),
+                                    ],
+                                  ),
+                                  const SizedBox(height: 35),
+                                  Row(
+                                    children: [
+                                      FutureBuilder(
+                                          future: commitEpicFuture,
+                                          builder: (context,
+                                              AsyncSnapshot<dynamic> snapshot) {
+                                            bool commitExists = false;
+                                            bool isHead = false;
+                                            CommitStatus stateOfCommit =
+                                                CommitStatus.notLoaded;
+
+                                            if (snapshot.connectionState ==
+                                                    ConnectionState.done &&
+                                                snapshot.hasData) {
+                                              commitExists =
+                                                  snapshot.data![0] as bool;
+                                              isHead =
+                                                  snapshot.data![1] as bool;
+                                              if (commitExists && isHead) {
+                                                stateOfCommit =
+                                                    CommitStatus.isHead;
+                                              } else if (commitExists) {
+                                                stateOfCommit =
+                                                    CommitStatus.isOldCommit;
+                                              } else {
+                                                stateOfCommit =
+                                                    CommitStatus.notACommit;
+                                              }
+                                            }
+                                            TextStyle indicationStyle =
+                                                STextStyles.itemSubtitle(
+                                                    context);
+                                            switch (stateOfCommit) {
+                                              case CommitStatus.isHead:
+                                                indicationStyle = STextStyles
+                                                        .itemSubtitle(context)
+                                                    .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .accentColorGreen);
+                                                break;
+                                              case CommitStatus.isOldCommit:
+                                                indicationStyle = STextStyles
+                                                        .itemSubtitle(context)
+                                                    .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .accentColorYellow);
+                                                break;
+                                              case CommitStatus.notACommit:
+                                                indicationStyle = STextStyles
+                                                        .itemSubtitle(context)
+                                                    .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .accentColorRed);
+                                                break;
+                                              default:
+                                                break;
+                                            }
+                                            return Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.start,
+                                              children: [
+                                                Text(
+                                                  "Epic Cash Build Commit",
+                                                  style: STextStyles
+                                                          .desktopTextExtraExtraSmall(
+                                                              context)
+                                                      .copyWith(
+                                                          color: Theme.of(
+                                                                  context)
+                                                              .extension<
+                                                                  StackColors>()!
+                                                              .textDark),
+                                                ),
+                                                const SizedBox(
+                                                  height: 2,
+                                                ),
+                                                SelectableText(
+                                                  epicCashCommit,
+                                                  style: indicationStyle,
+                                                ),
+                                              ],
+                                            );
+                                          }),
+                                      const SizedBox(
+                                        width: 105,
+                                      ),
+                                      FutureBuilder(
+                                          future: commitMoneroFuture,
+                                          builder: (context,
+                                              AsyncSnapshot<dynamic> snapshot) {
+                                            bool commitExists = false;
+                                            bool isHead = false;
+                                            CommitStatus stateOfCommit =
+                                                CommitStatus.notLoaded;
+
+                                            if (snapshot.connectionState ==
+                                                    ConnectionState.done &&
+                                                snapshot.hasData) {
+                                              commitExists =
+                                                  snapshot.data![0] as bool;
+                                              isHead =
+                                                  snapshot.data![1] as bool;
+                                              if (commitExists && isHead) {
+                                                stateOfCommit =
+                                                    CommitStatus.isHead;
+                                              } else if (commitExists) {
+                                                stateOfCommit =
+                                                    CommitStatus.isOldCommit;
+                                              } else {
+                                                stateOfCommit =
+                                                    CommitStatus.notACommit;
+                                              }
+                                            }
+                                            TextStyle indicationStyle =
+                                                STextStyles.itemSubtitle(
+                                                    context);
+                                            switch (stateOfCommit) {
+                                              case CommitStatus.isHead:
+                                                indicationStyle = STextStyles
+                                                        .itemSubtitle(context)
+                                                    .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .accentColorGreen);
+                                                break;
+                                              case CommitStatus.isOldCommit:
+                                                indicationStyle = STextStyles
+                                                        .itemSubtitle(context)
+                                                    .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .accentColorYellow);
+                                                break;
+                                              case CommitStatus.notACommit:
+                                                indicationStyle = STextStyles
+                                                        .itemSubtitle(context)
+                                                    .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .accentColorRed);
+                                                break;
+                                              default:
+                                                break;
+                                            }
+                                            return Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.start,
+                                              children: [
+                                                Text(
+                                                  "Monero Build Commit",
+                                                  style: STextStyles
+                                                          .desktopTextExtraExtraSmall(
+                                                              context)
+                                                      .copyWith(
+                                                          color: Theme.of(
+                                                                  context)
+                                                              .extension<
+                                                                  StackColors>()!
+                                                              .textDark),
+                                                ),
+                                                const SizedBox(
+                                                  height: 2,
+                                                ),
+                                                SelectableText(
+                                                  moneroCommit,
+                                                  style: indicationStyle,
+                                                ),
+                                              ],
+                                            );
+                                          }),
+                                    ],
+                                  ),
+                                  const SizedBox(height: 35),
+                                  Row(
+                                    children: [
+                                      Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          Text(
+                                            "Website",
+                                            style: STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark),
+                                          ),
+                                          const SizedBox(
+                                            height: 2,
+                                          ),
+                                          BlueTextButton(
+                                            text: "https://stackwallet.com",
+                                            onTap: () {
+                                              launchUrl(
+                                                Uri.parse(
+                                                    "https://stackwallet.com"),
+                                                mode: LaunchMode
+                                                    .externalApplication,
+                                              );
+                                            },
+                                          ),
+                                        ],
+                                      )
+                                    ],
+                                  )
+                                ],
+                              );
+                            },
+                          )
+                        ],
+                      ),
+                    )
+                  ],
+                ),
+              ),
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}

From cb83515dbc774abc9c9e49fbd9f18f265ec699a1 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Mon, 7 Nov 2022 13:45:25 -0600
Subject: [PATCH 152/426] do not use wownero-seed (wow_seed)

---
 crypto_plugins/flutter_libmonero              |   2 +-
 .../coins/wownero/wownero_wallet_test.dart    | 107 ++++++++++++++++++
 .../wownero/wownero_wallet_test_data.dart     |   8 ++
 3 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index d92fea3e6..371443607 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit d92fea3e6b915b79697deafbd5710fb4c15bfc76
+Subproject commit 371443607433a0ec509e2933ee21def29e9ad429
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 83b4844c7..945d8650f 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -83,8 +83,10 @@ void main() async {
   _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
   walletService = wownero.createWowneroWalletService(_walletInfoSource);
 
+  /*
   group("Wownero 14 word tests", () {
     setUp(() async {
+      bool hasThrown = false;
       try {
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
@@ -113,7 +115,9 @@ void main() async {
       } catch (e, s) {
         print(e);
         print(s);
+        hasThrown = true;
       }
+      expect(hasThrown, false);
     });
 
     test("Test mainnet address generation from 14 word seed", () async {
@@ -147,6 +151,109 @@ void main() async {
       walletBase?.close();
       walletBase = wallet as WowneroWalletBase;
     });
+    
+    // TODO delete left over wallet file with name: name
+  });
+   */
+
+  group("Wownero 25 word tests", () {
+    setUp(() async {
+      bool hasThrown = false;
+      try {
+        final dirPath = await pathForWalletDir(name: name, type: type);
+        path = await pathForWallet(name: name, type: type);
+        credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
+            name: name, height: 465760, mnemonic: testMnemonic25);
+
+        walletInfo = WalletInfo.external(
+            id: WalletBase.idFor(name, type),
+            name: name,
+            type: type,
+            isRecovery: false,
+            restoreHeight: credentials.height ?? 0,
+            date: DateTime.now(),
+            path: path,
+            address: "",
+            dirPath: dirPath);
+        credentials.walletInfo = walletInfo;
+
+        _walletCreationService = WalletCreationService(
+          secureStorage: storage,
+          sharedPreferences: prefs,
+          walletService: walletService,
+          keyService: keysStorage,
+        );
+        _walletCreationService.changeWalletType();
+      } catch (e, s) {
+        print(e);
+        print(s);
+        hasThrown = true;
+      }
+      expect(hasThrown, false);
+    });
+
+    test("Test mainnet address generation from 25 word seed", () async {
+      bool hasThrown = false;
+      try {
+        name = 'namee${Random().nextInt(10000000)}';
+        final dirPath = await pathForWalletDir(name: name, type: type);
+        path = await pathForWallet(name: name, type: type);
+        try {
+          credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
+              name: name, height: 465760, mnemonic: testMnemonic25);
+        } catch (e, s) {
+          print(e);
+          print(s);
+          hasThrown = true;
+        }
+        expect(hasThrown, false);
+
+        walletInfo = WalletInfo.external(
+            id: WalletBase.idFor(name, type),
+            name: name,
+            type: type,
+            isRecovery: false,
+            restoreHeight: credentials.height ?? 0,
+            date: DateTime.now(),
+            path: path,
+            address: "",
+            dirPath: dirPath);
+        credentials.walletInfo = walletInfo;
+
+        _walletCreationService = WalletCreationService(
+          secureStorage: storage,
+          sharedPreferences: prefs,
+          walletService: walletService,
+          keyService: keysStorage,
+        );
+        _walletCreationService.changeWalletType();
+      } catch (e, s) {
+        print(e);
+        print(s);
+        hasThrown = true;
+      }
+      expect(hasThrown, false);
+
+      final wallet = await _walletCreationService.restoreFromSeed(credentials);
+      walletInfo.address = wallet.walletAddresses.address;
+
+      hasThrown = false;
+      try {
+        await _walletInfoSource.add(walletInfo);
+        walletBase?.close();
+        walletBase = wallet as WowneroWalletBase;
+
+        expect(walletInfo.address, mainnetTestData25[0][0]);
+      } catch (_) {
+        hasThrown = true;
+      }
+      expect(hasThrown, false);
+
+      walletBase?.close();
+      walletBase = wallet as WowneroWalletBase;
+    });
+
+    // TODO delete left over wallet file with name: name
   });
 }
 
diff --git a/test/services/coins/wownero/wownero_wallet_test_data.dart b/test/services/coins/wownero/wownero_wallet_test_data.dart
index 8ab825dfa..7f27fc486 100644
--- a/test/services/coins/wownero/wownero_wallet_test_data.dart
+++ b/test/services/coins/wownero/wownero_wallet_test_data.dart
@@ -12,3 +12,11 @@ var mainnetTestData14 = [
     'WW2KQLLt6gjC9gRsC4NGehbAZX6UPU7sK89UQFwSg3NKj3MXPwnjh5BiJVqYYNQb6JNsfa7oP7eDjLagtLa2H6YP11RhUNQqw'
   ]
 ];
+
+String testMnemonic25 =
+    'myth byline benches sadness nylon tamper guide giving match angled lurk rally makeup alarms river soapy dolphin woven ticket maul examine public luggage mammal alarms';
+var mainnetTestData25 = [
+  [
+    'Wo3piMnt1ztjLktFJNsfs9ce6N1tyHk7DB93cNqTGPJ7To3RS7W2q5DdxgQAG5E6RQXQhchQD7ip8WWL3fD8Ww5K2XmAXYxta'
+  ]
+];

From 6e5a0bad784831ba7c98db99b3291f6ab305ac48 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Mon, 7 Nov 2022 14:42:52 -0600
Subject: [PATCH 153/426] do not use wownero-seed (wow_seed) function for
 height, hardcoded POC

---
 crypto_plugins/flutter_libmonero                    |  2 +-
 lib/services/coins/wownero/wownero_wallet.dart      |  7 ++++---
 .../services/coins/wownero/wownero_wallet_test.dart | 13 ++-----------
 3 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index 371443607..da826f313 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit 371443607433a0ec509e2933ee21def29e9ad429
+Subproject commit da826f31352c695942bc9b821d1d0c82a9267ade
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index d3aba5bbb..a069414b6 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -713,8 +713,8 @@ class WowneroWallet extends CoinServiceAPI {
       final wallet = await _walletCreationService?.create(credentials);
 
       // subtract a couple days to ensure we have a buffer for SWB
-      final bufferedCreateHeight =
-          getSeedHeightSync(wallet?.seed.trim() as String);
+      final bufferedCreateHeight = 0;
+      //final bufferedCreateHeight = getSeedHeightSync(wallet?.seed.trim() as String); // TODO use an alternative to wow_seed's get_seed_height
 
       await DB.instance.put<dynamic>(
           boxName: walletId, key: "restoreHeight", value: bufferedCreateHeight);
@@ -969,7 +969,8 @@ class WowneroWallet extends CoinServiceAPI {
       await _secureStore.write(
           key: '${_walletId}_mnemonic', value: mnemonic.trim());
 
-      height = getSeedHeightSync(mnemonic.trim());
+      height = 0;
+      //height = getSeedHeightSync(mnemonic.trim()); // TODO use an alternative to wow_seed's get_seed_height
 
       await DB.instance
           .put<dynamic>(boxName: walletId, key: "restoreHeight", value: height);
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 945d8650f..ca7540da5 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -91,7 +91,7 @@ void main() async {
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
         credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
-            name: name, height: 465760, mnemonic: testMnemonic14);
+            name: name, height: 465760, mnemonic: testMnemonic14); // TODO catch failure
 
         walletInfo = WalletInfo.external(
             id: WalletBase.idFor(name, type),
@@ -163,7 +163,7 @@ void main() async {
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
         credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
-            name: name, height: 465760, mnemonic: testMnemonic25);
+            name: name, height: 465760, mnemonic: testMnemonic25); // TODO catch failure
 
         walletInfo = WalletInfo.external(
             id: WalletBase.idFor(name, type),
@@ -198,15 +198,6 @@ void main() async {
         name = 'namee${Random().nextInt(10000000)}';
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
-        try {
-          credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
-              name: name, height: 465760, mnemonic: testMnemonic25);
-        } catch (e, s) {
-          print(e);
-          print(s);
-          hasThrown = true;
-        }
-        expect(hasThrown, false);
 
         walletInfo = WalletInfo.external(
             id: WalletBase.idFor(name, type),

From b41c4c37bd6c5756fe8be0f4011da685d1265bd8 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Mon, 7 Nov 2022 14:46:48 -0600
Subject: [PATCH 154/426] delineate divergence point more clearly

---
 lib/services/coins/wownero/wownero_wallet.dart | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index a069414b6..1153a881a 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -713,8 +713,12 @@ class WowneroWallet extends CoinServiceAPI {
       final wallet = await _walletCreationService?.create(credentials);
 
       // subtract a couple days to ensure we have a buffer for SWB
+      // 14 words
+      //final bufferedCreateHeight = getSeedHeightSync(wallet?.seed.trim() as String);
+
+      // 25 words
       final bufferedCreateHeight = 0;
-      //final bufferedCreateHeight = getSeedHeightSync(wallet?.seed.trim() as String); // TODO use an alternative to wow_seed's get_seed_height
+      // TODO use an alternative to wow_seed's get_seed_height
 
       await DB.instance.put<dynamic>(
           boxName: walletId, key: "restoreHeight", value: bufferedCreateHeight);

From c962f597fdc9c696edbbdac655172ab9f5e217e7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 7 Nov 2022 14:46:36 -0600
Subject: [PATCH 155/426] added extra checks to BCH as well as test cases

---
 .../coins/bitcoincash/bitcoincash_wallet.dart |  58 ++++---
 .../bitcoincash/bitcoincash_wallet_test.dart  | 164 +++++++++++++++++-
 2 files changed, 199 insertions(+), 23 deletions(-)

diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index 98a31ee0c..5b3b54663 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -208,9 +208,9 @@ class BitcoinCashWallet extends CoinServiceAPI {
           _getCurrentAddressForChain(0, DerivePathType.bip44);
   Future<String>? _currentReceivingAddressP2PKH;
 
-  Future<String> get currentReceivingAddressP2SH =>
-      _currentReceivingAddressP2SH ??=
-          _getCurrentAddressForChain(0, DerivePathType.bip49);
+  // Future<String> get currentReceivingAddressP2SH =>
+  //     _currentReceivingAddressP2SH ??=
+  //         _getCurrentAddressForChain(0, DerivePathType.bip49);
   Future<String>? _currentReceivingAddressP2SH;
 
   @override
@@ -269,7 +269,11 @@ class BitcoinCashWallet extends CoinServiceAPI {
     try {
       if (bitbox.Address.detectFormat(address) ==
           bitbox.Address.formatCashAddr) {
-        address = bitbox.Address.toLegacyAddress(address);
+        if (validateCashAddr(address)) {
+          address = bitbox.Address.toLegacyAddress(address);
+        } else {
+          throw ArgumentError('$address is not currently supported');
+        }
       }
     } catch (e, s) {}
     try {
@@ -294,11 +298,14 @@ class BitcoinCashWallet extends CoinServiceAPI {
       } catch (err) {
         // Bech32 decode fail
       }
-      if (_network.bech32 != decodeBech32!.hrp) {
-        throw ArgumentError('Invalid prefix or Network mismatch');
-      }
-      if (decodeBech32.version != 0) {
-        throw ArgumentError('Invalid address version');
+
+      if (decodeBech32 != null) {
+        if (_network.bech32 != decodeBech32.hrp) {
+          throw ArgumentError('Invalid prefix or Network mismatch');
+        }
+        if (decodeBech32.version != 0) {
+          throw ArgumentError('Invalid address version');
+        }
       }
     }
     throw ArgumentError('$address has no matching Script');
@@ -1203,6 +1210,15 @@ class BitcoinCashWallet extends CoinServiceAPI {
     _transactionData = Future(() => cachedTxData!);
   }
 
+  bool validateCashAddr(String cashAddr) {
+    String addr = cashAddr;
+    if (cashAddr.contains(":")) {
+      addr = cashAddr.split(":").last;
+    }
+
+    return addr.startsWith("q");
+  }
+
   @override
   bool validateAddress(String address) {
     try {
@@ -1217,12 +1233,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
       }
 
       if (format == bitbox.Address.formatCashAddr) {
-        String addr = address;
-        if (address.contains(":")) {
-          addr = address.split(":").last;
-        }
-
-        return addr.startsWith("q");
+        return validateCashAddr(address);
       } else {
         return address.startsWith("1");
       }
@@ -2085,7 +2096,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
   String _convertToScriptHash(String bchAddress, NetworkType network) {
     try {
       if (bitbox.Address.detectFormat(bchAddress) ==
-          bitbox.Address.formatCashAddr) {
+              bitbox.Address.formatCashAddr &&
+          validateCashAddr(bchAddress)) {
         bchAddress = bitbox.Address.toLegacyAddress(bchAddress);
       }
       final output = Address.addressToOutputScript(bchAddress, network);
@@ -2163,7 +2175,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
     List<String> allAddressesOld = await _fetchAllOwnAddresses();
     List<String> allAddresses = [];
     for (String address in allAddressesOld) {
-      if (bitbox.Address.detectFormat(address) == bitbox.Address.formatLegacy) {
+      if (bitbox.Address.detectFormat(address) == bitbox.Address.formatLegacy &&
+          addressType(address: address) == DerivePathType.bip44) {
         allAddresses.add(bitbox.Address.toCashAddress(address));
       } else {
         allAddresses.add(address);
@@ -2882,7 +2895,12 @@ class BitcoinCashWallet extends CoinServiceAPI {
             String address = output["scriptPubKey"]["addresses"][0] as String;
             if (bitbox.Address.detectFormat(address) ==
                 bitbox.Address.formatCashAddr) {
-              address = bitbox.Address.toLegacyAddress(address);
+              if (validateCashAddr(address)) {
+                address = bitbox.Address.toLegacyAddress(address);
+              } else {
+                throw Exception(
+                    "Unsupported address found during fetchBuildTxData(): $address");
+              }
             }
             if (!addressTxid.containsKey(address)) {
               addressTxid[address] = <String>[];
@@ -2913,10 +2931,6 @@ class BitcoinCashWallet extends CoinServiceAPI {
         );
         for (int i = 0; i < p2pkhLength; i++) {
           String address = addressesP2PKH[i];
-          if (bitbox.Address.detectFormat(address) ==
-              bitbox.Address.formatCashAddr) {
-            address = bitbox.Address.toLegacyAddress(address);
-          }
 
           // receives
           final receiveDerivation = receiveDerivations[address];
diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart
index 50ff8f741..077163809 100644
--- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart
+++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart
@@ -60,7 +60,7 @@ void main() {
     });
   });
 
-  group("validate mainnet bitcoincash addresses", () {
+  group("mainnet bitcoincash addressType", () {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
@@ -136,6 +136,168 @@ void main() {
       verifyNoMoreInteractions(priceAPI);
     });
 
+    test("P2PKH cashaddr with prefix", () {
+      expect(
+          mainnetWallet?.addressType(
+              address:
+                  "bitcoincash:qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"),
+          DerivePathType.bip44);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
+    test("P2PKH cashaddr without prefix", () {
+      expect(
+          mainnetWallet?.addressType(
+              address: "qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"),
+          DerivePathType.bip44);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
+    test("Multisig cashaddr with prefix", () {
+      expect(
+          () => mainnetWallet?.addressType(
+              address:
+                  "bitcoincash:pzpp3nchmzzf0gr69lj82ymurg5u3ds6kcwr5m07np"),
+          throwsArgumentError);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
+    test("Multisig cashaddr without prefix", () {
+      expect(
+          () => mainnetWallet?.addressType(
+              address: "pzpp3nchmzzf0gr69lj82ymurg5u3ds6kcwr5m07np"),
+          throwsArgumentError);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
+    test("Multisig/P2SH address", () {
+      expect(
+          mainnetWallet?.addressType(
+              address: "3DYuVEmuKWQFxJcF7jDPhwPiXLTiNnyMFb"),
+          DerivePathType.bip49);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+  });
+
+  group("validate mainnet bitcoincash addresses", () {
+    MockElectrumX? client;
+    MockCachedElectrumX? cachedClient;
+    MockPriceAPI? priceAPI;
+    FakeSecureStorage? secureStore;
+    MockTransactionNotificationTracker? tracker;
+
+    BitcoinCashWallet? mainnetWallet;
+
+    setUp(() {
+      client = MockElectrumX();
+      cachedClient = MockCachedElectrumX();
+      priceAPI = MockPriceAPI();
+      secureStore = FakeSecureStorage();
+      tracker = MockTransactionNotificationTracker();
+
+      mainnetWallet = BitcoinCashWallet(
+        walletId: "validateAddressMainNet",
+        walletName: "validateAddressMainNet",
+        coin: Coin.bitcoincash,
+        client: client!,
+        cachedClient: cachedClient!,
+        tracker: tracker!,
+        priceAPI: priceAPI,
+        secureStore: secureStore,
+      );
+    });
+
+    test("valid mainnet legacy/p2pkh address type", () {
+      expect(
+          mainnetWallet?.validateAddress("1DP3PUePwMa5CoZwzjznVKhzdLsZftjcAT"),
+          true);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
+    test("valid mainnet legacy/p2pkh cashaddr with prefix address type", () {
+      expect(
+          mainnetWallet?.validateAddress(
+              "bitcoincash:qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"),
+          true);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
+    test("valid mainnet legacy/p2pkh cashaddr without prefix address type", () {
+      expect(
+          mainnetWallet
+              ?.validateAddress("qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"),
+          true);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
+    test("invalid legacy/p2pkh address type", () {
+      expect(
+          mainnetWallet?.validateAddress("mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"),
+          false);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
+    test(
+        "invalid cashaddr (is valid multisig but bitbox is broken for multisig)",
+        () {
+      expect(
+          mainnetWallet
+              ?.validateAddress("pzpp3nchmzzf0gr69lj82ymurg5u3ds6kcwr5m07np"),
+          false);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
+    test("multisig address should fail for bitbox", () {
+      expect(
+          mainnetWallet?.validateAddress("3DYuVEmuKWQFxJcF7jDPhwPiXLTiNnyMFb"),
+          false);
+      expect(secureStore?.interactions, 0);
+      verifyNoMoreInteractions(client);
+      verifyNoMoreInteractions(cachedClient);
+      verifyNoMoreInteractions(tracker);
+      verifyNoMoreInteractions(priceAPI);
+    });
+
     test("invalid mainnet bitcoincash legacy/p2pkh address", () {
       expect(
           mainnetWallet?.validateAddress("mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"),

From b3a343d28a29c6cc60e3f71d6d851b2aff27ebcc Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 7 Nov 2022 15:48:16 -0600
Subject: [PATCH 156/426] desktop theme toggle

---
 .../settings_menu/appearance_settings.dart    | 391 ++++++++++--------
 1 file changed, 218 insertions(+), 173 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
index b5f239ab1..bf6fc81e2 100644
--- a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
@@ -1,16 +1,19 @@
 import 'package:flutter/material.dart';
-import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/hive/db.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/ui/color_theme_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/color_theme.dart';
+import 'package:stackwallet/utilities/theme/dark_colors.dart';
+import 'package:stackwallet/utilities/theme/light_colors.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import '../../../providers/global/prefs_provider.dart';
-import '../../../utilities/constants.dart';
-import '../../../widgets/custom_buttons/draggable_switch_button.dart';
-
 class AppearanceOptionSettings extends ConsumerStatefulWidget {
   const AppearanceOptionSettings({Key? key}) : super(key: key);
 
@@ -140,7 +143,10 @@ class _AppearanceOptionSettings
                     ],
                   ),
                 ),
-                ThemeToggle(),
+                const Padding(
+                  padding: EdgeInsets.all(10),
+                  child: ThemeToggle(),
+                ),
               ],
             ),
           ),
@@ -150,7 +156,7 @@ class _AppearanceOptionSettings
   }
 }
 
-class ThemeToggle extends StatefulWidget {
+class ThemeToggle extends ConsumerStatefulWidget {
   const ThemeToggle({
     Key? key,
   }) : super(key: key);
@@ -159,187 +165,226 @@ class ThemeToggle extends StatefulWidget {
   // final void Function(bool)? onChanged;
 
   @override
-  State<StatefulWidget> createState() => _ThemeToggle();
+  ConsumerState<ThemeToggle> createState() => _ThemeToggle();
 }
 
-class _ThemeToggle extends State<ThemeToggle> {
+class _ThemeToggle extends ConsumerState<ThemeToggle> {
   // late bool externalCallsEnabled;
 
+  late String _selectedTheme;
+
+  @override
+  void initState() {
+    _selectedTheme =
+        DB.instance.get<dynamic>(boxName: DB.boxNameTheme, key: "colorScheme")
+                as String? ??
+            "light";
+
+    super.initState();
+  }
+
   @override
   Widget build(BuildContext context) {
     return Row(
-      // mainAxisAlignment: MainAxisAlignment.spaceEvenly,
       children: [
-        Padding(
-          padding: const EdgeInsets.all(8.0),
-          child: RawMaterialButton(
-            elevation: 0,
-            hoverColor: Colors.transparent,
-            shape: RoundedRectangleBorder(
-              side: BorderSide(
-                color:
-                    Theme.of(context).extension<StackColors>()!.infoItemIcons,
-                width: 2,
-              ),
-              // side: !externalCallsEnabled
-              //     ? BorderSide.none
-              //     : BorderSide(
-              //         color: Theme.of(context)
-              //             .extension<StackColors>()!
-              //             .infoItemIcons,
-              //         width: 2,
-              //       ),
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius * 2,
-              ),
-            ),
-            onPressed: () {}, //onPressed
-            child: Padding(
-              padding: const EdgeInsets.all(8.0),
-              child: Stack(
-                children: [
-                  Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      Padding(
-                        padding: const EdgeInsets.only(
-                          left: 24,
-                        ),
-                        child: SvgPicture.asset(
-                          Assets.svg.themeLight,
-                        ),
-                      ),
-                      Padding(
-                        padding: const EdgeInsets.only(
-                          left: 50,
-                          top: 12,
-                        ),
-                        child: Text(
-                          "Light",
-                          style: STextStyles.desktopTextExtraSmall(context)
-                              .copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark,
-                          ),
-                        ),
-                      )
-                    ],
-                  ),
-                  // if (externalCallsEnabled)
-                  Positioned(
-                    bottom: 0,
-                    left: 6,
-                    child: SvgPicture.asset(
-                      Assets.svg.checkCircle,
-                      width: 20,
-                      height: 20,
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .infoItemIcons,
-                    ),
-                  ),
-                  // if (!externalCallsEnabled)
-                  //   Positioned(
-                  //     bottom: 0,
-                  //     left: 6,
-                  //     child: Container(
-                  //       width: 20,
-                  //       height: 20,
-                  //       decoration: BoxDecoration(
-                  //         borderRadius: BorderRadius.circular(1000),
-                  //         color: Theme.of(context)
-                  //             .extension<StackColors>()!
-                  //             .textFieldDefaultBG,
-                  //       ),
-                  //     ),
-                  //   ),
-                ],
-              ),
+        MaterialButton(
+          splashColor: Colors.transparent,
+          hoverColor: Colors.transparent,
+          padding: const EdgeInsets.all(0),
+          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
             ),
           ),
-        ),
-        const SizedBox(
-          width: 1,
-        ),
-        Expanded(
-          child: Padding(
-            padding: const EdgeInsets.all(8.0),
-            child: RawMaterialButton(
-              elevation: 0,
-              hoverColor: Colors.transparent,
-              shape: RoundedRectangleBorder(
-                // side: !externalCallsEnabled
-                //     ? BorderSide.none
-                //     : BorderSide(
-                //         color: Theme.of(context)
-                //             .extension<StackColors>()!
-                //             .infoItemIcons,
-                //         width: 2,
-                //       ),
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius * 2,
-                ),
-              ),
-              onPressed: () {}, //onPressed
-              child: Padding(
-                padding: const EdgeInsets.all(8.0),
-                child: Stack(
-                  children: [
-                    Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        SvgPicture.asset(
-                          Assets.svg.themeDark,
-                        ),
-                        Padding(
-                          padding: const EdgeInsets.only(
-                            left: 45,
-                            top: 12,
-                          ),
-                          child: Text(
-                            "Dark",
-                            style: STextStyles.desktopTextExtraSmall(context)
-                                .copyWith(
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textDark,
-                            ),
-                          ),
-                        ),
-                      ],
-                    ),
-                    // if (externalCallsEnabled)
-                    //   Positioned(
-                    //     bottom: 0,
-                    //     left: 0,
-                    //     child: SvgPicture.asset(
-                    //       Assets.svg.checkCircle,
-                    //       width: 20,
-                    //       height: 20,
-                    //       color: Theme.of(context)
-                    //           .extension<StackColors>()!
-                    //           .infoItemIcons,
-                    //     ),
-                    //   ),
-                    // if (!externalCallsEnabled)
-                    Positioned(
-                      bottom: 0,
-                      left: 0,
-                      child: Container(
-                        width: 20,
-                        height: 20,
-                        decoration: BoxDecoration(
-                          borderRadius: BorderRadius.circular(1000),
-                          color: Theme.of(context)
+          onPressed: () {
+            DB.instance.put<dynamic>(
+              boxName: DB.boxNameTheme,
+              key: "colorScheme",
+              value: ThemeType.light.name,
+            );
+            ref.read(colorThemeProvider.state).state =
+                StackColors.fromStackColorTheme(
+              LightColors(),
+            );
+
+            setState(() {
+              _selectedTheme = "light";
+            });
+          },
+          child: SizedBox(
+            width: 200,
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                Container(
+                  decoration: BoxDecoration(
+                    border: Border.all(
+                      width: 2.5,
+                      color: _selectedTheme == "light"
+                          ? Theme.of(context)
                               .extension<StackColors>()!
-                              .textFieldDefaultBG,
-                        ),
+                              .infoItemIcons
+                          : Theme.of(context).extension<StackColors>()!.popupBG,
+                    ),
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
+                  ),
+                  child: SvgPicture.asset(
+                    Assets.svg.themeLight,
+                  ),
+                ),
+                const SizedBox(
+                  height: 12,
+                ),
+                Row(
+                  children: [
+                    SizedBox(
+                      width: 20,
+                      height: 20,
+                      child: Radio(
+                        activeColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .radioButtonIconEnabled,
+                        value: "light",
+                        groupValue: _selectedTheme,
+                        onChanged: (newValue) {
+                          if (newValue is String && newValue == "light") {
+                            DB.instance.put<dynamic>(
+                              boxName: DB.boxNameTheme,
+                              key: "colorScheme",
+                              value: ThemeType.light.name,
+                            );
+                            ref.read(colorThemeProvider.state).state =
+                                StackColors.fromStackColorTheme(
+                              LightColors(),
+                            );
+
+                            setState(() {
+                              _selectedTheme = "light";
+                            });
+                          }
+                        },
+                      ),
+                    ),
+                    const SizedBox(
+                      width: 14,
+                    ),
+                    Text(
+                      "Light",
+                      style:
+                          STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark,
                       ),
                     ),
                   ],
                 ),
-              ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          width: 20,
+        ),
+        MaterialButton(
+          splashColor: Colors.transparent,
+          hoverColor: Colors.transparent,
+          padding: const EdgeInsets.all(0),
+          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+          ),
+          onPressed: () {
+            DB.instance.put<dynamic>(
+              boxName: DB.boxNameTheme,
+              key: "colorScheme",
+              value: ThemeType.dark.name,
+            );
+            ref.read(colorThemeProvider.state).state =
+                StackColors.fromStackColorTheme(
+              DarkColors(),
+            );
+
+            setState(() {
+              _selectedTheme = "dark";
+            });
+          },
+          child: SizedBox(
+            width: 200,
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                Container(
+                  decoration: BoxDecoration(
+                    border: Border.all(
+                      width: 2.5,
+                      color: _selectedTheme == "dark"
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .infoItemIcons
+                          : Theme.of(context).extension<StackColors>()!.popupBG,
+                    ),
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
+                  ),
+                  child: SvgPicture.asset(
+                    Assets.svg.themeDark,
+                  ),
+                ),
+                const SizedBox(
+                  height: 12,
+                ),
+                Row(
+                  children: [
+                    SizedBox(
+                      width: 20,
+                      height: 20,
+                      child: Radio(
+                        activeColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .radioButtonIconEnabled,
+                        value: "dark",
+                        groupValue: _selectedTheme,
+                        onChanged: (newValue) {
+                          if (newValue is String && newValue == "dark") {
+                            DB.instance.put<dynamic>(
+                              boxName: DB.boxNameTheme,
+                              key: "colorScheme",
+                              value: ThemeType.dark.name,
+                            );
+                            ref.read(colorThemeProvider.state).state =
+                                StackColors.fromStackColorTheme(
+                              DarkColors(),
+                            );
+
+                            setState(() {
+                              _selectedTheme = "dark";
+                            });
+                          }
+                        },
+                      ),
+                    ),
+                    const SizedBox(
+                      width: 14,
+                    ),
+                    Text(
+                      "Dark",
+                      style:
+                          STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark,
+                      ),
+                    ),
+                  ],
+                ),
+              ],
             ),
           ),
         ),

From 3c627a5ddb36e93c229f9e96a9829df1664d700d Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 7 Nov 2022 15:57:04 -0600
Subject: [PATCH 157/426] support tweak

---
 .../desktop_support_view.dart                   | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart b/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart
index 8e9d709d1..ce3e3f3cc 100644
--- a/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart
+++ b/lib/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart
@@ -1,12 +1,11 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/support_view.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 
-import '../../../pages/settings_views/global_settings_view/support_view.dart';
-
 class DesktopSupportView extends ConsumerStatefulWidget {
   const DesktopSupportView({Key? key}) : super(key: key);
 
@@ -38,10 +37,18 @@ class _DesktopSupportView extends ConsumerState<DesktopSupportView> {
         ),
       ),
       body: Column(
-        children: const [
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
           Padding(
-            padding: EdgeInsets.fromLTRB(24, 10, 377, 270),
-            child: SupportView(),
+            padding: const EdgeInsets.fromLTRB(24, 10, 0, 0),
+            child: Row(
+              children: const [
+                SizedBox(
+                  width: 576,
+                  child: SupportView(),
+                ),
+              ],
+            ),
           ),
         ],
       ),

From 2f6b1278fe59971855e9772de7e60961abf3a29e Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 7 Nov 2022 16:30:17 -0600
Subject: [PATCH 158/426] swb desktop layout tweaks

---
 .../create_backup_view.dart                   |   4 +-
 .../restore_from_file_view.dart               |   4 +-
 .../backup_and_restore_settings.dart          | 192 ++++++++++--------
 .../enable_backup_dialog.dart                 |   3 +-
 4 files changed, 115 insertions(+), 88 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 2d2ed4960..30fcb7962 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -157,7 +157,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                               .textDark3),
                 ),
               ),
-              // child,
+              child,
               const SizedBox(height: 20),
               Row(
                 children: [
@@ -442,7 +442,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
             const SizedBox(
               height: 16,
             ),
-            const Spacer(),
+            if (!isDesktop) const Spacer(),
             TextButton(
               style: shouldEnableCreate
                   ? Theme.of(context)
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index 9f2796415..0c101d0b3 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -142,7 +142,7 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                     textAlign: TextAlign.left,
                   ),
                 ),
-                // child,
+                child,
                 const SizedBox(height: 20),
                 Row(
                   children: [
@@ -285,7 +285,7 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
               const SizedBox(
                 height: 16,
               ),
-              const Spacer(),
+              if (!isDesktop) const Spacer(),
               TextButton(
                 style: passwordController.text.isEmpty ||
                         fileLocationController.text.isEmpty
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index b59206f17..49debf22f 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -64,48 +64,56 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                             height: 48,
                           ),
                           Center(
-                            child: Padding(
-                              padding: const EdgeInsets.all(10),
-                              child: RichText(
-                                textAlign: TextAlign.start,
-                                text: TextSpan(
-                                  children: [
-                                    TextSpan(
-                                      text: "Auto Backup",
-                                      style:
-                                          STextStyles.desktopTextSmall(context),
+                            child: Row(
+                              children: [
+                                Expanded(
+                                  child: Padding(
+                                    padding: const EdgeInsets.all(10),
+                                    child: RichText(
+                                      textAlign: TextAlign.start,
+                                      text: TextSpan(
+                                        children: [
+                                          TextSpan(
+                                            text: "Auto Backup",
+                                            style: STextStyles.desktopTextSmall(
+                                                context),
+                                          ),
+                                          TextSpan(
+                                            text:
+                                                "\n\nAuto backup is a custom Stack Wallet feature that offers a convenient backup of your data."
+                                                "To ensure maximum security, we recommend using a unique password that you haven't used anywhere "
+                                                "else on the internet before. Your password is not stored.",
+                                            style: STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context),
+                                          ),
+                                          TextSpan(
+                                            text:
+                                                "\n\nFor more information, please see our website ",
+                                            style: STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context),
+                                          ),
+                                          TextSpan(
+                                            text: "stackwallet.com",
+                                            style: STextStyles.richLink(context)
+                                                .copyWith(fontSize: 14),
+                                            recognizer: TapGestureRecognizer()
+                                              ..onTap = () {
+                                                launchUrl(
+                                                  Uri.parse(
+                                                      "https://stackwallet.com/"),
+                                                  mode: LaunchMode
+                                                      .externalApplication,
+                                                );
+                                              },
+                                          ),
+                                        ],
+                                      ),
                                     ),
-                                    TextSpan(
-                                      text:
-                                          "\n\nAuto backup is a custom Stack Wallet feature that offers a convenient backup of your data."
-                                          "To ensure maximum security, we recommend using a unique password that you haven't used anywhere "
-                                          "else on the internet before. Your password is not stored.",
-                                      style: STextStyles
-                                          .desktopTextExtraExtraSmall(context),
-                                    ),
-                                    TextSpan(
-                                      text:
-                                          "\n\nFor more information, please see our website ",
-                                      style: STextStyles
-                                          .desktopTextExtraExtraSmall(context),
-                                    ),
-                                    TextSpan(
-                                      text: "stackwallet.com",
-                                      style: STextStyles.richLink(context)
-                                          .copyWith(fontSize: 14),
-                                      recognizer: TapGestureRecognizer()
-                                        ..onTap = () {
-                                          launchUrl(
-                                            Uri.parse(
-                                                "https://stackwallet.com/"),
-                                            mode:
-                                                LaunchMode.externalApplication,
-                                          );
-                                        },
-                                    ),
-                                  ],
+                                  ),
                                 ),
-                              ),
+                              ],
                             ),
                           ),
                           Column(
@@ -148,39 +156,49 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                             alignment: Alignment.topLeft,
                           ),
                           Center(
-                            child: Padding(
-                              padding: const EdgeInsets.all(10),
-                              child: RichText(
-                                textAlign: TextAlign.start,
-                                text: TextSpan(
-                                  children: [
-                                    TextSpan(
-                                      text: "Manual Backup",
-                                      style:
-                                          STextStyles.desktopTextSmall(context),
+                            child: Row(
+                              children: [
+                                Expanded(
+                                  child: Padding(
+                                    padding: const EdgeInsets.all(10),
+                                    child: RichText(
+                                      textAlign: TextAlign.start,
+                                      text: TextSpan(
+                                        children: [
+                                          TextSpan(
+                                            text: "Manual Backup",
+                                            style: STextStyles.desktopTextSmall(
+                                                context),
+                                          ),
+                                          TextSpan(
+                                            text:
+                                                "\n\nCreate manual backup to easily transfer your data between devices. "
+                                                "You will create a backup file that can be later used in the Restore option. "
+                                                "Use a strong password to encrypt your data.",
+                                            style: STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context),
+                                          ),
+                                        ],
+                                      ),
                                     ),
-                                    TextSpan(
-                                      text:
-                                          "\n\nCreate manual backup to easily transfer your data between devices. "
-                                          "You will create a backup file that can be later used in the Restore option. "
-                                          "Use a strong password to encrypt your data.",
-                                      style: STextStyles
-                                          .desktopTextExtraExtraSmall(context),
-                                    ),
-                                  ],
+                                  ),
                                 ),
-                              ),
+                              ],
                             ),
                           ),
                           Column(
                             crossAxisAlignment: CrossAxisAlignment.start,
                             children: [
                               Padding(
-                                padding: EdgeInsets.all(
+                                padding: const EdgeInsets.all(
                                   10,
                                 ),
                                 child: createBackup
-                                    ? const CreateBackupView()
+                                    ? const SizedBox(
+                                        width: 512,
+                                        child: CreateBackupView(),
+                                      )
                                     : PrimaryButton(
                                         desktopMed: true,
                                         width: 200,
@@ -217,27 +235,34 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                             alignment: Alignment.topLeft,
                           ),
                           Center(
-                            child: Padding(
-                              padding: const EdgeInsets.all(10),
-                              child: RichText(
-                                textAlign: TextAlign.start,
-                                text: TextSpan(
-                                  children: [
-                                    TextSpan(
-                                      text: "Restore Backup",
-                                      style:
-                                          STextStyles.desktopTextSmall(context),
+                            child: Row(
+                              children: [
+                                Expanded(
+                                  child: Padding(
+                                    padding: const EdgeInsets.all(10),
+                                    child: RichText(
+                                      textAlign: TextAlign.start,
+                                      text: TextSpan(
+                                        children: [
+                                          TextSpan(
+                                            text: "Restore Backup",
+                                            style: STextStyles.desktopTextSmall(
+                                                context),
+                                          ),
+                                          TextSpan(
+                                            text:
+                                                "\n\nUse your Stack Wallet backup file to restore your wallets, address book "
+                                                "and wallet preferences.",
+                                            style: STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context),
+                                          ),
+                                        ],
+                                      ),
                                     ),
-                                    TextSpan(
-                                      text:
-                                          "\n\nUse your Stack Wallet backup file to restore your wallets, address book "
-                                          "and wallet preferences.",
-                                      style: STextStyles
-                                          .desktopTextExtraExtraSmall(context),
-                                    ),
-                                  ],
+                                  ),
                                 ),
-                              ),
+                              ],
                             ),
                           ),
                           Column(
@@ -248,7 +273,10 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                   10,
                                 ),
                                 child: restoreBackup
-                                    ? RestoreFromFileView()
+                                    ? const SizedBox(
+                                        width: 512,
+                                        child: RestoreFromFileView(),
+                                      )
                                     : PrimaryButton(
                                         desktopMed: true,
                                         width: 200,
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
index 046d136a8..963fb4441 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
@@ -61,8 +61,7 @@ class EnableBackupDialog extends StatelessWidget {
                   child: SecondaryButton(
                     label: "Cancel",
                     onPressed: () {
-                      int count = 0;
-                      Navigator.of(context).popUntil((_) => count++ >= 2);
+                      Navigator.of(context).pop();
                     },
                   ),
                 ),

From 77aa3bc8e484534f893c3ee5f04820bca50918ad Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Mon, 7 Nov 2022 16:45:26 -0600
Subject: [PATCH 159/426] use wownero-seed for 14 word seed, use wownero
 wallet2 for 25 word seed

and update tests showing examples of both.  TODO proper validation, must eg calculate and check checksums etc
---
 crypto_plugins/flutter_libmonero              |  2 +-
 .../coins/wownero/wownero_wallet_test.dart    | 40 ++++++++++---------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index da826f313..e95c19662 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit da826f31352c695942bc9b821d1d0c82a9267ade
+Subproject commit e95c19662ccf17d83109ab7b651cfbc0521deb47
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index ca7540da5..2099df364 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -83,7 +83,6 @@ void main() async {
   _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
   walletService = wownero.createWowneroWalletService(_walletInfoSource);
 
-  /*
   group("Wownero 14 word tests", () {
     setUp(() async {
       bool hasThrown = false;
@@ -91,7 +90,9 @@ void main() async {
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
         credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
-            name: name, height: 465760, mnemonic: testMnemonic14); // TODO catch failure
+            name: name,
+            height: 465760,
+            mnemonic: testMnemonic14); // TODO catch failure
 
         walletInfo = WalletInfo.external(
             id: WalletBase.idFor(name, type),
@@ -128,21 +129,21 @@ void main() async {
       try {
         await _walletInfoSource.add(walletInfo);
         walletBase?.close();
-          walletBase = wallet as WowneroWalletBase;
+        walletBase = wallet as WowneroWalletBase;
 
         expect(walletInfo.address, mainnetTestData14[0][0]);
-        expect(
-            await walletBase!.getTransactionAddress(0, 0), mainnetTestData14[0][0]);
-        expect(
-            await walletBase!.getTransactionAddress(0, 1), mainnetTestData14[0][1]);
-        expect(
-            await walletBase!.getTransactionAddress(0, 2), mainnetTestData14[0][2]);
-        expect(
-            await walletBase!.getTransactionAddress(1, 0), mainnetTestData14[1][0]);
-        expect(
-            await walletBase!.getTransactionAddress(1, 1), mainnetTestData14[1][1]);
-        expect(
-            await walletBase!.getTransactionAddress(1, 2), mainnetTestData14[1][2]);
+        expect(await walletBase!.getTransactionAddress(0, 0),
+            mainnetTestData14[0][0]);
+        expect(await walletBase!.getTransactionAddress(0, 1),
+            mainnetTestData14[0][1]);
+        expect(await walletBase!.getTransactionAddress(0, 2),
+            mainnetTestData14[0][2]);
+        expect(await walletBase!.getTransactionAddress(1, 0),
+            mainnetTestData14[1][0]);
+        expect(await walletBase!.getTransactionAddress(1, 1),
+            mainnetTestData14[1][1]);
+        expect(await walletBase!.getTransactionAddress(1, 2),
+            mainnetTestData14[1][2]);
       } catch (_) {
         hasThrown = true;
       }
@@ -151,19 +152,21 @@ void main() async {
       walletBase?.close();
       walletBase = wallet as WowneroWalletBase;
     });
-    
+
     // TODO delete left over wallet file with name: name
   });
-   */
 
   group("Wownero 25 word tests", () {
     setUp(() async {
       bool hasThrown = false;
       try {
+        name = 'namee${Random().nextInt(10000000)}';
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
         credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
-            name: name, height: 465760, mnemonic: testMnemonic25); // TODO catch failure
+            name: name,
+            height: 465760,
+            mnemonic: testMnemonic25); // TODO catch failure
 
         walletInfo = WalletInfo.external(
             id: WalletBase.idFor(name, type),
@@ -195,7 +198,6 @@ void main() async {
     test("Test mainnet address generation from 25 word seed", () async {
       bool hasThrown = false;
       try {
-        name = 'namee${Random().nextInt(10000000)}';
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
 

From fa0c982274159d3d7be179ad48a88cf50faef62a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 8 Nov 2022 07:35:28 -0600
Subject: [PATCH 160/426] Return what we internally consider the "txid" for
 epic transactions from the epic confirmSend to be consistent with all other
 coins confirmSend return value. This should fix the epic notes issue.

---
 .../coins/epiccash/epiccash_wallet.dart         | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart
index 3702a9158..6c71f39e4 100644
--- a/lib/services/coins/epiccash/epiccash_wallet.dart
+++ b/lib/services/coins/epiccash/epiccash_wallet.dart
@@ -833,10 +833,16 @@ class EpicCashWallet extends CoinServiceAPI {
         final txLogEntryFirst = txLogEntry[0];
         Logger.print("TX_LOG_ENTRY_IS $txLogEntryFirst");
         final wallet = await Hive.openBox<dynamic>(_walletId);
-        final slateToAddresses = (await wallet.get("slate_to_address")) as Map?;
-        slateToAddresses?[txLogEntryFirst['tx_slate_id']] = txData['addresss'];
+        final slateToAddresses =
+            (await wallet.get("slate_to_address")) as Map? ?? {};
+        final slateId = txLogEntryFirst['tx_slate_id'] as String;
+        slateToAddresses[slateId] = txData['addresss'];
         await wallet.put('slate_to_address', slateToAddresses);
-        return txLogEntryFirst['tx_slate_id'] as String;
+        final slatesToCommits = await getSlatesToCommits();
+        String? commitId = slatesToCommits[slateId]?['commitId'] as String?;
+        Logging.instance.log("sent commitId: $commitId", level: LogLevel.Info);
+        return commitId!;
+        // return txLogEntryFirst['tx_slate_id'] as String;
       }
     } catch (e, s) {
       Logging.instance.log("Error sending $e - $s", level: LogLevel.Error);
@@ -2155,8 +2161,9 @@ class EpicCashWallet extends CoinServiceAPI {
               as String? ??
           "";
       String? commitId = slatesToCommits[slateId]?['commitId'] as String?;
-      Logging.instance
-          .log("commitId: $commitId $slateId", level: LogLevel.Info);
+      Logging.instance.log(
+          "commitId: $commitId, slateId: $slateId, id: ${tx["id"]}",
+          level: LogLevel.Info);
 
       bool isCancelled = tx["tx_type"] == "TxSentCancelled" ||
           tx["tx_type"] == "TxReceivedCancelled";

From 7c3d40782cbd024911e4626f6a0aa15d85290b79 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Tue, 8 Nov 2022 09:55:15 -0600
Subject: [PATCH 161/426] add generation tests and update flutter_libmonero ref

change seedWords to SeedWordsLength to match rest of codebase
---
 crypto_plugins/flutter_libmonero              |   2 +-
 .../coins/wownero/wownero_wallet.dart         |  20 +-
 .../coins/wownero/wownero_wallet_test.dart    | 172 ++++++++++++++----
 3 files changed, 147 insertions(+), 47 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index e95c19662..afdee4b88 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit e95c19662ccf17d83109ab7b651cfbc0521deb47
+Subproject commit afdee4b880202f39a2375afc320f0642e98a1827
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 1153a881a..a0dc7bfe0 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -647,7 +647,7 @@ class WowneroWallet extends CoinServiceAPI {
   }
 
   //TODO: take in the default language when creating wallet.
-  Future<void> _generateNewWallet() async {
+  Future<void> _generateNewWallet({int seedWordsLength = 14}) async {
     Logging.instance
         .log("IS_INTEGRATION_TEST: $integrationTestFlag", level: LogLevel.Info);
     // TODO: ping wownero server and make sure the genesis hash matches
@@ -687,6 +687,7 @@ class WowneroWallet extends CoinServiceAPI {
       credentials = wownero.createWowneroNewWalletCredentials(
         name: name,
         language: "English",
+        seedWordsLength: seedWordsLength
       );
 
       walletInfo = WalletInfo.external(
@@ -713,12 +714,12 @@ class WowneroWallet extends CoinServiceAPI {
       final wallet = await _walletCreationService?.create(credentials);
 
       // subtract a couple days to ensure we have a buffer for SWB
-      // 14 words
-      //final bufferedCreateHeight = getSeedHeightSync(wallet?.seed.trim() as String);
-
-      // 25 words
-      final bufferedCreateHeight = 0;
-      // TODO use an alternative to wow_seed's get_seed_height
+      if (seedWordsLength == 14) {
+        final bufferedCreateHeight = getSeedHeightSync(wallet?.seed.trim() as String);
+      } else {
+        final bufferedCreateHeight = 0;
+        // TODO use an alternative to wow_seed's get_seed_height
+      }
 
       await DB.instance.put<dynamic>(
           boxName: walletId, key: "restoreHeight", value: bufferedCreateHeight);
@@ -726,6 +727,7 @@ class WowneroWallet extends CoinServiceAPI {
 
       await _secureStore.write(
           key: '${_walletId}_mnemonic', value: wallet?.seed.trim());
+
       walletInfo.address = wallet?.walletAddresses.address;
       await DB.instance
           .add<WalletInfo>(boxName: WalletInfo.boxName, value: walletInfo);
@@ -782,7 +784,7 @@ class WowneroWallet extends CoinServiceAPI {
 
   @override
   // TODO: implement initializeWallet
-  Future<bool> initializeNew() async {
+  Future<bool> initializeNew({int seedWordsLength = 14}) async {
     await _prefs.init();
     // TODO: ping actual wownero network
     // try {
@@ -800,7 +802,7 @@ class WowneroWallet extends CoinServiceAPI {
     prefs = await SharedPreferences.getInstance();
     keysStorage = KeyService(storage!);
 
-    await _generateNewWallet();
+    await _generateNewWallet(seedWordsLength: seedWordsLength);
     // var password;
     // try {
     //   password =
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 2099df364..660bc1438 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -46,7 +46,7 @@ dynamic _walletInfoSource;
 
 String path = '';
 
-String name = 'namee${Random().nextInt(10000000)}';
+String name = '';
 int nettype = 0;
 WalletType type = WalletType.wownero;
 
@@ -83,10 +83,75 @@ void main() async {
   _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
   walletService = wownero.createWowneroWalletService(_walletInfoSource);
 
-  group("Wownero 14 word tests", () {
+  group("Wownero 14 word seed generation", () {
     setUp(() async {
       bool hasThrown = false;
       try {
+        name = 'namee${Random().nextInt(10000000)}';
+        final dirPath = await pathForWalletDir(name: name, type: type);
+        path = await pathForWallet(name: name, type: type);
+        credentials = wownero.createWowneroNewWalletCredentials(
+            name: name,
+            language: "English",
+            seedWordsLength: 14); // TODO catch failure
+
+        walletInfo = WalletInfo.external(
+            id: WalletBase.idFor(name, type),
+            name: name,
+            type: type,
+            isRecovery: false,
+            restoreHeight: credentials.height ?? 0,
+            date: DateTime.now(),
+            path: path,
+            address: "",
+            dirPath: dirPath);
+        credentials.walletInfo = walletInfo;
+
+        _walletCreationService = WalletCreationService(
+          secureStorage: storage,
+          sharedPreferences: prefs,
+          walletService: walletService,
+          keyService: keysStorage,
+        );
+        _walletCreationService.changeWalletType();
+      } catch (e, s) {
+        print(e);
+        print(s);
+        hasThrown = true;
+      }
+      expect(hasThrown, false);
+    });
+
+    test("Wownero 14 word seed address generation", () async {
+      final wallet = await _walletCreationService.create(credentials);
+      // TODO validate mnemonic
+      walletInfo.address = wallet.walletAddresses.address;
+
+      bool hasThrown = false;
+      try {
+        await _walletInfoSource.add(walletInfo);
+        walletBase?.close();
+        walletBase = wallet as WowneroWalletBase;
+
+        // TODO validate
+        //expect(walletInfo.address, mainnetTestData14[0][0]);
+      } catch (_) {
+        hasThrown = true;
+      }
+      expect(hasThrown, false);
+
+      walletBase?.close();
+      walletBase = wallet as WowneroWalletBase;
+    });
+
+    // TODO delete left over wallet file with name: name
+  });
+
+  group("Wownero 14 word seed restoration", () {
+    setUp(() async {
+      bool hasThrown = false;
+      try {
+        name = 'namee${Random().nextInt(10000000)}';
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
         credentials = wownero.createWowneroRestoreWalletFromSeedCredentials(
@@ -121,7 +186,7 @@ void main() async {
       expect(hasThrown, false);
     });
 
-    test("Test mainnet address generation from 14 word seed", () async {
+    test("Wownero 14 word seed address generation", () async {
       final wallet = await _walletCreationService.restoreFromSeed(credentials);
       walletInfo.address = wallet.walletAddresses.address;
 
@@ -156,7 +221,71 @@ void main() async {
     // TODO delete left over wallet file with name: name
   });
 
-  group("Wownero 25 word tests", () {
+  group("Wownero 25 word seed generation", () {
+    setUp(() async {
+      bool hasThrown = false;
+      try {
+        name = 'namee${Random().nextInt(10000000)}';
+        final dirPath = await pathForWalletDir(name: name, type: type);
+        path = await pathForWallet(name: name, type: type);
+        credentials = wownero.createWowneroNewWalletCredentials(
+            name: name,
+            language: "English",
+            seedWordsLength: 25); // TODO catch failure
+
+        walletInfo = WalletInfo.external(
+            id: WalletBase.idFor(name, type),
+            name: name,
+            type: type,
+            isRecovery: false,
+            restoreHeight: credentials.height ?? 0,
+            date: DateTime.now(),
+            path: path,
+            address: "",
+            dirPath: dirPath);
+        credentials.walletInfo = walletInfo;
+
+        _walletCreationService = WalletCreationService(
+          secureStorage: storage,
+          sharedPreferences: prefs,
+          walletService: walletService,
+          keyService: keysStorage,
+        );
+        _walletCreationService.changeWalletType();
+      } catch (e, s) {
+        print(e);
+        print(s);
+        hasThrown = true;
+      }
+      expect(hasThrown, false);
+    });
+
+    test("Wownero 25 word seed address generation", () async {
+      final wallet = await _walletCreationService.create(credentials);
+      // TODO validate mnemonic
+      walletInfo.address = wallet.walletAddresses.address;
+
+      bool hasThrown = false;
+      try {
+        await _walletInfoSource.add(walletInfo);
+        walletBase?.close();
+        walletBase = wallet as WowneroWalletBase;
+
+        // TODO validate
+        //expect(walletInfo.address, mainnetTestData14[0][0]);
+      } catch (_) {
+        hasThrown = true;
+      }
+      expect(hasThrown, false);
+
+      walletBase?.close();
+      walletBase = wallet as WowneroWalletBase;
+    });
+
+    // TODO delete left over wallet file with name: name
+  });
+
+  group("Wownero 25 word seed restoration", () {
     setUp(() async {
       bool hasThrown = false;
       try {
@@ -195,42 +324,11 @@ void main() async {
       expect(hasThrown, false);
     });
 
-    test("Test mainnet address generation from 25 word seed", () async {
-      bool hasThrown = false;
-      try {
-        final dirPath = await pathForWalletDir(name: name, type: type);
-        path = await pathForWallet(name: name, type: type);
-
-        walletInfo = WalletInfo.external(
-            id: WalletBase.idFor(name, type),
-            name: name,
-            type: type,
-            isRecovery: false,
-            restoreHeight: credentials.height ?? 0,
-            date: DateTime.now(),
-            path: path,
-            address: "",
-            dirPath: dirPath);
-        credentials.walletInfo = walletInfo;
-
-        _walletCreationService = WalletCreationService(
-          secureStorage: storage,
-          sharedPreferences: prefs,
-          walletService: walletService,
-          keyService: keysStorage,
-        );
-        _walletCreationService.changeWalletType();
-      } catch (e, s) {
-        print(e);
-        print(s);
-        hasThrown = true;
-      }
-      expect(hasThrown, false);
-
+    test("Wownero 25 word seed address generation", () async {
       final wallet = await _walletCreationService.restoreFromSeed(credentials);
       walletInfo.address = wallet.walletAddresses.address;
 
-      hasThrown = false;
+      bool hasThrown = false;
       try {
         await _walletInfoSource.add(walletInfo);
         walletBase?.close();

From f17785ffc7e81f187239881eed0e72da6d7fb8b2 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 8 Nov 2022 10:18:48 -0600
Subject: [PATCH 162/426] monero/wownero untrusted cert popup

---
 .../add_edit_node_view.dart                   |  24 +++-
 .../manage_nodes_views/node_details_view.dart |  24 +++-
 .../test_monero_node_connection.dart          | 115 +++++++++++++++---
 lib/widgets/node_card.dart                    |  24 +++-
 lib/widgets/node_options_sheet.dart           |  24 +++-
 5 files changed, 192 insertions(+), 19 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 87aee413e..382e3f09e 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -110,7 +110,29 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
               ref.read(nodeFormDataProvider).useSSL = false;
             }
 
-            testPassed = await testMoneroNodeConnection(Uri.parse(uriString));
+            final response = await testMoneroNodeConnection(
+              Uri.parse(uriString),
+              false,
+            );
+
+            if (response.cert != null) {
+              if (mounted) {
+                final shouldAllowBadCert = await showBadX509CertificateDialog(
+                  response.cert!,
+                  response.url!,
+                  response.port!,
+                  context,
+                );
+
+                if (shouldAllowBadCert) {
+                  final response = await testMoneroNodeConnection(
+                      Uri.parse(uriString), true);
+                  testPassed = response.success;
+                }
+              }
+            } else {
+              testPassed = response.success;
+            }
           }
         } catch (e, s) {
           Logging.instance.log("$e\n$s", level: LogLevel.Warning);
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index c5e666ce2..f9b64c460 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -97,7 +97,29 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
 
             String uriString = "${uri.scheme}://${uri.host}:${node.port}$path";
 
-            testPassed = await testMoneroNodeConnection(Uri.parse(uriString));
+            final response = await testMoneroNodeConnection(
+              Uri.parse(uriString),
+              false,
+            );
+
+            if (response.cert != null) {
+              if (mounted) {
+                final shouldAllowBadCert = await showBadX509CertificateDialog(
+                  response.cert!,
+                  response.url!,
+                  response.port!,
+                  context,
+                );
+
+                if (shouldAllowBadCert) {
+                  final response = await testMoneroNodeConnection(
+                      Uri.parse(uriString), true);
+                  testPassed = response.success;
+                }
+              }
+            } else {
+              testPassed = response.success;
+            }
           }
         } catch (e, s) {
           Logging.instance.log("$e\n$s", level: LogLevel.Warning);
diff --git a/lib/utilities/test_monero_node_connection.dart b/lib/utilities/test_monero_node_connection.dart
index 7cb01e8b1..92b645141 100644
--- a/lib/utilities/test_monero_node_connection.dart
+++ b/lib/utilities/test_monero_node_connection.dart
@@ -1,26 +1,111 @@
 import 'dart:convert';
+import 'dart:io';
 
-import 'package:http/http.dart' as http;
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/stack_dialog.dart';
 
-Future<bool> testMoneroNodeConnection(Uri uri) async {
+class MoneroNodeConnectionResponse {
+  final X509Certificate? cert;
+  final String? url;
+  final int? port;
+  final bool success;
+
+  MoneroNodeConnectionResponse(this.cert, this.url, this.port, this.success);
+}
+
+Future<MoneroNodeConnectionResponse> testMoneroNodeConnection(
+  Uri uri,
+  bool allowBadX509Certificate,
+) async {
+  final client = HttpClient();
+  MoneroNodeConnectionResponse? badCertResponse;
   try {
-    final client = http.Client();
-    final response = await client
-        .post(
-          uri,
-          headers: {'Content-Type': 'application/json'},
-          body: jsonEncode({"jsonrpc": "2.0", "id": "0", "method": "get_info"}),
-        )
-        .timeout(const Duration(milliseconds: 1200),
-            onTimeout: () async => http.Response('Error', 408));
+    client.badCertificateCallback = (cert, url, port) {
+      if (allowBadX509Certificate) {
+        return true;
+      }
 
-    final result = jsonDecode(response.body);
+      if (badCertResponse == null) {
+        badCertResponse = MoneroNodeConnectionResponse(cert, url, port, false);
+      } else {
+        return false;
+      }
+
+      return false;
+    };
+
+    final request = await client.postUrl(uri);
+
+    final body = utf8.encode(
+      jsonEncode({
+        "jsonrpc": "2.0",
+        "id": "0",
+        "method": "get_info",
+      }),
+    );
+
+    request.headers.add(
+      'Content-Length',
+      body.length.toString(),
+      preserveHeaderCase: true,
+    );
+    request.headers.set(
+      'Content-Type',
+      'application/json',
+      preserveHeaderCase: true,
+    );
+
+    request.add(body);
+
+    final response = await request.close();
+    final result = await response.transform(utf8.decoder).join();
     // TODO: json decoded without error so assume connection exists?
     // or we can check for certain values in the response to decide
-    return true;
+    return MoneroNodeConnectionResponse(null, null, null, true);
   } catch (e, s) {
-    Logging.instance.log("$e\n$s", level: LogLevel.Warning);
-    return false;
+    if (badCertResponse != null) {
+      return badCertResponse!;
+    } else {
+      Logging.instance.log("$e\n$s", level: LogLevel.Warning);
+      return MoneroNodeConnectionResponse(null, null, null, false);
+    }
+  } finally {
+    client.close(force: true);
   }
 }
+
+Future<bool> showBadX509CertificateDialog(
+  X509Certificate cert,
+  String url,
+  int port,
+  BuildContext context,
+) async {
+  final result = await showDialog<bool>(
+    context: context,
+    barrierDismissible: false,
+    builder: (context) {
+      return StackDialog(
+        title: "Untrusted X509Certificate",
+        message: "SHA1: ${Format.uint8listToString(cert.sha1)}",
+        leftButton: SecondaryButton(
+          label: "Cancel",
+          onPressed: () {
+            Navigator.of(context).pop(false);
+          },
+        ),
+        rightButton: PrimaryButton(
+          label: "Trust",
+          onPressed: () {
+            Navigator.of(context).pop(true);
+          },
+        ),
+      );
+    },
+  );
+
+  return result ?? false;
+}
diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart
index bf9d2746e..1da7e9012 100644
--- a/lib/widgets/node_card.dart
+++ b/lib/widgets/node_card.dart
@@ -110,7 +110,29 @@ class _NodeCardState extends ConsumerState<NodeCard> {
 
             String uriString = "${uri.scheme}://${uri.host}:${node.port}$path";
 
-            testPassed = await testMoneroNodeConnection(Uri.parse(uriString));
+            final response = await testMoneroNodeConnection(
+              Uri.parse(uriString),
+              false,
+            );
+
+            if (response.cert != null) {
+              if (mounted) {
+                final shouldAllowBadCert = await showBadX509CertificateDialog(
+                  response.cert!,
+                  response.url!,
+                  response.port!,
+                  context,
+                );
+
+                if (shouldAllowBadCert) {
+                  final response = await testMoneroNodeConnection(
+                      Uri.parse(uriString), true);
+                  testPassed = response.success;
+                }
+              }
+            } else {
+              testPassed = response.success;
+            }
           }
         } catch (e, s) {
           Logging.instance.log("$e\n$s", level: LogLevel.Warning);
diff --git a/lib/widgets/node_options_sheet.dart b/lib/widgets/node_options_sheet.dart
index a5345161c..7ffd290f3 100644
--- a/lib/widgets/node_options_sheet.dart
+++ b/lib/widgets/node_options_sheet.dart
@@ -93,7 +93,29 @@ class NodeOptionsSheet extends ConsumerWidget {
 
             String uriString = "${uri.scheme}://${uri.host}:${node.port}$path";
 
-            testPassed = await testMoneroNodeConnection(Uri.parse(uriString));
+            final response = await testMoneroNodeConnection(
+              Uri.parse(uriString),
+              false,
+            );
+
+            if (response.cert != null) {
+              // if (mounted) {
+              final shouldAllowBadCert = await showBadX509CertificateDialog(
+                response.cert!,
+                response.url!,
+                response.port!,
+                context,
+              );
+
+              if (shouldAllowBadCert) {
+                final response =
+                    await testMoneroNodeConnection(Uri.parse(uriString), true);
+                testPassed = response.success;
+              }
+              // }
+            } else {
+              testPassed = response.success;
+            }
           }
         } catch (e, s) {
           Logging.instance.log("$e\n$s", level: LogLevel.Warning);

From a8c3d5f1042b6b70888acca8db0020928faa4684 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 8 Nov 2022 11:41:12 -0600
Subject: [PATCH 163/426] format sha1 string

---
 lib/utilities/test_monero_node_connection.dart | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/lib/utilities/test_monero_node_connection.dart b/lib/utilities/test_monero_node_connection.dart
index 92b645141..5e35f9a03 100644
--- a/lib/utilities/test_monero_node_connection.dart
+++ b/lib/utilities/test_monero_node_connection.dart
@@ -84,13 +84,23 @@ Future<bool> showBadX509CertificateDialog(
   int port,
   BuildContext context,
 ) async {
+  final chars = Format.uint8listToString(cert.sha1)
+      .toUpperCase()
+      .characters
+      .toList(growable: false);
+
+  String sha1 = chars.sublist(0, 2).join();
+  for (int i = 2; i < chars.length; i += 2) {
+    sha1 += ":${chars.sublist(i, i + 2).join()}";
+  }
+
   final result = await showDialog<bool>(
     context: context,
     barrierDismissible: false,
     builder: (context) {
       return StackDialog(
         title: "Untrusted X509Certificate",
-        message: "SHA1: ${Format.uint8listToString(cert.sha1)}",
+        message: "SHA1:\n$sha1",
         leftButton: SecondaryButton(
           label: "Cancel",
           onPressed: () {

From e41f8088b02c8aeaac8caaebac27dcbe7cc1d893 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 8 Nov 2022 12:00:10 -0600
Subject: [PATCH 164/426] WIP: wownero 25 word seed option ui

---
 .../restore_options_view.dart                 | 36 +++++++++++++++----
 .../restore_wallet_view.dart                  |  5 +++
 .../coins/wownero/wownero_wallet.dart         | 10 +++++-
 lib/utilities/constants.dart                  |  6 +---
 4 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
index 76e74fa14..1ce5d713a 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
@@ -252,7 +252,11 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
               SizedBox(
                 height: isDesktop ? 40 : 24,
               ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 Text(
                   "Choose start date",
                   style: isDesktop
@@ -264,11 +268,19 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
                       : STextStyles.smallMed12(context),
                   textAlign: TextAlign.left,
                 ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 SizedBox(
                   height: isDesktop ? 16 : 8,
                 ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
 
                 // if (!isDesktop)
                 RestoreFromDatePicker(
@@ -278,11 +290,19 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
 
               // if (isDesktop)
               //   // TODO desktop date picker
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 const SizedBox(
                   height: 8,
                 ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 RoundedWhiteContainer(
                   child: Center(
                     child: Text(
@@ -299,7 +319,11 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
                     ),
                   ),
                 ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 SizedBox(
                   height: isDesktop ? 24 : 16,
                 ),
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
index def0724b5..a6b7e7e77 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
@@ -149,6 +149,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
     super.dispose();
   }
 
+  // TODO: check for wownero wordlist?
   bool _isValidMnemonicWord(String word) {
     // TODO: get the actual language
     if (widget.coin == Coin.monero) {
@@ -181,6 +182,10 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
       if (widget.coin == Coin.monero) {
         height = monero.getHeigthByDate(date: widget.restoreFromDate);
       }
+      // todo: wait until this implemented
+      // else if (widget.coin == Coin.wownero) {
+      //   height = wownero.getHeightByDate(date: widget.restoreFromDate);
+      // }
 
       // TODO: make more robust estimate of date maybe using https://explorer.epic.tech/api-index
       if (widget.coin == Coin.epicCash) {
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 72f43eac8..788f2f9d8 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -942,6 +942,11 @@ class WowneroWallet extends CoinServiceAPI {
     required int maxNumberOfIndexesToCheck,
     required int height,
   }) async {
+    final int seedLength = mnemonic.trim().split(" ").length;
+    if (!(seedLength == 14 || seedLength == 25)) {
+      throw Exception("Invalid wownero mnemonic length found: $seedLength");
+    }
+
     await _prefs.init();
     longMutex = true;
     final start = DateTime.now();
@@ -969,7 +974,10 @@ class WowneroWallet extends CoinServiceAPI {
       await _secureStore.write(
           key: '${_walletId}_mnemonic', value: mnemonic.trim());
 
-      height = getSeedHeightSync(mnemonic.trim());
+      // extract seed height from 14 word seed
+      if (seedLength == 14) {
+        height = getSeedHeightSync(mnemonic.trim());
+      }
 
       await DB.instance
           .put<dynamic>(boxName: walletId, key: "restoreHeight", value: height);
diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart
index 4fb3fb54b..e27fbaa3d 100644
--- a/lib/utilities/constants.dart
+++ b/lib/utilities/constants.dart
@@ -35,10 +35,6 @@ abstract class Constants {
 
   static const int pinLength = 4;
 
-  // enable testnet
-  // TODO: currently unused
-  static const bool allowTestnets = true;
-
   // Enable Logger.print statements
   static const bool disableLogger = false;
 
@@ -66,7 +62,7 @@ abstract class Constants {
         values.addAll([25]);
         break;
       case Coin.wownero:
-        values.addAll([14]);
+        values.addAll([14, 25]);
         break;
     }
     return values;

From 43deb9f81fa99d65318a116c1c835a0dc9f96f9e Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 7 Nov 2022 16:17:54 -0700
Subject: [PATCH 165/426] desktop about ui fix

---
 .../desktop_about_view.dart                   | 933 ++++++++++--------
 1 file changed, 497 insertions(+), 436 deletions(-)

diff --git a/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart b/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart
index 86fcf78e0..18988cb68 100644
--- a/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart
+++ b/lib/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart
@@ -140,262 +140,123 @@ class DesktopAboutView extends ConsumerWidget {
         children: [
           Padding(
             padding: const EdgeInsets.fromLTRB(24, 10, 24, 35),
-            child: RoundedWhiteContainer(
-              width: 929,
-              height: 411,
-              child: Padding(
-                padding: const EdgeInsets.only(left: 10, top: 10),
-                child: Column(
-                  // mainAxisAlignment: MainAxisAlignment.start,
-                  children: [
-                    Row(
-                      mainAxisAlignment: MainAxisAlignment.start,
-                      children: [
-                        Text(
-                          "Stack Wallet",
-                          style: STextStyles.desktopH3(context),
-                          textAlign: TextAlign.start,
-                        ),
-                      ],
-                    ),
-                    const SizedBox(height: 16),
-                    Row(
-                      children: [
-                        RichText(
-                          textAlign: TextAlign.start,
-                          text: TextSpan(
-                            style: STextStyles.label(context),
+            child: Row(
+              children: [
+                Expanded(
+                  child: RoundedWhiteContainer(
+                    width: 929,
+                    height: 411,
+                    child: Padding(
+                      padding: const EdgeInsets.only(left: 10, top: 10),
+                      child: Column(
+                        // mainAxisAlignment: MainAxisAlignment.start,
+                        children: [
+                          Row(
+                            mainAxisAlignment: MainAxisAlignment.start,
                             children: [
-                              TextSpan(
-                                text:
-                                    "By using Stack Wallet, you agree to the ",
-                                style: STextStyles.desktopTextExtraExtraSmall(
-                                        context)
-                                    .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textDark3),
-                              ),
-                              TextSpan(
-                                text: "Terms of service",
-                                style: STextStyles.richLink(context)
-                                    .copyWith(fontSize: 14),
-                                recognizer: TapGestureRecognizer()
-                                  ..onTap = () {
-                                    launchUrl(
-                                      Uri.parse(
-                                          "https://stackwallet.com/terms-of-service.html"),
-                                      mode: LaunchMode.externalApplication,
-                                    );
-                                  },
-                              ),
-                              TextSpan(
-                                text: " and ",
-                                style: STextStyles.desktopTextExtraExtraSmall(
-                                        context)
-                                    .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textDark3),
-                              ),
-                              TextSpan(
-                                text: "Privacy policy",
-                                style: STextStyles.richLink(context)
-                                    .copyWith(fontSize: 14),
-                                recognizer: TapGestureRecognizer()
-                                  ..onTap = () {
-                                    launchUrl(
-                                      Uri.parse(
-                                          "https://stackwallet.com/privacy-policy.html"),
-                                      mode: LaunchMode.externalApplication,
-                                    );
-                                  },
+                              Text(
+                                "Stack Wallet",
+                                style: STextStyles.desktopH3(context),
+                                textAlign: TextAlign.start,
                               ),
                             ],
                           ),
-                        ),
-                      ],
-                    ),
-                    const SizedBox(height: 32),
-                    Padding(
-                      padding: const EdgeInsets.only(right: 10, bottom: 10),
-                      child: Column(
-                        children: [
-                          FutureBuilder(
-                            future: PackageInfo.fromPlatform(),
-                            builder:
-                                (context, AsyncSnapshot<PackageInfo> snapshot) {
-                              String version = "";
-                              String signature = "";
-                              String build = "";
+                          const SizedBox(height: 16),
+                          Row(
+                            children: [
+                              RichText(
+                                textAlign: TextAlign.start,
+                                text: TextSpan(
+                                  style: STextStyles.label(context),
+                                  children: [
+                                    TextSpan(
+                                      text:
+                                          "By using Stack Wallet, you agree to the ",
+                                      style: STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark3),
+                                    ),
+                                    TextSpan(
+                                      text: "Terms of service",
+                                      style: STextStyles.richLink(context)
+                                          .copyWith(fontSize: 14),
+                                      recognizer: TapGestureRecognizer()
+                                        ..onTap = () {
+                                          launchUrl(
+                                            Uri.parse(
+                                                "https://stackwallet.com/terms-of-service.html"),
+                                            mode:
+                                                LaunchMode.externalApplication,
+                                          );
+                                        },
+                                    ),
+                                    TextSpan(
+                                      text: " and ",
+                                      style: STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark3),
+                                    ),
+                                    TextSpan(
+                                      text: "Privacy policy",
+                                      style: STextStyles.richLink(context)
+                                          .copyWith(fontSize: 14),
+                                      recognizer: TapGestureRecognizer()
+                                        ..onTap = () {
+                                          launchUrl(
+                                            Uri.parse(
+                                                "https://stackwallet.com/privacy-policy.html"),
+                                            mode:
+                                                LaunchMode.externalApplication,
+                                          );
+                                        },
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            ],
+                          ),
+                          const SizedBox(height: 32),
+                          Padding(
+                            padding:
+                                const EdgeInsets.only(right: 10, bottom: 10),
+                            child: Column(
+                              children: [
+                                FutureBuilder(
+                                  future: PackageInfo.fromPlatform(),
+                                  builder: (context,
+                                      AsyncSnapshot<PackageInfo> snapshot) {
+                                    String version = "";
+                                    String signature = "";
+                                    String build = "";
 
-                              if (snapshot.connectionState ==
-                                      ConnectionState.done &&
-                                  snapshot.hasData) {
-                                version = snapshot.data!.version;
-                                build = snapshot.data!.buildNumber;
-                                signature = snapshot.data!.buildSignature;
-                              }
+                                    if (snapshot.connectionState ==
+                                            ConnectionState.done &&
+                                        snapshot.hasData) {
+                                      version = snapshot.data!.version;
+                                      build = snapshot.data!.buildNumber;
+                                      signature = snapshot.data!.buildSignature;
+                                    }
 
-                              return Column(
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
-                                children: [
-                                  Row(
-                                    children: [
-                                      Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
-                                        children: [
-                                          Text(
-                                            "Version",
-                                            style: STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark),
-                                          ),
-                                          const SizedBox(
-                                            height: 2,
-                                          ),
-                                          SelectableText(
-                                            version,
-                                            style: STextStyles.itemSubtitle(
-                                                context),
-                                          ),
-                                        ],
-                                      ),
-                                      const SizedBox(
-                                        width: 400,
-                                      ),
-                                      Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
-                                        children: [
-                                          Text(
-                                            "Build number",
-                                            style: STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark),
-                                          ),
-                                          const SizedBox(
-                                            height: 2,
-                                          ),
-                                          SelectableText(
-                                            build,
-                                            style: STextStyles.itemSubtitle(
-                                                context),
-                                          ),
-                                        ],
-                                      ),
-                                    ],
-                                  ),
-                                  const SizedBox(height: 32),
-                                  Row(
-                                    children: [
-                                      Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
-                                        children: [
-                                          Text(
-                                            "Build signature",
-                                            style: STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark),
-                                          ),
-                                          const SizedBox(
-                                            height: 2,
-                                          ),
-                                          SelectableText(
-                                            signature,
-                                            style: STextStyles.itemSubtitle(
-                                                context),
-                                          ),
-                                        ],
-                                      ),
-                                      const SizedBox(
-                                        width: 350,
-                                      ),
-                                      FutureBuilder(
-                                          future: commitFiroFuture,
-                                          builder: (context,
-                                              AsyncSnapshot<dynamic> snapshot) {
-                                            bool commitExists = false;
-                                            bool isHead = false;
-                                            CommitStatus stateOfCommit =
-                                                CommitStatus.notLoaded;
-
-                                            if (snapshot.connectionState ==
-                                                    ConnectionState.done &&
-                                                snapshot.hasData) {
-                                              commitExists =
-                                                  snapshot.data![0] as bool;
-                                              isHead =
-                                                  snapshot.data![1] as bool;
-                                              if (commitExists && isHead) {
-                                                stateOfCommit =
-                                                    CommitStatus.isHead;
-                                              } else if (commitExists) {
-                                                stateOfCommit =
-                                                    CommitStatus.isOldCommit;
-                                              } else {
-                                                stateOfCommit =
-                                                    CommitStatus.notACommit;
-                                              }
-                                            }
-                                            TextStyle indicationStyle =
-                                                STextStyles.itemSubtitle(
-                                                    context);
-                                            switch (stateOfCommit) {
-                                              case CommitStatus.isHead:
-                                                indicationStyle = STextStyles
-                                                        .itemSubtitle(context)
-                                                    .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .accentColorGreen);
-                                                break;
-                                              case CommitStatus.isOldCommit:
-                                                indicationStyle = STextStyles
-                                                        .itemSubtitle(context)
-                                                    .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .accentColorYellow);
-                                                break;
-                                              case CommitStatus.notACommit:
-                                                indicationStyle = STextStyles
-                                                        .itemSubtitle(context)
-                                                    .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .accentColorRed);
-                                                break;
-                                              default:
-                                                break;
-                                            }
-                                            return Column(
+                                    return Column(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceBetween,
+                                      children: [
+                                        Row(
+                                          children: [
+                                            Column(
                                               crossAxisAlignment:
                                                   CrossAxisAlignment.start,
                                               children: [
                                                 Text(
-                                                  "Firo Build Commit",
+                                                  "Version",
                                                   style: STextStyles
                                                           .desktopTextExtraExtraSmall(
                                                               context)
@@ -410,84 +271,22 @@ class DesktopAboutView extends ConsumerWidget {
                                                   height: 2,
                                                 ),
                                                 SelectableText(
-                                                  firoCommit,
-                                                  style: indicationStyle,
+                                                  version,
+                                                  style:
+                                                      STextStyles.itemSubtitle(
+                                                          context),
                                                 ),
                                               ],
-                                            );
-                                          }),
-                                    ],
-                                  ),
-                                  const SizedBox(height: 35),
-                                  Row(
-                                    children: [
-                                      FutureBuilder(
-                                          future: commitEpicFuture,
-                                          builder: (context,
-                                              AsyncSnapshot<dynamic> snapshot) {
-                                            bool commitExists = false;
-                                            bool isHead = false;
-                                            CommitStatus stateOfCommit =
-                                                CommitStatus.notLoaded;
-
-                                            if (snapshot.connectionState ==
-                                                    ConnectionState.done &&
-                                                snapshot.hasData) {
-                                              commitExists =
-                                                  snapshot.data![0] as bool;
-                                              isHead =
-                                                  snapshot.data![1] as bool;
-                                              if (commitExists && isHead) {
-                                                stateOfCommit =
-                                                    CommitStatus.isHead;
-                                              } else if (commitExists) {
-                                                stateOfCommit =
-                                                    CommitStatus.isOldCommit;
-                                              } else {
-                                                stateOfCommit =
-                                                    CommitStatus.notACommit;
-                                              }
-                                            }
-                                            TextStyle indicationStyle =
-                                                STextStyles.itemSubtitle(
-                                                    context);
-                                            switch (stateOfCommit) {
-                                              case CommitStatus.isHead:
-                                                indicationStyle = STextStyles
-                                                        .itemSubtitle(context)
-                                                    .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .accentColorGreen);
-                                                break;
-                                              case CommitStatus.isOldCommit:
-                                                indicationStyle = STextStyles
-                                                        .itemSubtitle(context)
-                                                    .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .accentColorYellow);
-                                                break;
-                                              case CommitStatus.notACommit:
-                                                indicationStyle = STextStyles
-                                                        .itemSubtitle(context)
-                                                    .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .accentColorRed);
-                                                break;
-                                              default:
-                                                break;
-                                            }
-                                            return Column(
+                                            ),
+                                            const SizedBox(
+                                              width: 400,
+                                            ),
+                                            Column(
                                               crossAxisAlignment:
                                                   CrossAxisAlignment.start,
                                               children: [
                                                 Text(
-                                                  "Epic Cash Build Commit",
+                                                  "Build number",
                                                   style: STextStyles
                                                           .desktopTextExtraExtraSmall(
                                                               context)
@@ -502,82 +301,24 @@ class DesktopAboutView extends ConsumerWidget {
                                                   height: 2,
                                                 ),
                                                 SelectableText(
-                                                  epicCashCommit,
-                                                  style: indicationStyle,
+                                                  build,
+                                                  style:
+                                                      STextStyles.itemSubtitle(
+                                                          context),
                                                 ),
                                               ],
-                                            );
-                                          }),
-                                      const SizedBox(
-                                        width: 105,
-                                      ),
-                                      FutureBuilder(
-                                          future: commitMoneroFuture,
-                                          builder: (context,
-                                              AsyncSnapshot<dynamic> snapshot) {
-                                            bool commitExists = false;
-                                            bool isHead = false;
-                                            CommitStatus stateOfCommit =
-                                                CommitStatus.notLoaded;
-
-                                            if (snapshot.connectionState ==
-                                                    ConnectionState.done &&
-                                                snapshot.hasData) {
-                                              commitExists =
-                                                  snapshot.data![0] as bool;
-                                              isHead =
-                                                  snapshot.data![1] as bool;
-                                              if (commitExists && isHead) {
-                                                stateOfCommit =
-                                                    CommitStatus.isHead;
-                                              } else if (commitExists) {
-                                                stateOfCommit =
-                                                    CommitStatus.isOldCommit;
-                                              } else {
-                                                stateOfCommit =
-                                                    CommitStatus.notACommit;
-                                              }
-                                            }
-                                            TextStyle indicationStyle =
-                                                STextStyles.itemSubtitle(
-                                                    context);
-                                            switch (stateOfCommit) {
-                                              case CommitStatus.isHead:
-                                                indicationStyle = STextStyles
-                                                        .itemSubtitle(context)
-                                                    .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .accentColorGreen);
-                                                break;
-                                              case CommitStatus.isOldCommit:
-                                                indicationStyle = STextStyles
-                                                        .itemSubtitle(context)
-                                                    .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .accentColorYellow);
-                                                break;
-                                              case CommitStatus.notACommit:
-                                                indicationStyle = STextStyles
-                                                        .itemSubtitle(context)
-                                                    .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .accentColorRed);
-                                                break;
-                                              default:
-                                                break;
-                                            }
-                                            return Column(
+                                            ),
+                                          ],
+                                        ),
+                                        const SizedBox(height: 32),
+                                        Row(
+                                          children: [
+                                            Column(
                                               crossAxisAlignment:
                                                   CrossAxisAlignment.start,
                                               children: [
                                                 Text(
-                                                  "Monero Build Commit",
+                                                  "Build signature",
                                                   style: STextStyles
                                                           .desktopTextExtraExtraSmall(
                                                               context)
@@ -592,60 +333,380 @@ class DesktopAboutView extends ConsumerWidget {
                                                   height: 2,
                                                 ),
                                                 SelectableText(
-                                                  moneroCommit,
-                                                  style: indicationStyle,
+                                                  signature,
+                                                  style:
+                                                      STextStyles.itemSubtitle(
+                                                          context),
                                                 ),
                                               ],
-                                            );
-                                          }),
-                                    ],
-                                  ),
-                                  const SizedBox(height: 35),
-                                  Row(
-                                    children: [
-                                      Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
-                                        children: [
-                                          Text(
-                                            "Website",
-                                            style: STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark),
-                                          ),
-                                          const SizedBox(
-                                            height: 2,
-                                          ),
-                                          BlueTextButton(
-                                            text: "https://stackwallet.com",
-                                            onTap: () {
-                                              launchUrl(
-                                                Uri.parse(
-                                                    "https://stackwallet.com"),
-                                                mode: LaunchMode
-                                                    .externalApplication,
-                                              );
-                                            },
-                                          ),
-                                        ],
-                                      )
-                                    ],
-                                  )
-                                ],
-                              );
-                            },
+                                            ),
+                                            const SizedBox(
+                                              width: 350,
+                                            ),
+                                            FutureBuilder(
+                                                future: commitFiroFuture,
+                                                builder: (context,
+                                                    AsyncSnapshot<dynamic>
+                                                        snapshot) {
+                                                  bool commitExists = false;
+                                                  bool isHead = false;
+                                                  CommitStatus stateOfCommit =
+                                                      CommitStatus.notLoaded;
+
+                                                  if (snapshot.connectionState ==
+                                                          ConnectionState
+                                                              .done &&
+                                                      snapshot.hasData) {
+                                                    commitExists = snapshot
+                                                        .data![0] as bool;
+                                                    isHead = snapshot.data![1]
+                                                        as bool;
+                                                    if (commitExists &&
+                                                        isHead) {
+                                                      stateOfCommit =
+                                                          CommitStatus.isHead;
+                                                    } else if (commitExists) {
+                                                      stateOfCommit =
+                                                          CommitStatus
+                                                              .isOldCommit;
+                                                    } else {
+                                                      stateOfCommit =
+                                                          CommitStatus
+                                                              .notACommit;
+                                                    }
+                                                  }
+                                                  TextStyle indicationStyle =
+                                                      STextStyles.itemSubtitle(
+                                                          context);
+                                                  switch (stateOfCommit) {
+                                                    case CommitStatus.isHead:
+                                                      indicationStyle = STextStyles
+                                                              .itemSubtitle(
+                                                                  context)
+                                                          .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .accentColorGreen);
+                                                      break;
+                                                    case CommitStatus
+                                                        .isOldCommit:
+                                                      indicationStyle = STextStyles
+                                                              .itemSubtitle(
+                                                                  context)
+                                                          .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .accentColorYellow);
+                                                      break;
+                                                    case CommitStatus
+                                                        .notACommit:
+                                                      indicationStyle = STextStyles
+                                                              .itemSubtitle(
+                                                                  context)
+                                                          .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .accentColorRed);
+                                                      break;
+                                                    default:
+                                                      break;
+                                                  }
+                                                  return Column(
+                                                    crossAxisAlignment:
+                                                        CrossAxisAlignment
+                                                            .start,
+                                                    children: [
+                                                      Text(
+                                                        "Firo Build Commit",
+                                                        style: STextStyles
+                                                                .desktopTextExtraExtraSmall(
+                                                                    context)
+                                                            .copyWith(
+                                                                color: Theme.of(
+                                                                        context)
+                                                                    .extension<
+                                                                        StackColors>()!
+                                                                    .textDark),
+                                                      ),
+                                                      const SizedBox(
+                                                        height: 2,
+                                                      ),
+                                                      SelectableText(
+                                                        firoCommit,
+                                                        style: indicationStyle,
+                                                      ),
+                                                    ],
+                                                  );
+                                                }),
+                                          ],
+                                        ),
+                                        const SizedBox(height: 35),
+                                        Row(
+                                          children: [
+                                            FutureBuilder(
+                                                future: commitEpicFuture,
+                                                builder: (context,
+                                                    AsyncSnapshot<dynamic>
+                                                        snapshot) {
+                                                  bool commitExists = false;
+                                                  bool isHead = false;
+                                                  CommitStatus stateOfCommit =
+                                                      CommitStatus.notLoaded;
+
+                                                  if (snapshot.connectionState ==
+                                                          ConnectionState
+                                                              .done &&
+                                                      snapshot.hasData) {
+                                                    commitExists = snapshot
+                                                        .data![0] as bool;
+                                                    isHead = snapshot.data![1]
+                                                        as bool;
+                                                    if (commitExists &&
+                                                        isHead) {
+                                                      stateOfCommit =
+                                                          CommitStatus.isHead;
+                                                    } else if (commitExists) {
+                                                      stateOfCommit =
+                                                          CommitStatus
+                                                              .isOldCommit;
+                                                    } else {
+                                                      stateOfCommit =
+                                                          CommitStatus
+                                                              .notACommit;
+                                                    }
+                                                  }
+                                                  TextStyle indicationStyle =
+                                                      STextStyles.itemSubtitle(
+                                                          context);
+                                                  switch (stateOfCommit) {
+                                                    case CommitStatus.isHead:
+                                                      indicationStyle = STextStyles
+                                                              .itemSubtitle(
+                                                                  context)
+                                                          .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .accentColorGreen);
+                                                      break;
+                                                    case CommitStatus
+                                                        .isOldCommit:
+                                                      indicationStyle = STextStyles
+                                                              .itemSubtitle(
+                                                                  context)
+                                                          .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .accentColorYellow);
+                                                      break;
+                                                    case CommitStatus
+                                                        .notACommit:
+                                                      indicationStyle = STextStyles
+                                                              .itemSubtitle(
+                                                                  context)
+                                                          .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .accentColorRed);
+                                                      break;
+                                                    default:
+                                                      break;
+                                                  }
+                                                  return Column(
+                                                    crossAxisAlignment:
+                                                        CrossAxisAlignment
+                                                            .start,
+                                                    children: [
+                                                      Text(
+                                                        "Epic Cash Build Commit",
+                                                        style: STextStyles
+                                                                .desktopTextExtraExtraSmall(
+                                                                    context)
+                                                            .copyWith(
+                                                                color: Theme.of(
+                                                                        context)
+                                                                    .extension<
+                                                                        StackColors>()!
+                                                                    .textDark),
+                                                      ),
+                                                      const SizedBox(
+                                                        height: 2,
+                                                      ),
+                                                      SelectableText(
+                                                        epicCashCommit,
+                                                        style: indicationStyle,
+                                                      ),
+                                                    ],
+                                                  );
+                                                }),
+                                            const SizedBox(
+                                              width: 105,
+                                            ),
+                                            FutureBuilder(
+                                                future: commitMoneroFuture,
+                                                builder: (context,
+                                                    AsyncSnapshot<dynamic>
+                                                        snapshot) {
+                                                  bool commitExists = false;
+                                                  bool isHead = false;
+                                                  CommitStatus stateOfCommit =
+                                                      CommitStatus.notLoaded;
+
+                                                  if (snapshot.connectionState ==
+                                                          ConnectionState
+                                                              .done &&
+                                                      snapshot.hasData) {
+                                                    commitExists = snapshot
+                                                        .data![0] as bool;
+                                                    isHead = snapshot.data![1]
+                                                        as bool;
+                                                    if (commitExists &&
+                                                        isHead) {
+                                                      stateOfCommit =
+                                                          CommitStatus.isHead;
+                                                    } else if (commitExists) {
+                                                      stateOfCommit =
+                                                          CommitStatus
+                                                              .isOldCommit;
+                                                    } else {
+                                                      stateOfCommit =
+                                                          CommitStatus
+                                                              .notACommit;
+                                                    }
+                                                  }
+                                                  TextStyle indicationStyle =
+                                                      STextStyles.itemSubtitle(
+                                                          context);
+                                                  switch (stateOfCommit) {
+                                                    case CommitStatus.isHead:
+                                                      indicationStyle = STextStyles
+                                                              .itemSubtitle(
+                                                                  context)
+                                                          .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .accentColorGreen);
+                                                      break;
+                                                    case CommitStatus
+                                                        .isOldCommit:
+                                                      indicationStyle = STextStyles
+                                                              .itemSubtitle(
+                                                                  context)
+                                                          .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .accentColorYellow);
+                                                      break;
+                                                    case CommitStatus
+                                                        .notACommit:
+                                                      indicationStyle = STextStyles
+                                                              .itemSubtitle(
+                                                                  context)
+                                                          .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .accentColorRed);
+                                                      break;
+                                                    default:
+                                                      break;
+                                                  }
+                                                  return Column(
+                                                    crossAxisAlignment:
+                                                        CrossAxisAlignment
+                                                            .start,
+                                                    children: [
+                                                      Text(
+                                                        "Monero Build Commit",
+                                                        style: STextStyles
+                                                                .desktopTextExtraExtraSmall(
+                                                                    context)
+                                                            .copyWith(
+                                                                color: Theme.of(
+                                                                        context)
+                                                                    .extension<
+                                                                        StackColors>()!
+                                                                    .textDark),
+                                                      ),
+                                                      const SizedBox(
+                                                        height: 2,
+                                                      ),
+                                                      SelectableText(
+                                                        moneroCommit,
+                                                        style: indicationStyle,
+                                                      ),
+                                                    ],
+                                                  );
+                                                }),
+                                          ],
+                                        ),
+                                        const SizedBox(height: 35),
+                                        Row(
+                                          children: [
+                                            Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.start,
+                                              children: [
+                                                Text(
+                                                  "Website",
+                                                  style: STextStyles
+                                                          .desktopTextExtraExtraSmall(
+                                                              context)
+                                                      .copyWith(
+                                                          color: Theme.of(
+                                                                  context)
+                                                              .extension<
+                                                                  StackColors>()!
+                                                              .textDark),
+                                                ),
+                                                const SizedBox(
+                                                  height: 2,
+                                                ),
+                                                BlueTextButton(
+                                                  text:
+                                                      "https://stackwallet.com",
+                                                  onTap: () {
+                                                    launchUrl(
+                                                      Uri.parse(
+                                                          "https://stackwallet.com"),
+                                                      mode: LaunchMode
+                                                          .externalApplication,
+                                                    );
+                                                  },
+                                                ),
+                                              ],
+                                            )
+                                          ],
+                                        )
+                                      ],
+                                    );
+                                  },
+                                )
+                              ],
+                            ),
                           )
                         ],
                       ),
-                    )
-                  ],
+                    ),
+                  ),
                 ),
-              ),
+              ],
             ),
           ),
         ],

From 543f9631d845838c1cab2e39fc38e9f077e7d4a9 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 8 Nov 2022 09:34:47 -0700
Subject: [PATCH 166/426] changed desktop textbox fontsize

---
 .../stack_backup_views/create_backup_view.dart                | 4 ++++
 .../stack_backup_views/restore_from_file_view.dart            | 2 ++
 .../backup_and_restore/backup_and_restore_settings.dart       | 2 +-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 30fcb7962..48f1a1b7f 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -272,6 +272,8 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                   passwordFocusNode,
                   context,
                 ).copyWith(
+                  labelStyle:
+                      isDesktop ? STextStyles.fieldLabel(context) : null,
                   suffixIcon: UnconstrainedBox(
                     child: Row(
                       children: [
@@ -403,6 +405,8 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                   passwordRepeatFocusNode,
                   context,
                 ).copyWith(
+                  labelStyle:
+                      isDesktop ? STextStyles.fieldLabel(context) : null,
                   suffixIcon: UnconstrainedBox(
                     child: Row(
                       children: [
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index 0c101d0b3..c73d596f0 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -245,6 +245,8 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                     passwordFocusNode,
                     context,
                   ).copyWith(
+                    labelStyle:
+                        isDesktop ? STextStyles.fieldLabel(context) : null,
                     suffixIcon: UnconstrainedBox(
                       child: Row(
                         children: [
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 49debf22f..8928a268d 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -269,7 +269,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                             crossAxisAlignment: CrossAxisAlignment.start,
                             children: [
                               Padding(
-                                padding: EdgeInsets.all(
+                                padding: const EdgeInsets.all(
                                   10,
                                 ),
                                 child: restoreBackup

From eea5225ba5c05a4c0cae4607cb8522b85a1cdc56 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 8 Nov 2022 10:07:38 -0700
Subject: [PATCH 167/426] button correction for desktop manual backup

---
 .../create_backup_view.dart                   | 356 ++++++++++++------
 1 file changed, 239 insertions(+), 117 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 48f1a1b7f..51a1d7218 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -158,24 +158,24 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                 ),
               ),
               child,
-              const SizedBox(height: 20),
-              Row(
-                children: [
-                  PrimaryButton(
-                    desktopMed: true,
-                    width: 200,
-                    label: "Create backup",
-                    onPressed: () {},
-                  ),
-                  const SizedBox(width: 16),
-                  SecondaryButton(
-                    desktopMed: true,
-                    width: 200,
-                    label: "Cancel",
-                    onPressed: () {},
-                  ),
-                ],
-              ),
+              // const SizedBox(height: 20),
+              // Row(
+              //   children: [
+              //     PrimaryButton(
+              //       desktopMed: true,
+              //       width: 200,
+              //       label: "Create backup",
+              //       onPressed: () {},
+              //     ),
+              //     const SizedBox(width: 16),
+              //     SecondaryButton(
+              //       desktopMed: true,
+              //       width: 200,
+              //       label: "Cancel",
+              //       onPressed: () {},
+              //     ),
+              //   ],
+              // ),
             ],
           );
         },
@@ -447,112 +447,234 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
               height: 16,
             ),
             if (!isDesktop) const Spacer(),
-            TextButton(
-              style: shouldEnableCreate
-                  ? Theme.of(context)
-                      .extension<StackColors>()!
-                      .getPrimaryEnabledButtonColor(context)
-                  : Theme.of(context)
-                      .extension<StackColors>()!
-                      .getPrimaryDisabledButtonColor(context),
-              onPressed: !shouldEnableCreate
-                  ? null
-                  : () async {
-                      final String pathToSave = fileLocationController.text;
-                      final String passphrase = passwordController.text;
-                      final String repeatPassphrase =
-                          passwordRepeatController.text;
+            !isDesktop
+                ? TextButton(
+                    style: shouldEnableCreate
+                        ? Theme.of(context)
+                            .extension<StackColors>()!
+                            .getPrimaryEnabledButtonColor(context)
+                        : Theme.of(context)
+                            .extension<StackColors>()!
+                            .getPrimaryDisabledButtonColor(context),
+                    onPressed: !shouldEnableCreate
+                        ? null
+                        : () async {
+                            final String pathToSave =
+                                fileLocationController.text;
+                            final String passphrase = passwordController.text;
+                            final String repeatPassphrase =
+                                passwordRepeatController.text;
 
-                      if (pathToSave.isEmpty) {
-                        unawaited(showFloatingFlushBar(
-                          type: FlushBarType.warning,
-                          message: "Directory not chosen",
-                          context: context,
-                        ));
-                        return;
-                      }
-                      if (!(await Directory(pathToSave).exists())) {
-                        unawaited(showFloatingFlushBar(
-                          type: FlushBarType.warning,
-                          message: "Directory does not exist",
-                          context: context,
-                        ));
-                        return;
-                      }
-                      if (passphrase.isEmpty) {
-                        unawaited(showFloatingFlushBar(
-                          type: FlushBarType.warning,
-                          message: "A passphrase is required",
-                          context: context,
-                        ));
-                        return;
-                      }
-                      if (passphrase != repeatPassphrase) {
-                        unawaited(showFloatingFlushBar(
-                          type: FlushBarType.warning,
-                          message: "Passphrase does not match",
-                          context: context,
-                        ));
-                        return;
-                      }
+                            if (pathToSave.isEmpty) {
+                              unawaited(showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "Directory not chosen",
+                                context: context,
+                              ));
+                              return;
+                            }
+                            if (!(await Directory(pathToSave).exists())) {
+                              unawaited(showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "Directory does not exist",
+                                context: context,
+                              ));
+                              return;
+                            }
+                            if (passphrase.isEmpty) {
+                              unawaited(showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "A passphrase is required",
+                                context: context,
+                              ));
+                              return;
+                            }
+                            if (passphrase != repeatPassphrase) {
+                              unawaited(showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "Passphrase does not match",
+                                context: context,
+                              ));
+                              return;
+                            }
 
-                      unawaited(showDialog<dynamic>(
-                        context: context,
-                        barrierDismissible: false,
-                        builder: (_) => const StackDialog(
-                          title: "Encrypting backup",
-                          message: "This shouldn't take long",
-                        ),
-                      ));
-                      // make sure the dialog is able to be displayed for at least 1 second
-                      await Future<void>.delayed(const Duration(seconds: 1));
+                            unawaited(showDialog<dynamic>(
+                              context: context,
+                              barrierDismissible: false,
+                              builder: (_) => const StackDialog(
+                                title: "Encrypting backup",
+                                message: "This shouldn't take long",
+                              ),
+                            ));
+                            // make sure the dialog is able to be displayed for at least 1 second
+                            await Future<void>.delayed(
+                                const Duration(seconds: 1));
 
-                      final DateTime now = DateTime.now();
-                      final String fileToSave =
-                          "$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
+                            final DateTime now = DateTime.now();
+                            final String fileToSave =
+                                "$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
 
-                      final backup = await SWB.createStackWalletJSON();
+                            final backup = await SWB.createStackWalletJSON();
 
-                      bool result = await SWB.encryptStackWalletWithPassphrase(
-                        fileToSave,
-                        passphrase,
-                        jsonEncode(backup),
-                      );
+                            bool result =
+                                await SWB.encryptStackWalletWithPassphrase(
+                              fileToSave,
+                              passphrase,
+                              jsonEncode(backup),
+                            );
 
-                      if (mounted) {
-                        // pop encryption progress dialog
-                        Navigator.of(context).pop();
+                            if (mounted) {
+                              // pop encryption progress dialog
+                              Navigator.of(context).pop();
 
-                        if (result) {
-                          await showDialog<dynamic>(
-                            context: context,
-                            barrierDismissible: false,
-                            builder: (_) => Platform.isAndroid
-                                ? StackOkDialog(
-                                    title: "Backup saved to:",
-                                    message: fileToSave,
-                                  )
-                                : const StackOkDialog(
-                                    title: "Backup creation succeeded"),
-                          );
-                          passwordController.text = "";
-                          passwordRepeatController.text = "";
-                          setState(() {});
-                        } else {
-                          await showDialog<dynamic>(
-                            context: context,
-                            barrierDismissible: false,
-                            builder: (_) => const StackOkDialog(
-                                title: "Backup creation failed"),
-                          );
-                        }
-                      }
-                    },
-              child: Text(
-                "Create backup",
-                style: STextStyles.button(context),
-              ),
-            ),
+                              if (result) {
+                                await showDialog<dynamic>(
+                                  context: context,
+                                  barrierDismissible: false,
+                                  builder: (_) => Platform.isAndroid
+                                      ? StackOkDialog(
+                                          title: "Backup saved to:",
+                                          message: fileToSave,
+                                        )
+                                      : const StackOkDialog(
+                                          title: "Backup creation succeeded"),
+                                );
+                                passwordController.text = "";
+                                passwordRepeatController.text = "";
+                                setState(() {});
+                              } else {
+                                await showDialog<dynamic>(
+                                  context: context,
+                                  barrierDismissible: false,
+                                  builder: (_) => const StackOkDialog(
+                                      title: "Backup creation failed"),
+                                );
+                              }
+                            }
+                          },
+                    child: Text(
+                      "Create backup",
+                      style: STextStyles.button(context),
+                    ),
+                  )
+                : Row(
+                    children: [
+                      PrimaryButton(
+                        width: 183,
+                        desktopMed: true,
+                        label: "Create backup",
+                        enabled: shouldEnableCreate,
+                        onPressed: !shouldEnableCreate
+                            ? null
+                            : () async {
+                                final String pathToSave =
+                                    fileLocationController.text;
+                                final String passphrase =
+                                    passwordController.text;
+                                final String repeatPassphrase =
+                                    passwordRepeatController.text;
+
+                                if (pathToSave.isEmpty) {
+                                  unawaited(showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "Directory not chosen",
+                                    context: context,
+                                  ));
+                                  return;
+                                }
+                                if (!(await Directory(pathToSave).exists())) {
+                                  unawaited(showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "Directory does not exist",
+                                    context: context,
+                                  ));
+                                  return;
+                                }
+                                if (passphrase.isEmpty) {
+                                  unawaited(showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "A passphrase is required",
+                                    context: context,
+                                  ));
+                                  return;
+                                }
+                                if (passphrase != repeatPassphrase) {
+                                  unawaited(showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "Passphrase does not match",
+                                    context: context,
+                                  ));
+                                  return;
+                                }
+
+                                unawaited(showDialog<dynamic>(
+                                  context: context,
+                                  barrierDismissible: false,
+                                  builder: (_) => const StackDialog(
+                                    title: "Encrypting backup",
+                                    message: "This shouldn't take long",
+                                  ),
+                                ));
+                                // make sure the dialog is able to be displayed for at least 1 second
+                                await Future<void>.delayed(
+                                    const Duration(seconds: 1));
+
+                                final DateTime now = DateTime.now();
+                                final String fileToSave =
+                                    "$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
+
+                                final backup =
+                                    await SWB.createStackWalletJSON();
+
+                                bool result =
+                                    await SWB.encryptStackWalletWithPassphrase(
+                                  fileToSave,
+                                  passphrase,
+                                  jsonEncode(backup),
+                                );
+
+                                if (mounted) {
+                                  // pop encryption progress dialog
+                                  Navigator.of(context).pop();
+
+                                  if (result) {
+                                    await showDialog<dynamic>(
+                                      context: context,
+                                      barrierDismissible: false,
+                                      builder: (_) => Platform.isAndroid
+                                          ? StackOkDialog(
+                                              title: "Backup saved to:",
+                                              message: fileToSave,
+                                            )
+                                          : const StackOkDialog(
+                                              title:
+                                                  "Backup creation succeeded"),
+                                    );
+                                    passwordController.text = "";
+                                    passwordRepeatController.text = "";
+                                    setState(() {});
+                                  } else {
+                                    await showDialog<dynamic>(
+                                      context: context,
+                                      barrierDismissible: false,
+                                      builder: (_) => const StackOkDialog(
+                                          title: "Backup creation failed"),
+                                    );
+                                  }
+                                }
+                              },
+                      ),
+                      const SizedBox(
+                        width: 16,
+                      ),
+                      SecondaryButton(
+                        width: 183,
+                        desktopMed: true,
+                        label: "Cancel",
+                        onPressed: () {},
+                      ),
+                    ],
+                  ),
           ],
         ),
       ),

From 8af1350b95acc35ffb0e83e3ea67a32453b53a2f Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 8 Nov 2022 10:50:12 -0700
Subject: [PATCH 168/426] button correction for desktop restore backup and
 other ui fixes

---
 .../create_backup_view.dart                   |  37 +-
 .../restore_from_file_view.dart               | 354 ++++++++++++------
 2 files changed, 251 insertions(+), 140 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 51a1d7218..eacdda66a 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -147,7 +147,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
             crossAxisAlignment: CrossAxisAlignment.start,
             children: [
               Padding(
-                padding: const EdgeInsets.all(10.0),
+                padding: const EdgeInsets.only(bottom: 10),
                 child: Text(
                   "Choose file location",
                   style: STextStyles.desktopTextExtraExtraSmall(context)
@@ -158,24 +158,6 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                 ),
               ),
               child,
-              // const SizedBox(height: 20),
-              // Row(
-              //   children: [
-              //     PrimaryButton(
-              //       desktopMed: true,
-              //       width: 200,
-              //       label: "Create backup",
-              //       onPressed: () {},
-              //     ),
-              //     const SizedBox(width: 16),
-              //     SecondaryButton(
-              //       desktopMed: true,
-              //       width: 200,
-              //       label: "Cancel",
-              //       onPressed: () {},
-              //     ),
-              //   ],
-              // ),
             ],
           );
         },
@@ -252,8 +234,21 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                 );
               }),
             if (!Platform.isAndroid)
-              const SizedBox(
-                height: 8,
+              SizedBox(
+                height: !isDesktop ? 8 : 24,
+              ),
+            if (isDesktop)
+              Padding(
+                padding: const EdgeInsets.only(bottom: 10.0),
+                child: Text(
+                  "Create a passphrase",
+                  style: STextStyles.desktopTextExtraExtraSmall(context)
+                      .copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark3),
+                  textAlign: TextAlign.left,
+                ),
               ),
             ClipRRect(
               borderRadius: BorderRadius.circular(
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index c73d596f0..f7a9883de 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -131,7 +131,7 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
                 Padding(
-                  padding: const EdgeInsets.all(10.0),
+                  padding: const EdgeInsets.only(bottom: 10.0),
                   child: Text(
                     "Choose file location",
                     style: STextStyles.desktopTextExtraExtraSmall(context)
@@ -143,26 +143,6 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                   ),
                 ),
                 child,
-                const SizedBox(height: 20),
-                Row(
-                  children: [
-                    PrimaryButton(
-                      desktopMed: true,
-                      width: 200,
-                      label: "Restore",
-                      onPressed: () {
-                        restoreBackupPopup(context);
-                      },
-                    ),
-                    const SizedBox(width: 16),
-                    SecondaryButton(
-                      desktopMed: true,
-                      width: 200,
-                      label: "Cancel",
-                      onPressed: () {},
-                    ),
-                  ],
-                ),
               ],
             );
           },
@@ -225,9 +205,22 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                 ),
                 onChanged: (newValue) {},
               ),
-              const SizedBox(
-                height: 8,
+              SizedBox(
+                height: !isDesktop ? 8 : 24,
               ),
+              if (isDesktop)
+                Padding(
+                  padding: const EdgeInsets.only(bottom: 10.0),
+                  child: Text(
+                    "Enter passphrase",
+                    style: STextStyles.desktopTextExtraExtraSmall(context)
+                        .copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark3),
+                    textAlign: TextAlign.left,
+                  ),
+                ),
               ClipRRect(
                 borderRadius: BorderRadius.circular(
                   Constants.size.circularBorderRadius,
@@ -288,113 +281,236 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                 height: 16,
               ),
               if (!isDesktop) const Spacer(),
-              TextButton(
-                style: passwordController.text.isEmpty ||
-                        fileLocationController.text.isEmpty
-                    ? Theme.of(context)
-                        .extension<StackColors>()!
-                        .getPrimaryDisabledButtonColor(context)
-                    : Theme.of(context)
-                        .extension<StackColors>()!
-                        .getPrimaryEnabledButtonColor(context),
-                onPressed: passwordController.text.isEmpty ||
-                        fileLocationController.text.isEmpty
-                    ? null
-                    : () async {
-                        final String fileToRestore =
-                            fileLocationController.text;
-                        final String passphrase = passwordController.text;
+              !isDesktop
+                  ? TextButton(
+                      style: passwordController.text.isEmpty ||
+                              fileLocationController.text.isEmpty
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .getPrimaryDisabledButtonColor(context)
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .getPrimaryEnabledButtonColor(context),
+                      onPressed: passwordController.text.isEmpty ||
+                              fileLocationController.text.isEmpty
+                          ? null
+                          : () async {
+                              final String fileToRestore =
+                                  fileLocationController.text;
+                              final String passphrase = passwordController.text;
 
-                        if (FocusScope.of(context).hasFocus) {
-                          FocusScope.of(context).unfocus();
-                          await Future<void>.delayed(
-                              const Duration(milliseconds: 75));
-                        }
+                              if (FocusScope.of(context).hasFocus) {
+                                FocusScope.of(context).unfocus();
+                                await Future<void>.delayed(
+                                    const Duration(milliseconds: 75));
+                              }
 
-                        if (!(await File(fileToRestore).exists())) {
-                          showFloatingFlushBar(
-                            type: FlushBarType.warning,
-                            message: "Backup file does not exist",
-                            context: context,
-                          );
-                          return;
-                        }
+                              if (!(await File(fileToRestore).exists())) {
+                                await showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "Backup file does not exist",
+                                  context: context,
+                                );
+                                return;
+                              }
 
-                        bool shouldPop = false;
-                        showDialog<dynamic>(
-                          barrierDismissible: false,
-                          context: context,
-                          builder: (_) => WillPopScope(
-                            onWillPop: () async {
-                              return shouldPop;
-                            },
-                            child: Column(
-                              crossAxisAlignment: CrossAxisAlignment.stretch,
-                              mainAxisAlignment: MainAxisAlignment.center,
-                              children: [
-                                Material(
-                                  color: Colors.transparent,
-                                  child: Center(
-                                    child: Text(
-                                      "Decrypting Stack backup file",
-                                      style: STextStyles.pageTitleH2(context)
-                                          .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textWhite,
+                              bool shouldPop = false;
+                              await showDialog<dynamic>(
+                                barrierDismissible: false,
+                                context: context,
+                                builder: (_) => WillPopScope(
+                                  onWillPop: () async {
+                                    return shouldPop;
+                                  },
+                                  child: Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.stretch,
+                                    mainAxisAlignment: MainAxisAlignment.center,
+                                    children: [
+                                      Material(
+                                        color: Colors.transparent,
+                                        child: Center(
+                                          child: Text(
+                                            "Decrypting Stack backup file",
+                                            style:
+                                                STextStyles.pageTitleH2(context)
+                                                    .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textWhite,
+                                            ),
+                                          ),
+                                        ),
                                       ),
+                                      const SizedBox(
+                                        height: 64,
+                                      ),
+                                      const Center(
+                                        child: LoadingIndicator(
+                                          width: 100,
+                                        ),
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              );
+
+                              final String? jsonString = await compute(
+                                SWB.decryptStackWalletWithPassphrase,
+                                Tuple2(fileToRestore, passphrase),
+                                debugLabel: "stack wallet decryption compute",
+                              );
+
+                              if (mounted) {
+                                // pop LoadingIndicator
+                                shouldPop = true;
+                                Navigator.of(context).pop();
+
+                                passwordController.text = "";
+
+                                if (jsonString == null) {
+                                  await showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "Failed to decrypt backup file",
+                                    context: context,
+                                  );
+                                  return;
+                                }
+
+                                await Navigator.of(context).push(
+                                  RouteGenerator.getRoute(
+                                    builder: (_) => StackRestoreProgressView(
+                                      jsonString: jsonString,
                                     ),
                                   ),
-                                ),
-                                const SizedBox(
-                                  height: 64,
-                                ),
-                                const Center(
-                                  child: LoadingIndicator(
-                                    width: 100,
-                                  ),
-                                ),
-                              ],
-                            ),
-                          ),
-                        );
+                                );
+                              }
+                            },
+                      child: Text(
+                        "Restore",
+                        style: STextStyles.button(context),
+                      ),
+                    )
+                  : Row(
+                      children: [
+                        PrimaryButton(
+                          width: 183,
+                          desktopMed: true,
+                          label: "Restore",
+                          enabled: !(passwordController.text.isEmpty ||
+                              fileLocationController.text.isEmpty),
+                          onPressed: passwordController.text.isEmpty ||
+                                  fileLocationController.text.isEmpty
+                              ? null
+                              : () async {
+                                  final String fileToRestore =
+                                      fileLocationController.text;
+                                  final String passphrase =
+                                      passwordController.text;
 
-                        final String? jsonString = await compute(
-                          SWB.decryptStackWalletWithPassphrase,
-                          Tuple2(fileToRestore, passphrase),
-                          debugLabel: "stack wallet decryption compute",
-                        );
+                                  if (FocusScope.of(context).hasFocus) {
+                                    FocusScope.of(context).unfocus();
+                                    await Future<void>.delayed(
+                                        const Duration(milliseconds: 75));
+                                  }
 
-                        if (mounted) {
-                          // pop LoadingIndicator
-                          shouldPop = true;
-                          Navigator.of(context).pop();
+                                  if (!(await File(fileToRestore).exists())) {
+                                    await showFloatingFlushBar(
+                                      type: FlushBarType.warning,
+                                      message: "Backup file does not exist",
+                                      context: context,
+                                    );
+                                    return;
+                                  }
 
-                          passwordController.text = "";
+                                  bool shouldPop = false;
+                                  await showDialog<dynamic>(
+                                    barrierDismissible: false,
+                                    context: context,
+                                    builder: (_) => WillPopScope(
+                                      onWillPop: () async {
+                                        return shouldPop;
+                                      },
+                                      child: Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.stretch,
+                                        mainAxisAlignment:
+                                            MainAxisAlignment.center,
+                                        children: [
+                                          Material(
+                                            color: Colors.transparent,
+                                            child: Center(
+                                              child: Text(
+                                                "Decrypting Stack backup file",
+                                                style: STextStyles.pageTitleH2(
+                                                        context)
+                                                    .copyWith(
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textWhite,
+                                                ),
+                                              ),
+                                            ),
+                                          ),
+                                          const SizedBox(
+                                            height: 64,
+                                          ),
+                                          const Center(
+                                            child: LoadingIndicator(
+                                              width: 100,
+                                            ),
+                                          ),
+                                        ],
+                                      ),
+                                    ),
+                                  );
 
-                          if (jsonString == null) {
-                            showFloatingFlushBar(
-                              type: FlushBarType.warning,
-                              message: "Failed to decrypt backup file",
-                              context: context,
-                            );
-                            return;
-                          }
+                                  final String? jsonString = await compute(
+                                    SWB.decryptStackWalletWithPassphrase,
+                                    Tuple2(fileToRestore, passphrase),
+                                    debugLabel:
+                                        "stack wallet decryption compute",
+                                  );
 
-                          Navigator.of(context).push(
-                            RouteGenerator.getRoute(
-                              builder: (_) => StackRestoreProgressView(
-                                jsonString: jsonString,
-                              ),
-                            ),
-                          );
-                        }
-                      },
-                child: Text(
-                  "Restore",
-                  style: STextStyles.button(context),
-                ),
-              ),
+                                  if (mounted) {
+                                    // pop LoadingIndicator
+                                    shouldPop = true;
+                                    Navigator.of(context).pop();
+
+                                    passwordController.text = "";
+
+                                    if (jsonString == null) {
+                                      await showFloatingFlushBar(
+                                        type: FlushBarType.warning,
+                                        message:
+                                            "Failed to decrypt backup file",
+                                        context: context,
+                                      );
+                                      return;
+                                    }
+
+                                    await Navigator.of(context).push(
+                                      RouteGenerator.getRoute(
+                                        builder: (_) =>
+                                            StackRestoreProgressView(
+                                          jsonString: jsonString,
+                                        ),
+                                      ),
+                                    );
+                                  }
+                                },
+                        ),
+                        const SizedBox(
+                          width: 16,
+                        ),
+                        SecondaryButton(
+                          width: 183,
+                          desktopMed: true,
+                          label: "Cancel",
+                          onPressed: () {},
+                        ),
+                      ],
+                    ),
             ],
           ),
         ));

From 95716bd0f6be7f5b7c6dcbb08b03efa6a5dfb545 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 8 Nov 2022 12:15:31 -0700
Subject: [PATCH 169/426] added textfield functionality to desktop create auto
 backup

---
 .../create_auto_backup.dart                   | 489 +++++++++++-------
 1 file changed, 306 insertions(+), 183 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index f3e502bcb..57a8d7a64 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -1,14 +1,23 @@
+import 'dart:io';
+
 import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/log_level_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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
+import 'package:zxcvbn/zxcvbn.dart';
 
 class CreateAutoBackup extends StatefulWidget {
   const CreateAutoBackup({Key? key}) : super(key: key);
@@ -22,13 +31,24 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
   late final TextEditingController passphraseController;
   late final TextEditingController passphraseRepeatController;
 
-  late final FocusNode chooseFileLocation;
+  late final StackFileSystem stackFileSystem;
   late final FocusNode passphraseFocusNode;
   late final FocusNode passphraseRepeatFocusNode;
+  final zxcvbn = Zxcvbn();
 
   bool shouldShowPasswordHint = true;
   bool hidePassword = true;
 
+  String passwordFeedback =
+      "Add another word or two. Uncommon words are better. Use a few words, avoid common phrases. No need for symbols, digits, or uppercase letters.";
+  double passwordStrength = 0.0;
+
+  bool get shouldEnableCreate {
+    return fileLocationController.text.isNotEmpty &&
+        passphraseController.text.isNotEmpty &&
+        passphraseRepeatController.text.isNotEmpty;
+  }
+
   bool get fieldsMatch =>
       passphraseController.text == passphraseRepeatController.text;
 
@@ -42,14 +62,26 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
 
   @override
   void initState() {
+    stackFileSystem = StackFileSystem();
+
     fileLocationController = TextEditingController();
     passphraseController = TextEditingController();
     passphraseRepeatController = TextEditingController();
 
-    chooseFileLocation = FocusNode();
     passphraseFocusNode = FocusNode();
     passphraseRepeatFocusNode = FocusNode();
 
+    if (Platform.isAndroid) {
+      WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
+        final dir = await stackFileSystem.prepareStorage();
+        if (mounted) {
+          setState(() {
+            fileLocationController.text = dir.path;
+          });
+        }
+      });
+    }
+
     super.initState();
   }
 
@@ -59,7 +91,6 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
     passphraseController.dispose();
     passphraseRepeatController.dispose();
 
-    chooseFileLocation.dispose();
     passphraseFocusNode.dispose();
     passphraseRepeatFocusNode.dispose();
 
@@ -71,9 +102,9 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
     debugPrint("BUILD: $runtimeType ");
 
     String? selectedItem = "Every 10 minutes";
-
+    final isDesktop = Util.isDesktop;
     return DesktopDialog(
-      maxHeight: 650,
+      maxHeight: 680,
       maxWidth: 600,
       child: Column(
         children: [
@@ -127,198 +158,289 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
             height: 10,
           ),
           Padding(
-            padding: const EdgeInsets.only(
-              left: 32,
-              right: 32,
-            ),
-            child: ClipRRect(
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-              child: TextField(
-                key: const Key("backupChooseFileLocation"),
-                focusNode: chooseFileLocation,
-                controller: fileLocationController,
-                style: STextStyles.desktopTextMedium(context).copyWith(
-                  height: 2,
-                ),
-                textAlign: TextAlign.left,
-                enableSuggestions: false,
-                autocorrect: false,
-                decoration: standardInputDecoration(
-                  "Save to...",
-                  chooseFileLocation,
-                  context,
-                ).copyWith(
-                  labelStyle:
-                      STextStyles.desktopTextExtraExtraSmall(context).copyWith(
-                    color:
-                        Theme.of(context).extension<StackColors>()!.textDark3,
-                  ),
-                  suffixIcon: Container(
-                    decoration: BoxDecoration(
+            padding: const EdgeInsets.symmetric(horizontal: 32),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.stretch,
+              children: [
+                if (!Platform.isAndroid)
+                  Consumer(builder: (context, ref, __) {
+                    return Container(
                       color: Colors.transparent,
-                      borderRadius: BorderRadius.circular(1000),
-                    ),
-                    height: 32,
-                    width: 32,
-                    child: Center(
-                      child: SvgPicture.asset(
-                        Assets.svg.folder,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textDark3,
-                        width: 20,
-                        height: 17.5,
-                      ),
-                    ),
-                  ),
-                ),
-              ),
-            ),
-          ),
-          const SizedBox(
-            height: 24,
-          ),
-          Container(
-            alignment: Alignment.centerLeft,
-            padding: const EdgeInsets.only(left: 32),
-            child: Text(
-              "Create a passphrase",
-              style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                color: Theme.of(context).extension<StackColors>()!.textDark3,
-              ),
-              textAlign: TextAlign.left,
-            ),
-          ),
-          const SizedBox(
-            height: 10,
-          ),
-          Padding(
-            padding: const EdgeInsets.only(
-              left: 32,
-              right: 32,
-            ),
-            child: ClipRRect(
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-              child: TextField(
-                key: const Key("createBackupPassphrase"),
-                focusNode: passphraseFocusNode,
-                controller: passphraseController,
-                style: STextStyles.desktopTextMedium(context).copyWith(
-                  height: 2,
-                ),
-                obscureText: hidePassword,
-                enableSuggestions: false,
-                autocorrect: false,
-                decoration: standardInputDecoration(
-                  "Create passphrase",
-                  passphraseFocusNode,
-                  context,
-                ).copyWith(
-                  labelStyle:
-                      STextStyles.desktopTextExtraExtraSmall(context).copyWith(
-                    color:
-                        Theme.of(context).extension<StackColors>()!.textDark3,
-                  ),
-                  suffixIcon: UnconstrainedBox(
-                    child: GestureDetector(
-                      key: const Key(
-                          "createDesktopAutoBackupShowPassphraseButton1"),
-                      onTap: () async {
-                        setState(() {
-                          hidePassword = !hidePassword;
-                        });
-                      },
-                      child: Container(
-                        decoration: BoxDecoration(
-                          color: Colors.transparent,
-                          borderRadius: BorderRadius.circular(1000),
-                        ),
-                        height: 32,
-                        width: 32,
-                        child: Center(
-                          child: SvgPicture.asset(
-                            hidePassword ? Assets.svg.eye : Assets.svg.eyeSlash,
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark3,
-                            width: 20,
-                            height: 17.5,
+                      child: TextField(
+                        autocorrect: false,
+                        enableSuggestions: false,
+                        onTap: Platform.isAndroid
+                            ? null
+                            : () async {
+                                try {
+                                  await stackFileSystem.prepareStorage();
+
+                                  if (mounted) {
+                                    await stackFileSystem.pickDir(context);
+                                  }
+
+                                  if (mounted) {
+                                    setState(() {
+                                      fileLocationController.text =
+                                          stackFileSystem.dirPath ?? "";
+                                    });
+                                  }
+                                } catch (e, s) {
+                                  Logging.instance
+                                      .log("$e\n$s", level: LogLevel.Error);
+                                }
+                              },
+                        controller: fileLocationController,
+                        style: STextStyles.field(context),
+                        decoration: InputDecoration(
+                          hintText: "Save to...",
+                          hintStyle: STextStyles.fieldLabel(context),
+                          suffixIcon: UnconstrainedBox(
+                            child: Row(
+                              children: [
+                                const SizedBox(
+                                  width: 16,
+                                ),
+                                SvgPicture.asset(
+                                  Assets.svg.folder,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark3,
+                                  width: 16,
+                                  height: 16,
+                                ),
+                                const SizedBox(
+                                  width: 12,
+                                ),
+                              ],
+                            ),
                           ),
                         ),
+                        key: const Key(
+                            "createBackupSaveToFileLocationTextFieldKey"),
+                        readOnly: true,
+                        toolbarOptions: const ToolbarOptions(
+                          copy: true,
+                          cut: false,
+                          paste: false,
+                          selectAll: false,
+                        ),
+                        onChanged: (newValue) {
+                          // ref.read(addressEntryDataProvider(widget.id)).address = newValue;
+                        },
                       ),
+                    );
+                  }),
+                if (!Platform.isAndroid)
+                  const SizedBox(
+                    height: 24,
+                  ),
+                if (isDesktop)
+                  Padding(
+                    padding: const EdgeInsets.only(bottom: 10.0),
+                    child: Text(
+                      "Create a passphrase",
+                      style: STextStyles.desktopTextExtraSmall(context)
+                          .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark3),
+                      textAlign: TextAlign.left,
                     ),
                   ),
-                ),
-              ),
-            ),
-          ),
-          const SizedBox(
-            height: 16,
-          ),
-          Padding(
-            padding: const EdgeInsets.only(
-              left: 32,
-              right: 32,
-            ),
-            child: ClipRRect(
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-              child: TextField(
-                key: const Key("createBackupPassphrase"),
-                focusNode: passphraseRepeatFocusNode,
-                controller: passphraseRepeatController,
-                style: STextStyles.desktopTextMedium(context).copyWith(
-                  height: 2,
-                ),
-                obscureText: hidePassword,
-                enableSuggestions: false,
-                autocorrect: false,
-                decoration: standardInputDecoration(
-                  "Confirm passphrase",
-                  passphraseRepeatFocusNode,
-                  context,
-                ).copyWith(
-                  labelStyle:
-                      STextStyles.desktopTextExtraExtraSmall(context).copyWith(
-                    color:
-                        Theme.of(context).extension<StackColors>()!.textDark3,
+                ClipRRect(
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
                   ),
-                  suffixIcon: UnconstrainedBox(
-                    child: GestureDetector(
-                      key: const Key(
-                          "createDesktopAutoBackupShowPassphraseButton2"),
-                      onTap: () async {
+                  child: TextField(
+                    key: const Key("createBackupPasswordFieldKey1"),
+                    focusNode: passphraseFocusNode,
+                    controller: passphraseController,
+                    style: STextStyles.field(context),
+                    obscureText: hidePassword,
+                    enableSuggestions: false,
+                    autocorrect: false,
+                    decoration: standardInputDecoration(
+                      "Create passphrase",
+                      passphraseFocusNode,
+                      context,
+                    ).copyWith(
+                      labelStyle:
+                          isDesktop ? STextStyles.fieldLabel(context) : null,
+                      suffixIcon: UnconstrainedBox(
+                        child: Row(
+                          children: [
+                            const SizedBox(
+                              width: 16,
+                            ),
+                            GestureDetector(
+                              key: const Key(
+                                  "createBackupPasswordFieldShowPasswordButtonKey"),
+                              onTap: () async {
+                                setState(() {
+                                  hidePassword = !hidePassword;
+                                });
+                              },
+                              child: SvgPicture.asset(
+                                hidePassword
+                                    ? Assets.svg.eye
+                                    : Assets.svg.eyeSlash,
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark3,
+                                width: 16,
+                                height: 16,
+                              ),
+                            ),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                    onChanged: (newValue) {
+                      if (newValue.isEmpty) {
                         setState(() {
-                          hidePassword = !hidePassword;
+                          passwordFeedback = "";
                         });
-                      },
-                      child: Container(
-                        decoration: BoxDecoration(
-                          color: Colors.transparent,
-                          borderRadius: BorderRadius.circular(1000),
-                        ),
-                        height: 32,
-                        width: 32,
-                        child: Center(
-                          child: SvgPicture.asset(
-                            hidePassword ? Assets.svg.eye : Assets.svg.eyeSlash,
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark3,
-                            width: 20,
-                            height: 17.5,
-                          ),
+                        return;
+                      }
+                      final result = zxcvbn.evaluate(newValue);
+                      String suggestionsAndTips = "";
+                      for (var sug in result.feedback.suggestions!.toSet()) {
+                        suggestionsAndTips += "$sug\n";
+                      }
+                      suggestionsAndTips += result.feedback.warning!;
+                      String feedback =
+                          // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
+                          suggestionsAndTips;
+
+                      passwordStrength = result.score! / 4;
+
+                      // hack fix to format back string returned from zxcvbn
+                      if (feedback.contains("phrasesNo need")) {
+                        feedback = feedback.replaceFirst(
+                            "phrasesNo need", "phrases\nNo need");
+                      }
+
+                      if (feedback.endsWith("\n")) {
+                        feedback = feedback.substring(0, feedback.length - 2);
+                      }
+
+                      setState(() {
+                        passwordFeedback = feedback;
+                      });
+                    },
+                  ),
+                ),
+                if (passphraseFocusNode.hasFocus ||
+                    passphraseRepeatFocusNode.hasFocus ||
+                    passphraseController.text.isNotEmpty)
+                  Padding(
+                    padding: EdgeInsets.only(
+                      left: 12,
+                      right: 12,
+                      top: passwordFeedback.isNotEmpty ? 4 : 0,
+                    ),
+                    child: passwordFeedback.isNotEmpty
+                        ? Text(
+                            passwordFeedback,
+                            style: STextStyles.infoSmall(context),
+                          )
+                        : null,
+                  ),
+                if (passphraseFocusNode.hasFocus ||
+                    passphraseRepeatFocusNode.hasFocus ||
+                    passphraseController.text.isNotEmpty)
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      left: 12,
+                      right: 12,
+                      top: 10,
+                    ),
+                    child: ProgressBar(
+                      key: const Key("createStackBackUpProgressBar"),
+                      width: 510,
+                      height: 5,
+                      fillColor: passwordStrength < 0.51
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .accentColorRed
+                          : passwordStrength < 1
+                              ? Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorYellow
+                              : Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorGreen,
+                      backgroundColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .buttonBackSecondary,
+                      percent:
+                          passwordStrength < 0.25 ? 0.03 : passwordStrength,
+                    ),
+                  ),
+                const SizedBox(
+                  height: 10,
+                ),
+                ClipRRect(
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
+                  child: TextField(
+                    key: const Key("createBackupPasswordFieldKey2"),
+                    focusNode: passphraseRepeatFocusNode,
+                    controller: passphraseRepeatController,
+                    style: STextStyles.field(context),
+                    obscureText: hidePassword,
+                    enableSuggestions: false,
+                    autocorrect: false,
+                    decoration: standardInputDecoration(
+                      "Confirm passphrase",
+                      passphraseRepeatFocusNode,
+                      context,
+                    ).copyWith(
+                      labelStyle: STextStyles.fieldLabel(context),
+                      suffixIcon: UnconstrainedBox(
+                        child: Row(
+                          children: [
+                            const SizedBox(
+                              width: 16,
+                            ),
+                            GestureDetector(
+                              key: const Key(
+                                  "createBackupPasswordFieldShowPasswordButtonKey"),
+                              onTap: () async {
+                                setState(() {
+                                  hidePassword = !hidePassword;
+                                });
+                              },
+                              child: SvgPicture.asset(
+                                hidePassword
+                                    ? Assets.svg.eye
+                                    : Assets.svg.eyeSlash,
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark3,
+                                width: 16,
+                                height: 16,
+                              ),
+                            ),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                          ],
                         ),
                       ),
                     ),
+                    onChanged: (newValue) {
+                      setState(() {});
+                      // TODO: ? check if passwords match?
+                    },
                   ),
                 ),
-              ),
+              ],
             ),
           ),
           const SizedBox(
@@ -376,6 +498,7 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
               },
             ),
           ),
+          const Spacer(),
           Padding(
             padding: const EdgeInsets.all(32),
             child: Row(

From 48e8501e27c8f2e8494c2746710c18be276dbce2 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Tue, 8 Nov 2022 13:35:27 -0600
Subject: [PATCH 170/426] cherrypick e41f8088b02c8aeaac8caaebac27dcbe7cc1d893

---
 .../restore_options_view.dart                 | 36 +++++++++++++++----
 .../restore_wallet_view.dart                  |  5 +++
 .../coins/wownero/wownero_wallet.dart         | 11 ++++--
 lib/utilities/constants.dart                  |  6 +---
 4 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
index 76e74fa14..1ce5d713a 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
@@ -252,7 +252,11 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
               SizedBox(
                 height: isDesktop ? 40 : 24,
               ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 Text(
                   "Choose start date",
                   style: isDesktop
@@ -264,11 +268,19 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
                       : STextStyles.smallMed12(context),
                   textAlign: TextAlign.left,
                 ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 SizedBox(
                   height: isDesktop ? 16 : 8,
                 ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
 
                 // if (!isDesktop)
                 RestoreFromDatePicker(
@@ -278,11 +290,19 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
 
               // if (isDesktop)
               //   // TODO desktop date picker
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 const SizedBox(
                   height: 8,
                 ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 RoundedWhiteContainer(
                   child: Center(
                     child: Text(
@@ -299,7 +319,11 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
                     ),
                   ),
                 ),
-              if (coin == Coin.monero || coin == Coin.epicCash)
+              if (coin == Coin.monero ||
+                  coin == Coin.epicCash ||
+                  (coin == Coin.wownero &&
+                      ref.watch(mnemonicWordCountStateProvider.state).state ==
+                          25))
                 SizedBox(
                   height: isDesktop ? 24 : 16,
                 ),
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
index def0724b5..a6b7e7e77 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
@@ -149,6 +149,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
     super.dispose();
   }
 
+  // TODO: check for wownero wordlist?
   bool _isValidMnemonicWord(String word) {
     // TODO: get the actual language
     if (widget.coin == Coin.monero) {
@@ -181,6 +182,10 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
       if (widget.coin == Coin.monero) {
         height = monero.getHeigthByDate(date: widget.restoreFromDate);
       }
+      // todo: wait until this implemented
+      // else if (widget.coin == Coin.wownero) {
+      //   height = wownero.getHeightByDate(date: widget.restoreFromDate);
+      // }
 
       // TODO: make more robust estimate of date maybe using https://explorer.epic.tech/api-index
       if (widget.coin == Coin.epicCash) {
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index a0dc7bfe0..5c419afd1 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -948,6 +948,11 @@ class WowneroWallet extends CoinServiceAPI {
     required int maxNumberOfIndexesToCheck,
     required int height,
   }) async {
+    final int seedLength = mnemonic.trim().split(" ").length;
+    if (!(seedLength == 14 || seedLength == 25)) {
+      throw Exception("Invalid wownero mnemonic length found: $seedLength");
+    }
+
     await _prefs.init();
     longMutex = true;
     final start = DateTime.now();
@@ -975,8 +980,10 @@ class WowneroWallet extends CoinServiceAPI {
       await _secureStore.write(
           key: '${_walletId}_mnemonic', value: mnemonic.trim());
 
-      height = 0;
-      //height = getSeedHeightSync(mnemonic.trim()); // TODO use an alternative to wow_seed's get_seed_height
+      // extract seed height from 14 word seed
+      if (seedLength == 14) {
+        height = getSeedHeightSync(mnemonic.trim());
+      }
 
       await DB.instance
           .put<dynamic>(boxName: walletId, key: "restoreHeight", value: height);
diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart
index 4fb3fb54b..e27fbaa3d 100644
--- a/lib/utilities/constants.dart
+++ b/lib/utilities/constants.dart
@@ -35,10 +35,6 @@ abstract class Constants {
 
   static const int pinLength = 4;
 
-  // enable testnet
-  // TODO: currently unused
-  static const bool allowTestnets = true;
-
   // Enable Logger.print statements
   static const bool disableLogger = false;
 
@@ -66,7 +62,7 @@ abstract class Constants {
         values.addAll([25]);
         break;
       case Coin.wownero:
-        values.addAll([14]);
+        values.addAll([14, 25]);
         break;
     }
     return values;

From d23f6f2823a2d53b578f930c11fb4b41e0b25a27 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Tue, 8 Nov 2022 13:48:29 -0600
Subject: [PATCH 171/426] return to use of final for bufferedCreateHeight using
 inline if

and use wowlet's height estimation function for 14 word seeds
---
 crypto_plugins/flutter_libmonero               | 2 +-
 lib/services/coins/wownero/wownero_wallet.dart | 8 ++------
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index afdee4b88..2d5f5e563 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit afdee4b880202f39a2375afc320f0642e98a1827
+Subproject commit 2d5f5e5636bdc4b211b2236492268167b5b969d0
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 5c419afd1..55f43cdd1 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -714,12 +714,8 @@ class WowneroWallet extends CoinServiceAPI {
       final wallet = await _walletCreationService?.create(credentials);
 
       // subtract a couple days to ensure we have a buffer for SWB
-      if (seedWordsLength == 14) {
-        final bufferedCreateHeight = getSeedHeightSync(wallet?.seed.trim() as String);
-      } else {
-        final bufferedCreateHeight = 0;
-        // TODO use an alternative to wow_seed's get_seed_height
-      }
+      final bufferedCreateHeight = (seedWordsLength == 14) ? getSeedHeightSync(wallet?.seed.trim() as String) : 0;
+      // TODO use an alternative to wow_seed's get_seed_height instead of 0 above
 
       await DB.instance.put<dynamic>(
           boxName: walletId, key: "restoreHeight", value: bufferedCreateHeight);

From 015f33326948aff663299206ed47ba3157c31a42 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Tue, 8 Nov 2022 14:33:16 -0600
Subject: [PATCH 172/426] do not rely upon nullable variable

---
 crypto_plugins/flutter_libmonero | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index 2d5f5e563..0b355aee5 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit 2d5f5e5636bdc4b211b2236492268167b5b969d0
+Subproject commit 0b355aee55608f497ca54aba151d0b3e9e2c4579

From cede571350db905f4f70ba532f758c8869a9e15c Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 8 Nov 2022 13:50:53 -0600
Subject: [PATCH 173/426] desktop login/password screen

---
 .../desktop_login_view.dart                   | 166 ++++++++++++++++--
 lib/utilities/text_styles.dart                |  19 ++
 .../custom_buttons/blue_text_button.dart      |  11 +-
 3 files changed, 179 insertions(+), 17 deletions(-)

diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index c986bffde..1c70a5d98 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -1,7 +1,14 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
+import 'package:stackwallet/utilities/assets.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/widgets/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
 
 class DesktopLoginView extends StatefulWidget {
   const DesktopLoginView({
@@ -18,28 +25,155 @@ class DesktopLoginView extends StatefulWidget {
 }
 
 class _DesktopLoginViewState extends State<DesktopLoginView> {
+  late final TextEditingController passwordController;
+
+  late final FocusNode passwordFocusNode;
+
+  bool hidePassword = true;
+  bool _continueEnabled = false;
+
+  @override
+  void initState() {
+    passwordController = TextEditingController();
+    passwordFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    passwordController.dispose();
+    passwordFocusNode.dispose();
+
+    super.dispose();
+  }
+
   @override
   Widget build(BuildContext context) {
-    return Material(
-      child: Column(
+    return DesktopScaffold(
+      body: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         crossAxisAlignment: CrossAxisAlignment.center,
         children: [
-          Text(
-            "Login",
-            style: STextStyles.desktopH3(context),
-          ),
-          PrimaryButton(
-            label: "Login",
-            onPressed: () {
-              // todo auth
+          SizedBox(
+            width: 480,
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.stackIcon(context),
+                  width: 100,
+                ),
+                const SizedBox(
+                  height: 42,
+                ),
+                Text(
+                  "Stack Wallet",
+                  style: STextStyles.desktopH1(context),
+                ),
+                const SizedBox(
+                  height: 24,
+                ),
+                SizedBox(
+                  width: 350,
+                  child: Text(
+                    "Open source multicoin wallet for everyone",
+                    textAlign: TextAlign.center,
+                    style: STextStyles.desktopSubtitleH1(context),
+                  ),
+                ),
+                const SizedBox(
+                  height: 24,
+                ),
+                ClipRRect(
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
+                  child: TextField(
+                    key: const Key("desktopLoginPasswordFieldKey"),
+                    focusNode: passwordFocusNode,
+                    controller: passwordController,
+                    style: STextStyles.desktopTextMedium(context).copyWith(
+                      height: 2,
+                    ),
+                    obscureText: hidePassword,
+                    enableSuggestions: false,
+                    autocorrect: false,
+                    decoration: standardInputDecoration(
+                      "Enter password",
+                      passwordFocusNode,
+                      context,
+                    ).copyWith(
+                      suffixIcon: UnconstrainedBox(
+                        child: SizedBox(
+                          height: 70,
+                          child: Row(
+                            children: [
+                              const SizedBox(
+                                width: 24,
+                              ),
+                              GestureDetector(
+                                key: const Key(
+                                    "restoreFromFilePasswordFieldShowPasswordButtonKey"),
+                                onTap: () async {
+                                  setState(() {
+                                    hidePassword = !hidePassword;
+                                  });
+                                },
+                                child: SvgPicture.asset(
+                                  hidePassword
+                                      ? Assets.svg.eye
+                                      : Assets.svg.eyeSlash,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark3,
+                                  width: 24,
+                                  height: 24,
+                                ),
+                              ),
+                              const SizedBox(
+                                width: 12,
+                              ),
+                            ],
+                          ),
+                        ),
+                      ),
+                    ),
+                    onChanged: (newValue) {
+                      setState(() {
+                        _continueEnabled = passwordController.text.isNotEmpty;
+                      });
+                    },
+                  ),
+                ),
+                const SizedBox(
+                  height: 24,
+                ),
+                PrimaryButton(
+                  label: "Continue",
+                  enabled: _continueEnabled,
+                  onPressed: () {
+                    // todo auth
 
-              Navigator.of(context).pushNamedAndRemoveUntil(
-                DesktopHomeView.routeName,
-                (route) => false,
-              );
-            },
-          )
+                    Navigator.of(context).pushNamedAndRemoveUntil(
+                      DesktopHomeView.routeName,
+                      (route) => false,
+                    );
+                  },
+                ),
+                const SizedBox(
+                  height: 60,
+                ),
+                BlueTextButton(
+                  text: "Forgot password?",
+                  textSize: 20,
+                  onTap: () {
+                    // todo: new screen
+                  },
+                ),
+              ],
+            ),
+          ),
         ],
       ),
     );
diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart
index 299ba5bec..63aa19afb 100644
--- a/lib/utilities/text_styles.dart
+++ b/lib/utilities/text_styles.dart
@@ -508,6 +508,25 @@ class STextStyles {
 
 // Desktop
 
+  static TextStyle desktopH1(BuildContext context) {
+    switch (_theme(context).themeType) {
+      case ThemeType.light:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 40,
+          height: 40 / 40,
+        );
+      case ThemeType.dark:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 40,
+          height: 40 / 40,
+        );
+    }
+  }
+
   static TextStyle desktopH2(BuildContext context) {
     switch (_theme(context).themeType) {
       case ThemeType.light:
diff --git a/lib/widgets/custom_buttons/blue_text_button.dart b/lib/widgets/custom_buttons/blue_text_button.dart
index aa7f75b1f..a87d1e6b2 100644
--- a/lib/widgets/custom_buttons/blue_text_button.dart
+++ b/lib/widgets/custom_buttons/blue_text_button.dart
@@ -10,11 +10,13 @@ class BlueTextButton extends ConsumerStatefulWidget {
     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
   ConsumerState<BlueTextButton> createState() => _BlueTextButtonState();
@@ -67,7 +69,14 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton>
       textAlign: TextAlign.center,
       text: TextSpan(
         text: widget.text,
-        style: STextStyles.link2(context).copyWith(color: color),
+        style: widget.textSize == null
+            ? STextStyles.link2(context).copyWith(
+                color: color,
+              )
+            : STextStyles.link2(context).copyWith(
+                color: color,
+                fontSize: widget.textSize,
+              ),
         recognizer: widget.enabled
             ? (TapGestureRecognizer()
               ..onTap = () {

From 97b4407957639d50a1cc9a52c710b6ef9a500baa Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 8 Nov 2022 14:04:00 -0600
Subject: [PATCH 174/426] desktop forgot password ui

---
 .../desktop_login_view.dart                   |   5 +-
 .../forgot_password_desktop_view.dart         | 101 ++++++++++++++++++
 lib/route_generator.dart                      |   7 ++
 3 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 lib/pages_desktop_specific/forgot_password_desktop_view.dart

diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index 1c70a5d98..fe05d719f 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages_desktop_specific/forgot_password_desktop_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -168,7 +169,9 @@ class _DesktopLoginViewState extends State<DesktopLoginView> {
                   text: "Forgot password?",
                   textSize: 20,
                   onTap: () {
-                    // todo: new screen
+                    Navigator.of(context).pushNamed(
+                      ForgotPasswordDesktopView.routeName,
+                    );
                   },
                 ),
               ],
diff --git a/lib/pages_desktop_specific/forgot_password_desktop_view.dart b/lib/pages_desktop_specific/forgot_password_desktop_view.dart
new file mode 100644
index 000000000..d501cbd38
--- /dev/null
+++ b/lib/pages_desktop_specific/forgot_password_desktop_view.dart
@@ -0,0 +1,101 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+class ForgotPasswordDesktopView extends StatefulWidget {
+  const ForgotPasswordDesktopView({
+    Key? key,
+  }) : super(key: key);
+
+  static const String routeName = "/forgotPasswordDesktop";
+
+  @override
+  State<ForgotPasswordDesktopView> createState() =>
+      _ForgotPasswordDesktopViewState();
+}
+
+class _ForgotPasswordDesktopViewState extends State<ForgotPasswordDesktopView> {
+  @override
+  Widget build(BuildContext context) {
+    return DesktopScaffold(
+      appBar: DesktopAppBar(
+        leading: AppBarBackButton(
+          onPressed: () async {
+            if (mounted) {
+              Navigator.of(context).pop();
+            }
+          },
+        ),
+        isCompactHeight: false,
+      ),
+      body: Column(
+        mainAxisAlignment: MainAxisAlignment.center,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        children: [
+          SizedBox(
+            width: 480,
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.stackIcon(context),
+                  width: 100,
+                ),
+                const SizedBox(
+                  height: 42,
+                ),
+                Text(
+                  "Stack Wallet",
+                  style: STextStyles.desktopH1(context),
+                ),
+                const SizedBox(
+                  height: 24,
+                ),
+                SizedBox(
+                  width: 400,
+                  child: Text(
+                    "Stack Wallet does not store your password. Create new wallet or use a Stack backup file to restore your wallet.",
+                    textAlign: TextAlign.center,
+                    style: STextStyles.desktopTextSmall(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textSubtitle1,
+                    ),
+                  ),
+                ),
+                const SizedBox(
+                  height: 48,
+                ),
+                PrimaryButton(
+                  label: "Create new wallet",
+                  onPressed: () {
+                    // // todo delete everything and start fresh?
+                  },
+                ),
+                const SizedBox(
+                  height: 24,
+                ),
+                SecondaryButton(
+                  label: "Restore from backup",
+                  onPressed: () {
+                    // todo SWB restore
+                  },
+                ),
+                const SizedBox(
+                  height: kDesktopAppBarHeight,
+                ),
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 40f11dc57..30963781b 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -85,6 +85,7 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_sear
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
 import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
 import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
+import 'package:stackwallet/pages_desktop_specific/forgot_password_desktop_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
@@ -998,6 +999,12 @@ class RouteGenerator {
             builder: (_) => const CreatePasswordView(),
             settings: RouteSettings(name: settings.name));
 
+      case ForgotPasswordDesktopView.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const ForgotPasswordDesktopView(),
+            settings: RouteSettings(name: settings.name));
+
       case DesktopHomeView.routeName:
         return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,

From c66e382fc380c45afb15690fbb69467ba1bde0d8 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Tue, 8 Nov 2022 17:30:09 -0600
Subject: [PATCH 175/426] get appropriate WowneroWordList based on seed length

---
 crypto_plugins/flutter_libmonero                           | 2 +-
 .../restore_wallet_view/restore_wallet_view.dart           | 7 ++++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index 0b355aee5..e440e9a3a 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit 0b355aee55608f497ca54aba151d0b3e9e2c4579
+Subproject commit e440e9a3a125ee2030551ad7dea9114dd6a06aa0
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
index a6b7e7e77..7596d7ac8 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
@@ -8,6 +8,7 @@ import 'package:bip39/src/wordlists/english.dart' as bip39wordlist;
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_libmonero/monero/monero.dart';
+import 'package:flutter_libmonero/wownero/wownero.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
@@ -149,13 +150,17 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
     super.dispose();
   }
 
-  // TODO: check for wownero wordlist?
   bool _isValidMnemonicWord(String word) {
     // TODO: get the actual language
     if (widget.coin == Coin.monero) {
       var moneroWordList = monero.getMoneroWordList("English");
       return moneroWordList.contains(word);
     }
+    if (widget.coin == Coin.wownero) {
+      var wowneroWordList = wownero.getWowneroWordList("English",
+          seedWordsLength: widget.seedWordsLength);
+      return wowneroWordList.contains(word);
+    }
     return _wordListHashSet.contains(word);
   }
 

From a94e66da9eec4ea809cc8b4a09e717c4fc852e62 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 8 Nov 2022 19:07:18 -0600
Subject: [PATCH 176/426] temp disable wow 25 word option in ui

---
 lib/utilities/constants.dart | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart
index e27fbaa3d..e170dad2a 100644
--- a/lib/utilities/constants.dart
+++ b/lib/utilities/constants.dart
@@ -62,7 +62,9 @@ abstract class Constants {
         values.addAll([25]);
         break;
       case Coin.wownero:
-        values.addAll([14, 25]);
+        values.addAll([14]);
+        // todo: uncomment when wownero 25 word seeds implemented
+        // values.addAll([14, 25]);
         break;
     }
     return values;

From a54d9a561e50593b6fe13a204776d631f7545f77 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Tue, 8 Nov 2022 23:10:27 -0600
Subject: [PATCH 177/426] track changes in flutter_libmonero

---
 crypto_plugins/flutter_libmonero | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index e440e9a3a..9267fd0f0 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit e440e9a3a125ee2030551ad7dea9114dd6a06aa0
+Subproject commit 9267fd0f0442a8d54b899473d77fc92ddc6d2391

From 357b93d6e897a2ece44eacdee8c32eac578177df Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 9 Nov 2022 00:16:21 -0600
Subject: [PATCH 178/426] use wownero.getHeightByDate

and save bufferedHeight upon Monero wallet creation
---
 crypto_plugins/flutter_libmonero              |  2 +-
 .../restore_wallet_view.dart                  |  6 ++---
 lib/services/coins/monero/monero_wallet.dart  |  2 +-
 .../coins/wownero/wownero_wallet.dart         | 23 +++++++++++++------
 4 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index 9267fd0f0..e705ba2d5 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit 9267fd0f0442a8d54b899473d77fc92ddc6d2391
+Subproject commit e705ba2d5126685adae9367b62921b676d7126ed
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
index 7596d7ac8..913302a98 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
@@ -186,11 +186,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
 
       if (widget.coin == Coin.monero) {
         height = monero.getHeigthByDate(date: widget.restoreFromDate);
+      } else if (widget.coin == Coin.wownero) {
+        height = wownero.getHeightByDate(date: widget.restoreFromDate);
       }
-      // todo: wait until this implemented
-      // else if (widget.coin == Coin.wownero) {
-      //   height = wownero.getHeightByDate(date: widget.restoreFromDate);
-      // }
 
       // TODO: make more robust estimate of date maybe using https://explorer.epic.tech/api-index
       if (widget.coin == Coin.epicCash) {
diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index b0ebac4e6..8e7873014 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -699,7 +699,7 @@ class MoneroWallet extends CoinServiceAPI {
           name: name,
           type: WalletType.monero,
           isRecovery: false,
-          restoreHeight: credentials.height ?? 0,
+          restoreHeight: bufferedCreateHeight,
           date: DateTime.now(),
           path: path,
           dirPath: dirPath,
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 55f43cdd1..0134cb1fe 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -1,6 +1,7 @@
 import 'dart:async';
 import 'dart:io';
 
+import 'package:cw_core/get_height_by_date.dart';
 import 'package:cw_core/monero_transaction_priority.dart';
 import 'package:cw_core/node.dart';
 import 'package:cw_core/pending_transaction.dart';
@@ -685,10 +686,7 @@ class WowneroWallet extends CoinServiceAPI {
           await pathForWalletDir(name: name, type: WalletType.wownero);
       final path = await pathForWallet(name: name, type: WalletType.wownero);
       credentials = wownero.createWowneroNewWalletCredentials(
-        name: name,
-        language: "English",
-        seedWordsLength: seedWordsLength
-      );
+          name: name, language: "English", seedWordsLength: seedWordsLength);
 
       walletInfo = WalletInfo.external(
           id: WalletBase.idFor(name, WalletType.wownero),
@@ -713,9 +711,12 @@ class WowneroWallet extends CoinServiceAPI {
       // To restore from a seed
       final wallet = await _walletCreationService?.create(credentials);
 
-      // subtract a couple days to ensure we have a buffer for SWB
-      final bufferedCreateHeight = (seedWordsLength == 14) ? getSeedHeightSync(wallet?.seed.trim() as String) : 0;
-      // TODO use an alternative to wow_seed's get_seed_height instead of 0 above
+      final bufferedCreateHeight = (seedWordsLength == 14)
+          ? getSeedHeightSync(wallet?.seed.trim() as String)
+          : wownero.getHeightByDate(
+              date: DateTime.now().subtract(const Duration(
+                  days:
+                      2))); // subtract a couple days to ensure we have a buffer for SWB
 
       await DB.instance.put<dynamic>(
           boxName: walletId, key: "restoreHeight", value: bufferedCreateHeight);
@@ -979,6 +980,14 @@ class WowneroWallet extends CoinServiceAPI {
       // extract seed height from 14 word seed
       if (seedLength == 14) {
         height = getSeedHeightSync(mnemonic.trim());
+      } else {
+        // 25 word seed. TODO validate
+        if (height == 0) {
+          height = wownero.getHeightByDate(
+              date: DateTime.now().subtract(const Duration(
+                  days:
+                      2))); // subtract a couple days to ensure we have a buffer for SWB\
+        }
       }
 
       await DB.instance

From 510233255f7a75b8f881754d5f60b2e0379272ff Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 9 Nov 2022 09:46:59 -0600
Subject: [PATCH 179/426] desktop swb restore fix

---
 .../restore_from_file_view.dart               | 76 ++++++++++---------
 1 file changed, 42 insertions(+), 34 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index f7a9883de..014099abd 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -1,3 +1,4 @@
+import 'dart:async';
 import 'dart:io';
 
 import 'package:flutter/foundation.dart';
@@ -424,43 +425,47 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                                   }
 
                                   bool shouldPop = false;
-                                  await showDialog<dynamic>(
-                                    barrierDismissible: false,
-                                    context: context,
-                                    builder: (_) => WillPopScope(
-                                      onWillPop: () async {
-                                        return shouldPop;
-                                      },
-                                      child: Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.stretch,
-                                        mainAxisAlignment:
-                                            MainAxisAlignment.center,
-                                        children: [
-                                          Material(
-                                            color: Colors.transparent,
-                                            child: Center(
-                                              child: Text(
-                                                "Decrypting Stack backup file",
-                                                style: STextStyles.pageTitleH2(
-                                                        context)
-                                                    .copyWith(
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .textWhite,
+                                  unawaited(
+                                    showDialog<dynamic>(
+                                      barrierDismissible: false,
+                                      context: context,
+                                      builder: (_) => WillPopScope(
+                                        onWillPop: () async {
+                                          return shouldPop;
+                                        },
+                                        child: Column(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.stretch,
+                                          mainAxisAlignment:
+                                              MainAxisAlignment.center,
+                                          children: [
+                                            Material(
+                                              color: Colors.transparent,
+                                              child: Center(
+                                                child: Text(
+                                                  "Decrypting Stack backup file",
+                                                  style:
+                                                      STextStyles.pageTitleH2(
+                                                              context)
+                                                          .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textWhite,
+                                                  ),
                                                 ),
                                               ),
                                             ),
-                                          ),
-                                          const SizedBox(
-                                            height: 64,
-                                          ),
-                                          const Center(
-                                            child: LoadingIndicator(
-                                              width: 100,
+                                            const SizedBox(
+                                              height: 64,
                                             ),
-                                          ),
-                                        ],
+                                            const Center(
+                                              child: LoadingIndicator(
+                                                width: 100,
+                                              ),
+                                            ),
+                                          ],
+                                        ),
                                       ),
                                     ),
                                   );
@@ -475,7 +480,10 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                                   if (mounted) {
                                     // pop LoadingIndicator
                                     shouldPop = true;
-                                    Navigator.of(context).pop();
+                                    Navigator.of(
+                                      context,
+                                      rootNavigator: true,
+                                    ).pop();
 
                                     passwordController.text = "";
 

From 041e23a5a5a18682daf352bab79242fb654a6403 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 9 Nov 2022 08:57:41 -0700
Subject: [PATCH 180/426] resolved route_generator conflict

---
 .../desktop_address_book.dart                 | 139 ++++++++++++++++++
 .../home/desktop_home_view.dart               |   8 +-
 lib/route_generator.dart                      |   7 +
 3 files changed, 152 insertions(+), 2 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart

diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
new file mode 100644
index 000000000..3622fcf1e
--- /dev/null
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -0,0 +1,139 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.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 DesktopAddressBook extends ConsumerStatefulWidget {
+  const DesktopAddressBook({Key? key}) : super(key: key);
+
+  static const String routeName = "/desktopAddressBook";
+
+  @override
+  ConsumerState<DesktopAddressBook> createState() => _DesktopAddressBook();
+}
+
+class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
+  late final TextEditingController _searchController;
+
+  late final FocusNode _searchFocusNode;
+
+  String filter = "";
+
+  @override
+  void initState() {
+    _searchController = TextEditingController();
+    _searchFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _searchController.dispose();
+    _searchFocusNode.dispose();
+
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+    final hasWallets = ref.watch(walletsChangeNotifierProvider).hasWallets;
+
+    return Column(
+      mainAxisSize: MainAxisSize.min,
+      children: [
+        DesktopAppBar(
+          isCompactHeight: true,
+          leading: Row(
+            children: [
+              const SizedBox(
+                width: 24,
+              ),
+              Text(
+                "Address Book",
+                style: STextStyles.desktopH3(context),
+              )
+            ],
+          ),
+        ),
+        const SizedBox(height: 53),
+        Padding(
+          padding: const EdgeInsets.symmetric(horizontal: 24),
+          child: Row(
+            children: [
+              SizedBox(
+                height: 60,
+                width: 489,
+                child: ClipRRect(
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
+                  child: TextField(
+                    autocorrect: false,
+                    enableSuggestions: false,
+                    controller: _searchController,
+                    focusNode: _searchFocusNode,
+                    onChanged: (newString) {
+                      setState(() => filter = newString);
+                    },
+                    style: STextStyles.field(context),
+                    decoration: standardInputDecoration(
+                      "Search...",
+                      _searchFocusNode,
+                      context,
+                    ).copyWith(
+                      labelStyle: STextStyles.fieldLabel(context)
+                          .copyWith(fontSize: 16),
+                      prefixIcon: Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 10,
+                          vertical: 16,
+                        ),
+                        child: SvgPicture.asset(
+                          Assets.svg.search,
+                          width: 16,
+                          height: 16,
+                        ),
+                      ),
+                      suffixIcon: _searchController.text.isNotEmpty
+                          ? Padding(
+                              padding: const EdgeInsets.only(right: 0),
+                              child: UnconstrainedBox(
+                                child: Row(
+                                  children: [
+                                    TextFieldIconButton(
+                                      child: const XIcon(),
+                                      onTap: () async {
+                                        setState(() {
+                                          _searchController.text = "";
+                                          filter = "";
+                                        });
+                                      },
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            )
+                          : null,
+                    ),
+                  ),
+                ),
+              ),
+            ],
+          ),
+        ),
+        // Expanded(
+        //   child: hasWallets ? const MyWallets() : const EmptyWallets(),
+        // ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index 14d2dae03..fab78e1f4 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -8,6 +8,8 @@ import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/d
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
+import 'address_book_view/desktop_address_book.dart';
+
 class DesktopHomeView extends ConsumerStatefulWidget {
   const DesktopHomeView({Key? key}) : super(key: key);
 
@@ -31,8 +33,10 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
     Container(
       color: Colors.red,
     ),
-    Container(
-      color: Colors.orange,
+    const Navigator(
+      key: Key("desktopAddressBookHomeKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: DesktopAddressBook.routeName,
     ),
     const Navigator(
       key: Key("desktopSettingHomeKey"),
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 30963781b..f3e37e383 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -86,6 +86,7 @@ import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
 import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
 import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
 import 'package:stackwallet/pages_desktop_specific/forgot_password_desktop_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/address_book_view/desktop_address_book.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
@@ -1105,6 +1106,12 @@ class RouteGenerator {
             builder: (_) => const DesktopAboutView(),
             settings: RouteSettings(name: settings.name));
 
+      case DesktopAddressBook.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const DesktopAddressBook(),
+            settings: RouteSettings(name: settings.name));
+
       case WalletKeysDesktopPopup.routeName:
         if (args is List<String>) {
           return FadePageRoute(

From 095f9c4ed9a7d692047131e1bdc043043822971e Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 9 Nov 2022 12:54:10 -0600
Subject: [PATCH 181/426] mobile swb restore unawaited

---
 .../restore_from_file_view.dart               | 67 ++++++++++---------
 1 file changed, 35 insertions(+), 32 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index 014099abd..a237d9ea9 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -316,42 +316,45 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                               }
 
                               bool shouldPop = false;
-                              await showDialog<dynamic>(
-                                barrierDismissible: false,
-                                context: context,
-                                builder: (_) => WillPopScope(
-                                  onWillPop: () async {
-                                    return shouldPop;
-                                  },
-                                  child: Column(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.stretch,
-                                    mainAxisAlignment: MainAxisAlignment.center,
-                                    children: [
-                                      Material(
-                                        color: Colors.transparent,
-                                        child: Center(
-                                          child: Text(
-                                            "Decrypting Stack backup file",
-                                            style:
-                                                STextStyles.pageTitleH2(context)
-                                                    .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textWhite,
+                              unawaited(
+                                showDialog<dynamic>(
+                                  barrierDismissible: false,
+                                  context: context,
+                                  builder: (_) => WillPopScope(
+                                    onWillPop: () async {
+                                      return shouldPop;
+                                    },
+                                    child: Column(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.stretch,
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.center,
+                                      children: [
+                                        Material(
+                                          color: Colors.transparent,
+                                          child: Center(
+                                            child: Text(
+                                              "Decrypting Stack backup file",
+                                              style: STextStyles.pageTitleH2(
+                                                      context)
+                                                  .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textWhite,
+                                              ),
                                             ),
                                           ),
                                         ),
-                                      ),
-                                      const SizedBox(
-                                        height: 64,
-                                      ),
-                                      const Center(
-                                        child: LoadingIndicator(
-                                          width: 100,
+                                        const SizedBox(
+                                          height: 64,
                                         ),
-                                      ),
-                                    ],
+                                        const Center(
+                                          child: LoadingIndicator(
+                                            width: 100,
+                                          ),
+                                        ),
+                                      ],
+                                    ),
                                   ),
                                 ),
                               );

From d15f022c4d6d86c5341972fb6c4824b24a01a503 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Wed, 9 Nov 2022 14:09:12 -0600
Subject: [PATCH 182/426] update wownero's first blocks per month

---
 crypto_plugins/flutter_libmonero | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index e705ba2d5..b9bc2dcc5 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit e705ba2d5126685adae9367b62921b676d7126ed
+Subproject commit b9bc2dcc56e13f235a6c5b0fc02c0e543eb87758

From 61f945aa98e8bb47858155556c37c1fd12585299 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 9 Nov 2022 13:13:42 -0700
Subject: [PATCH 183/426] dialog uses BackupFrequencyTypes and has offset for
 dropDownButton

---
 .../create_auto_backup.dart                   | 136 ++++++++++++------
 1 file changed, 93 insertions(+), 43 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 57a8d7a64..07a1f1b78 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -1,11 +1,14 @@
 import 'dart:io';
 
+import 'package:dropdown_button2/dropdown_button2.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/enums/log_level_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -19,14 +22,14 @@ import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:zxcvbn/zxcvbn.dart';
 
-class CreateAutoBackup extends StatefulWidget {
+class CreateAutoBackup extends ConsumerStatefulWidget {
   const CreateAutoBackup({Key? key}) : super(key: key);
 
   @override
-  State<StatefulWidget> createState() => _CreateAutoBackup();
+  ConsumerState<CreateAutoBackup> createState() => _CreateAutoBackup();
 }
 
-class _CreateAutoBackup extends State<CreateAutoBackup> {
+class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
   late final TextEditingController fileLocationController;
   late final TextEditingController passphraseController;
   late final TextEditingController passphraseRepeatController;
@@ -52,12 +55,13 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
   bool get fieldsMatch =>
       passphraseController.text == passphraseRepeatController.text;
 
-  String _currentDropDownValue = "Every 10 minutes";
+  BackupFrequencyType _currentDropDownValue =
+      BackupFrequencyType.everyTenMinutes;
 
-  final List<String> _dropDownItems = [
-    "Every 10 minutes",
-    "Every 20 minutes",
-    "Every 30 minutes",
+  final List<BackupFrequencyType> _dropDownItems = [
+    BackupFrequencyType.everyTenMinutes,
+    BackupFrequencyType.everyAppStart,
+    BackupFrequencyType.afterClosingAWallet,
   ];
 
   @override
@@ -101,6 +105,9 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType ");
 
+    bool isEnabledAutoBackup = ref.watch(prefsChangeNotifierProvider
+        .select((value) => value.isAutoBackupEnabled));
+
     String? selectedItem = "Every 10 minutes";
     final isDesktop = Util.isDesktop;
     return DesktopDialog(
@@ -225,9 +232,7 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
                           paste: false,
                           selectAll: false,
                         ),
-                        onChanged: (newValue) {
-                          // ref.read(addressEntryDataProvider(widget.id)).address = newValue;
-                        },
+                        onChanged: (newValue) {},
                       ),
                     );
                   }),
@@ -361,7 +366,7 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
                     ),
                     child: ProgressBar(
                       key: const Key("createStackBackUpProgressBar"),
-                      width: 510,
+                      width: 512,
                       height: 5,
                       fillColor: passwordStrength < 0.51
                           ? Theme.of(context)
@@ -465,38 +470,83 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
               left: 32,
               right: 32,
             ),
-            child: DropdownButtonFormField(
-              isExpanded: true,
-              elevation: 0,
-              style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                color: Theme.of(context).extension<StackColors>()!.textDark,
-              ),
-              icon: SvgPicture.asset(
-                Assets.svg.chevronDown,
-                width: 10,
-                height: 5,
-                color: Theme.of(context).extension<StackColors>()!.textDark3,
-              ),
-              dropdownColor:
-                  Theme.of(context).extension<StackColors>()!.textFieldActiveBG,
-              // focusColor: ,
-              value: _currentDropDownValue,
-              items: _dropDownItems
-                  .map(
-                    (e) => DropdownMenuItem(
-                      value: e,
-                      child: Text(e),
+            child: isDesktop
+                ? DropdownButtonHideUnderline(
+                    child: DropdownButton2(
+                      offset: Offset(0, -10),
+                      isExpanded: true,
+                      dropdownElevation: 0,
+                      value: _currentDropDownValue,
+                      items: [
+                        ..._dropDownItems.map(
+                          (e) {
+                            String message = "";
+                            switch (e) {
+                              case BackupFrequencyType.everyTenMinutes:
+                                message = "Every 10 minutes";
+                                break;
+                              case BackupFrequencyType.everyAppStart:
+                                message = "Every app startup";
+                                break;
+                              case BackupFrequencyType.afterClosingAWallet:
+                                message =
+                                    "After closing a cryptocurrency wallet";
+                                break;
+                            }
+
+                            return DropdownMenuItem(
+                              value: e,
+                              child: Text(message),
+                            );
+                          },
+                        ),
+                      ],
+                      onChanged: (value) {
+                        if (value is BackupFrequencyType) {
+                          if (ref
+                                  .read(prefsChangeNotifierProvider)
+                                  .backupFrequencyType !=
+                              value) {
+                            ref
+                                .read(prefsChangeNotifierProvider)
+                                .backupFrequencyType = value;
+                          }
+                          setState(() {
+                            _currentDropDownValue = value;
+                          });
+                        }
+                      },
+                      icon: SvgPicture.asset(
+                        Assets.svg.chevronDown,
+                        width: 10,
+                        height: 5,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark3,
+                      ),
+                      buttonPadding: const EdgeInsets.symmetric(
+                        horizontal: 16,
+                        vertical: 8,
+                      ),
+                      buttonDecoration: BoxDecoration(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                      ),
+                      dropdownDecoration: BoxDecoration(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                      ),
                     ),
                   )
-                  .toList(),
-              onChanged: (value) {
-                if (value is String) {
-                  setState(() {
-                    _currentDropDownValue = value;
-                  });
-                }
-              },
-            ),
+                : null,
           ),
           const Spacer(),
           Padding(
@@ -518,7 +568,7 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
                 Expanded(
                   child: PrimaryButton(
                     label: "Enable Auto Backup",
-                    enabled: false,
+                    enabled: shouldEnableCreate,
                     onPressed: () {},
                   ),
                 )

From cc779be46031b2491ad817af592d7d9266b1598b Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 9 Nov 2022 15:32:39 -0700
Subject: [PATCH 184/426] enable and disable auto back up

---
 .../backup_and_restore_settings.dart          | 235 +++++++++++++++++-
 .../create_auto_backup.dart                   | 180 +++++++++++++-
 lib/widgets/stack_dialog.dart                 |  18 +-
 3 files changed, 415 insertions(+), 18 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 8928a268d..a444f4b51 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -2,15 +2,27 @@ import 'package:flutter/gestures.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
+import 'package:intl/intl.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart';
+import 'package:stackwallet/providers/global/locale_provider.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
+import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:url_launcher/url_launcher.dart';
 
+import '../../../../providers/global/auto_swb_service_provider.dart';
+import '../../../../widgets/custom_buttons/blue_text_button.dart';
+
 class BackupRestoreSettings extends ConsumerStatefulWidget {
   const BackupRestoreSettings({Key? key}) : super(key: key);
 
@@ -24,6 +36,49 @@ class BackupRestoreSettings extends ConsumerStatefulWidget {
 class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
   late bool createBackup = false;
   late bool restoreBackup = false;
+  // late bool isEnabledAutoBackup;
+
+  final toggleController = DSBController();
+
+  late final TextEditingController fileLocationController;
+  late final TextEditingController passwordController;
+  late final TextEditingController frequencyController;
+
+  late final FocusNode fileLocationFocusNode;
+  late final FocusNode passwordFocusNode;
+
+  String prettySinceLastBackupString(DateTime? time) {
+    if (time == null) {
+      return "-";
+    }
+    final difference = DateTime.now().difference(time);
+    int value;
+    String postfix;
+    if (difference < const Duration(seconds: 60)) {
+      value = difference.inSeconds;
+      postfix = "seconds";
+    } else if (difference < const Duration(minutes: 60)) {
+      value = difference.inMinutes;
+      postfix = "minutes";
+    } else if (difference < const Duration(hours: 24)) {
+      value = difference.inHours;
+      postfix = "hours";
+    } else if (difference.inDays < 8) {
+      value = difference.inDays;
+      postfix = "days";
+    } else {
+      // if greater than a week return the actual date
+      return DateFormat.yMMMMd(
+              ref.read(localeServiceChangeNotifierProvider).locale)
+          .format(time);
+    }
+
+    if (value == 1) {
+      postfix = postfix.substring(0, postfix.length - 1);
+    }
+
+    return "$value $postfix ago";
+  }
 
   Future<void> enableAutoBackup(BuildContext context) async {
     await showDialog<dynamic>(
@@ -36,10 +91,105 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
     );
   }
 
+  Future<void> attemptDisable() async {
+    final result = await showDialog<bool?>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) {
+        return StackDialog(
+          title: "Disable Auto Backup",
+          message:
+              "You are turning off Auto Backup. You can turn it back on at any time. Your previous Auto Backup file will not be deleted. Remember to backup your wallets manually so you don't lose important information.",
+          leftButton: TextButton(
+            style: Theme.of(context)
+                .extension<StackColors>()!
+                .getSecondaryEnabledButtonColor(context),
+            child: Text(
+              "Back",
+              style: STextStyles.button(context).copyWith(
+                color:
+                    Theme.of(context).extension<StackColors>()!.accentColorDark,
+              ),
+            ),
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          rightButton: TextButton(
+            style: Theme.of(context)
+                .extension<StackColors>()!
+                .getPrimaryEnabledButtonColor(context),
+            child: Text(
+              "Disable",
+              style: STextStyles.button(context),
+            ),
+            onPressed: () {
+              Navigator.of(context).pop();
+              setState(() {
+                ref.watch(prefsChangeNotifierProvider).isAutoBackupEnabled =
+                    false;
+              });
+            },
+          ),
+        );
+      },
+    );
+    if (mounted) {
+      if (result is bool && result) {
+        ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled = false;
+        Navigator.of(context).pop();
+      } else {
+        toggleController.activate?.call();
+      }
+    }
+  }
+
+  @override
+  void initState() {
+    fileLocationController = TextEditingController();
+    passwordController = TextEditingController();
+    frequencyController = TextEditingController();
+
+    passwordController.text = "---------------";
+    fileLocationController.text =
+        ref.read(prefsChangeNotifierProvider).autoBackupLocation ?? " ";
+    frequencyController.text = Format.prettyFrequencyType(
+        ref.read(prefsChangeNotifierProvider).backupFrequencyType);
+
+    fileLocationFocusNode = FocusNode();
+    passwordFocusNode = FocusNode();
+
+    // _toggle = ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled;
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    fileLocationController.dispose();
+    passwordController.dispose();
+    frequencyController.dispose();
+
+    fileLocationFocusNode.dispose();
+    passwordFocusNode.dispose();
+
+    super.dispose();
+  }
+
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
+    bool isEnabledAutoBackup = ref.watch(prefsChangeNotifierProvider
+        .select((value) => value.isAutoBackupEnabled));
+
+    ref.listen(
+        prefsChangeNotifierProvider
+            .select((value) => value.backupFrequencyType),
+        (previous, BackupFrequencyType next) {
+      frequencyController.text = Format.prettyFrequencyType(next);
+    });
+
     return LayoutBuilder(builder: (context, constraints) {
       return SingleChildScrollView(
           scrollDirection: Axis.vertical,
@@ -120,17 +270,80 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                             crossAxisAlignment: CrossAxisAlignment.start,
                             children: [
                               Padding(
-                                padding: EdgeInsets.all(
-                                  10,
-                                ),
-                                child: PrimaryButton(
-                                  desktopMed: true,
-                                  width: 200,
-                                  label: "Enable auto backup",
-                                  onPressed: () {
-                                    enableAutoBackup(context);
-                                  },
-                                ),
+                                padding: const EdgeInsets.all(10),
+                                child: !isEnabledAutoBackup
+                                    ? PrimaryButton(
+                                        desktopMed: true,
+                                        width: 200,
+                                        label: "Enable auto backup",
+                                        onPressed: () {
+                                          enableAutoBackup(context);
+                                        },
+                                      )
+                                    : Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          Container(
+                                            width: 403,
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .background,
+                                            child: Padding(
+                                              padding:
+                                                  const EdgeInsets.all(8.0),
+                                              child: Column(
+                                                children: [
+                                                  Row(
+                                                    mainAxisAlignment:
+                                                        MainAxisAlignment
+                                                            .spaceBetween,
+                                                    children: [
+                                                      Text(
+                                                        "Backed up ${prettySinceLastBackupString(ref.watch(prefsChangeNotifierProvider.select((value) => value.lastAutoBackup)))}",
+                                                        style: STextStyles
+                                                            .itemSubtitle(
+                                                                context),
+                                                      ),
+                                                      BlueTextButton(
+                                                        text: "Back up now",
+                                                        onTap: () {
+                                                          ref
+                                                              .read(
+                                                                  autoSWBServiceProvider)
+                                                              .doBackup();
+                                                        },
+                                                      ),
+                                                    ],
+                                                  ),
+                                                ],
+                                              ),
+                                            ),
+                                          ),
+                                          const SizedBox(
+                                            height: 20,
+                                          ),
+                                          Row(
+                                            children: [
+                                              PrimaryButton(
+                                                desktopMed: true,
+                                                width: 190,
+                                                label: "Disable auto backup",
+                                                onPressed: () {
+                                                  attemptDisable();
+                                                },
+                                              ),
+                                              const SizedBox(width: 16),
+                                              SecondaryButton(
+                                                desktopMed: true,
+                                                width: 190,
+                                                label: "Edit auto backup",
+                                                onPressed: () {},
+                                              ),
+                                            ],
+                                          )
+                                        ],
+                                      ),
                               ),
                             ],
                           ),
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 07a1f1b78..e804071cc 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -1,15 +1,24 @@
+import 'dart:convert';
 import 'dart:io';
 
 import 'package:dropdown_button2/dropdown_button2.dart';
+import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stack_wallet_backup/stack_wallet_backup.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
+import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/enums/log_level_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/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -19,11 +28,19 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
+import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:zxcvbn/zxcvbn.dart';
 
 class CreateAutoBackup extends ConsumerStatefulWidget {
-  const CreateAutoBackup({Key? key}) : super(key: key);
+  const CreateAutoBackup({
+    Key? key,
+    this.secureStore = const SecureStorageWrapper(
+      FlutterSecureStorage(),
+    ),
+  }) : super(key: key);
+
+  final FlutterSecureStorageInterface secureStore;
 
   @override
   ConsumerState<CreateAutoBackup> createState() => _CreateAutoBackup();
@@ -34,6 +51,8 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
   late final TextEditingController passphraseController;
   late final TextEditingController passphraseRepeatController;
 
+  late final FlutterSecureStorageInterface secureStore;
+
   late final StackFileSystem stackFileSystem;
   late final FocusNode passphraseFocusNode;
   late final FocusNode passphraseRepeatFocusNode;
@@ -66,6 +85,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
 
   @override
   void initState() {
+    secureStore = widget.secureStore;
     stackFileSystem = StackFileSystem();
 
     fileLocationController = TextEditingController();
@@ -569,7 +589,163 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                   child: PrimaryButton(
                     label: "Enable Auto Backup",
                     enabled: shouldEnableCreate,
-                    onPressed: () {},
+                    onPressed: !shouldEnableCreate
+                        ? null
+                        : () async {
+                            final String pathToSave =
+                                fileLocationController.text;
+                            final String passphrase = passphraseController.text;
+                            final String repeatPassphrase =
+                                passphraseRepeatController.text;
+
+                            if (pathToSave.isEmpty) {
+                              showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "Directory not chosen",
+                                context: context,
+                              );
+                              return;
+                            }
+                            if (!(await Directory(pathToSave).exists())) {
+                              showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "Directory does not exist",
+                                context: context,
+                              );
+                              return;
+                            }
+                            if (passphrase.isEmpty) {
+                              showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "A passphrase is required",
+                                context: context,
+                              );
+                              return;
+                            }
+                            if (passphrase != repeatPassphrase) {
+                              showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "Passphrase does not match",
+                                context: context,
+                              );
+                              return;
+                            }
+
+                            showDialog<dynamic>(
+                              context: context,
+                              barrierDismissible: false,
+                              builder: (_) => const StackDialog(
+                                title: "Encrypting initial backup",
+                                message: "This shouldn't take long",
+                              ),
+                            );
+
+                            // make sure the dialog is able to be displayed for at least some time
+                            final fut = Future<void>.delayed(
+                                const Duration(milliseconds: 300));
+
+                            String adkString;
+                            int adkVersion;
+                            try {
+                              final adk =
+                                  await compute(generateAdk, passphrase);
+                              adkString = Format.uint8listToString(adk.item2);
+                              adkVersion = adk.item1;
+                            } on Exception catch (e, s) {
+                              String err = getErrorMessageFromSWBException(e);
+                              Logging.instance
+                                  .log("$err\n$s", level: LogLevel.Error);
+                              // pop encryption progress dialog
+                              Navigator.of(context).pop();
+                              showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: err,
+                                context: context,
+                              );
+                              return;
+                            } catch (e, s) {
+                              Logging.instance
+                                  .log("$e\n$s", level: LogLevel.Error);
+                              // pop encryption progress dialog
+                              Navigator.of(context).pop();
+                              showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "$e",
+                                context: context,
+                              );
+                              return;
+                            }
+
+                            await secureStore.write(
+                                key: "auto_adk_string", value: adkString);
+                            await secureStore.write(
+                                key: "auto_adk_version_string",
+                                value: adkVersion.toString());
+
+                            final DateTime now = DateTime.now();
+                            final String fileToSave =
+                                createAutoBackupFilename(pathToSave, now);
+
+                            final backup = await SWB.createStackWalletJSON();
+
+                            bool result = await SWB.encryptStackWalletWithADK(
+                              fileToSave,
+                              adkString,
+                              jsonEncode(backup),
+                              adkVersion: adkVersion,
+                            );
+
+                            // this future should already be complete unless there was an error encrypting
+                            await Future.wait([fut]);
+
+                            if (mounted) {
+                              // pop encryption progress dialog
+                              int count = 0;
+                              Navigator.of(context)
+                                  .popUntil((_) => count++ >= 2);
+
+                              if (result) {
+                                ref
+                                    .read(prefsChangeNotifierProvider)
+                                    .autoBackupLocation = pathToSave;
+                                ref
+                                    .read(prefsChangeNotifierProvider)
+                                    .lastAutoBackup = now;
+
+                                ref
+                                    .read(prefsChangeNotifierProvider)
+                                    .isAutoBackupEnabled = true;
+
+                                await showDialog<dynamic>(
+                                  context: context,
+                                  barrierDismissible: false,
+                                  builder: (_) => Platform.isAndroid
+                                      ? StackOkDialog(
+                                          title:
+                                              "Stack Auto Backup enabled and saved to:",
+                                          message: fileToSave,
+                                        )
+                                      : const StackOkDialog(
+                                          title: "Stack Auto Backup enabled!"),
+                                );
+                                if (mounted) {
+                                  passphraseController.text = "";
+                                  passphraseRepeatController.text = "";
+
+                                  int count = 0;
+                                  Navigator.of(context)
+                                      .popUntil((_) => count++ >= 2);
+                                }
+                              } else {
+                                await showDialog<dynamic>(
+                                  context: context,
+                                  barrierDismissible: false,
+                                  builder: (_) => const StackOkDialog(
+                                      title: "Failed to enable Auto Backup"),
+                                );
+                              }
+                            }
+                          },
                   ),
                 )
               ],
diff --git a/lib/widgets/stack_dialog.dart b/lib/widgets/stack_dialog.dart
index be1d51596..ea2638264 100644
--- a/lib/widgets/stack_dialog.dart
+++ b/lib/widgets/stack_dialog.dart
@@ -1,6 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
 
 class StackDialogBase extends StatelessWidget {
   const StackDialogBase({
@@ -17,7 +18,8 @@ class StackDialogBase extends StatelessWidget {
     return Padding(
       padding: const EdgeInsets.all(16),
       child: Column(
-        mainAxisAlignment: MainAxisAlignment.end,
+        mainAxisAlignment:
+            !Util.isDesktop ? MainAxisAlignment.end : MainAxisAlignment.center,
         children: [
           Material(
             borderRadius: BorderRadius.circular(
@@ -179,10 +181,16 @@ class StackOkDialog extends StatelessWidget {
               ),
               Expanded(
                 child: TextButton(
-                  onPressed: () {
-                    Navigator.of(context).pop();
-                    onOkPressed?.call("OK");
-                  },
+                  onPressed: !Util.isDesktop
+                      ? () {
+                          Navigator.of(context).pop();
+                          onOkPressed?.call("OK");
+                        }
+                      : () {
+                          int count = 0;
+                          Navigator.of(context).popUntil((_) => count++ >= 2);
+                          // onOkPressed?.call("OK");
+                        },
                   style: Theme.of(context)
                       .extension<StackColors>()!
                       .getPrimaryEnabledButtonColor(context),

From 6d0452debb939df3e95f34082eacb4dc7a5712a7 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 9 Nov 2022 16:23:53 -0700
Subject: [PATCH 185/426] small import fix

---
 lib/pages_desktop_specific/home/desktop_home_view.dart | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index fab78e1f4..cb8aba255 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages_desktop_specific/home/address_book_view/desktop_address_book.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_menu.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
@@ -8,8 +9,6 @@ import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/d
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
-import 'address_book_view/desktop_address_book.dart';
-
 class DesktopHomeView extends ConsumerStatefulWidget {
   const DesktopHomeView({Key? key}) : super(key: key);
 

From af47c67231eeb6cb1d04f2740a50847af55f9610 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 9 Nov 2022 12:58:38 -0600
Subject: [PATCH 186/426] BranchedParent class

---
 lib/widgets/conditional_parent.dart | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/lib/widgets/conditional_parent.dart b/lib/widgets/conditional_parent.dart
index 757c8f992..e8c60884a 100644
--- a/lib/widgets/conditional_parent.dart
+++ b/lib/widgets/conditional_parent.dart
@@ -21,3 +21,27 @@ class ConditionalParent extends StatelessWidget {
     }
   }
 }
+
+class BranchedParent extends StatelessWidget {
+  const BranchedParent({
+    Key? key,
+    required this.condition,
+    required this.conditionBranchBuilder,
+    required this.otherBranchBuilder,
+    required this.children,
+  }) : super(key: key);
+
+  final bool condition;
+  final Widget Function(List<Widget>) conditionBranchBuilder;
+  final Widget Function(List<Widget>) otherBranchBuilder;
+  final List<Widget> children;
+
+  @override
+  Widget build(BuildContext context) {
+    if (condition) {
+      return conditionBranchBuilder(children);
+    } else {
+      return otherBranchBuilder(children);
+    }
+  }
+}

From 2aa8dd2becce6c7dd39845273f6fc008db4f5ead Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 9 Nov 2022 13:12:41 -0600
Subject: [PATCH 187/426] WIP: trade details for desktop

---
 .../exchange_view/trade_details_view.dart     | 1315 ++++++++++-------
 .../sub_widgets/transactions_list.dart        |   87 +-
 2 files changed, 872 insertions(+), 530 deletions(-)

diff --git a/lib/pages/exchange_view/trade_details_view.dart b/lib/pages/exchange_view/trade_details_view.dart
index 76c845027..602d588da 100644
--- a/lib/pages/exchange_view/trade_details_view.dart
+++ b/lib/pages/exchange_view/trade_details_view.dart
@@ -15,17 +15,23 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.d
 import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
 import 'package:stackwallet/providers/global/trades_service_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
 import 'package:stackwallet/services/exchange/exchange.dart';
 import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.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/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -157,34 +163,113 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
     final sendAmount =
         Decimal.tryParse(trade.payInAmount) ?? Decimal.parse("-1");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
+    final isDesktop = Util.isDesktop;
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Scaffold(
         backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
+        appBar: AppBar(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          leading: AppBarBackButton(
+            onPressed: () async {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Trade details",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Trade details",
-          style: STextStyles.navBarTitle(context),
+        body: Padding(
+          padding: const EdgeInsets.all(12),
+          child: SingleChildScrollView(
+            child: Padding(
+              padding: const EdgeInsets.all(4),
+              child: child,
+            ),
+          ),
         ),
       ),
-      body: Padding(
-        padding: const EdgeInsets.all(12),
-        child: SingleChildScrollView(
-          child: Padding(
-            padding: const EdgeInsets.all(4),
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.stretch,
-              children: [
-                RoundedWhiteContainer(
+      child: Padding(
+        padding: isDesktop
+            ? const EdgeInsets.only(left: 32)
+            : const EdgeInsets.all(0),
+        child: BranchedParent(
+          condition: isDesktop,
+          conditionBranchBuilder: (children) => Padding(
+            padding: const EdgeInsets.only(
+              right: 20,
+            ),
+            child: Padding(
+              padding: const EdgeInsets.only(
+                right: 12,
+              ),
+              child: RoundedWhiteContainer(
+                borderColor: isDesktop
+                    ? Theme.of(context).extension<StackColors>()!.background
+                    : null,
+                padding: const EdgeInsets.all(0),
+                child: ListView(
+                  primary: false,
+                  shrinkWrap: true,
+                  children: children,
+                ),
+              ),
+            ),
+          ),
+          otherBranchBuilder: (children) => Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            mainAxisSize: isDesktop ? MainAxisSize.min : MainAxisSize.max,
+            children: children,
+          ),
+          children: [
+            RoundedWhiteContainer(
+              padding: isDesktop
+                  ? const EdgeInsets.all(0)
+                  : const EdgeInsets.all(12),
+              child: Container(
+                decoration: isDesktop
+                    ? BoxDecoration(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .background,
+                        borderRadius: BorderRadius.vertical(
+                          top: Radius.circular(
+                            Constants.size.circularBorderRadius,
+                          ),
+                        ),
+                      )
+                    : null,
+                child: Padding(
+                  padding: isDesktop
+                      ? const EdgeInsets.all(12)
+                      : const EdgeInsets.all(0),
                   child: Row(
                     mainAxisAlignment: MainAxisAlignment.spaceBetween,
                     children: [
+                      if (isDesktop)
+                        Row(
+                          children: [
+                            SvgPicture.asset(
+                              _fetchIconAssetForStatus(trade.status),
+                              width: 32,
+                              height: 32,
+                            ),
+                            const SizedBox(
+                              width: 16,
+                            ),
+                            SelectableText(
+                              "Exchange",
+                              style: STextStyles.desktopTextMedium(context),
+                            ),
+                          ],
+                        ),
                       Column(
-                        crossAxisAlignment: CrossAxisAlignment.start,
+                        crossAxisAlignment: isDesktop
+                            ? CrossAxisAlignment.end
+                            : CrossAxisAlignment.start,
                         children: [
                           SelectableText(
                             "${trade.payInCurrency.toUpperCase()} → ${trade.payOutCurrency.toUpperCase()}",
@@ -194,7 +279,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                             height: 4,
                           ),
                           SelectableText(
-                            "${Format.localizedStringAsFixed(value: sendAmount, locale: ref.watch(
+                            "-${Format.localizedStringAsFixed(value: sendAmount, locale: ref.watch(
                                   localeServiceChangeNotifierProvider
                                       .select((value) => value.locale),
                                 ), decimalPlaces: trade.payInCurrency.toLowerCase() == "xmr" ? 12 : 8)} ${trade.payInCurrency.toUpperCase()}",
@@ -202,136 +287,178 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                           ),
                         ],
                       ),
-                      Container(
-                        width: 32,
-                        height: 32,
-                        decoration: BoxDecoration(
-                          borderRadius: BorderRadius.circular(32),
-                        ),
-                        child: Center(
-                          child: SvgPicture.asset(
-                            _fetchIconAssetForStatus(trade.status),
-                            width: 32,
-                            height: 32,
+                      if (!isDesktop)
+                        Container(
+                          width: 32,
+                          height: 32,
+                          decoration: BoxDecoration(
+                            borderRadius: BorderRadius.circular(32),
+                          ),
+                          child: Center(
+                            child: SvgPicture.asset(
+                              _fetchIconAssetForStatus(trade.status),
+                              width: 32,
+                              height: 32,
+                            ),
                           ),
                         ),
-                      ),
                     ],
                   ),
                 ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "Status",
-                        style: STextStyles.itemSubtitle(context),
-                      ),
-                      const SizedBox(
-                        height: 4,
-                      ),
-                      SelectableText(
-                        trade.status,
-                        style: STextStyles.itemSubtitle(context).copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .colorForStatus(trade.status),
-                        ),
-                      ),
-                      //   ),
-                      // ),
-                    ],
-                  ),
-                ),
-                if (!sentFromStack && !hasTx)
-                  const SizedBox(
+              ),
+            ),
+            isDesktop
+                ? const _Divider()
+                : const SizedBox(
                     height: 12,
                   ),
-                if (!sentFromStack && !hasTx)
-                  RoundedContainer(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .warningBackground,
-                    child: RichText(
-                      text: TextSpan(
+            RoundedWhiteContainer(
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Text(
+                    "Status",
+                    style: STextStyles.itemSubtitle(context),
+                  ),
+                  const SizedBox(
+                    height: 4,
+                  ),
+                  SelectableText(
+                    trade.status,
+                    style: STextStyles.itemSubtitle(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .colorForStatus(trade.status),
+                    ),
+                  ),
+                  //   ),
+                  // ),
+                ],
+              ),
+            ),
+            if (!sentFromStack && !hasTx)
+              isDesktop
+                  ? const _Divider()
+                  : const SizedBox(
+                      height: 12,
+                    ),
+            if (!sentFromStack && !hasTx)
+              RoundedContainer(
+                padding: isDesktop
+                    ? const EdgeInsets.all(16)
+                    : const EdgeInsets.all(12),
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .warningBackground,
+                child: RichText(
+                  text: TextSpan(
+                      text:
+                          "You must send at least ${sendAmount.toStringAsFixed(
+                        trade.payInCurrency.toLowerCase() == "xmr" ? 12 : 8,
+                      )} ${trade.payInCurrency.toUpperCase()}. ",
+                      style: STextStyles.label700(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .warningForeground,
+                      ),
+                      children: [
+                        TextSpan(
                           text:
-                              "You must send at least ${sendAmount.toStringAsFixed(
+                              "If you send less than ${sendAmount.toStringAsFixed(
                             trade.payInCurrency.toLowerCase() == "xmr" ? 12 : 8,
-                          )} ${trade.payInCurrency.toUpperCase()}. ",
-                          style: STextStyles.label700(context).copyWith(
+                          )} ${trade.payInCurrency.toUpperCase()}, your transaction may not be converted and it may not be refunded.",
+                          style: STextStyles.label(context).copyWith(
                             color: Theme.of(context)
                                 .extension<StackColors>()!
                                 .warningForeground,
                           ),
-                          children: [
-                            TextSpan(
-                              text:
-                                  "If you send less than ${sendAmount.toStringAsFixed(
-                                trade.payInCurrency.toLowerCase() == "xmr"
-                                    ? 12
-                                    : 8,
-                              )} ${trade.payInCurrency.toUpperCase()}, your transaction may not be converted and it may not be refunded.",
-                              style: STextStyles.label(context).copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .warningForeground,
+                        ),
+                      ]),
+                ),
+              ),
+            if (sentFromStack)
+              isDesktop
+                  ? const _Divider()
+                  : const SizedBox(
+                      height: 12,
+                    ),
+            if (sentFromStack)
+              RoundedWhiteContainer(
+                padding: isDesktop
+                    ? const EdgeInsets.all(16)
+                    : const EdgeInsets.all(12),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Text(
+                      "Sent from",
+                      style: STextStyles.itemSubtitle(context),
+                    ),
+                    const SizedBox(
+                      height: 4,
+                    ),
+                    SelectableText(
+                      widget.walletName!,
+                      style: STextStyles.itemSubtitle12(context),
+                    ),
+                    const SizedBox(
+                      height: 10,
+                    ),
+                    BlueTextButton(
+                      text: "View transaction",
+                      onTap: () {
+                        final Coin coin =
+                            coinFromTickerCaseInsensitive(trade.payInCurrency);
+
+                        if (isDesktop) {
+                          Navigator.of(context).push(
+                            FadePageRoute<void>(
+                              DesktopDialog(
+                                maxHeight:
+                                    MediaQuery.of(context).size.height - 64,
+                                maxWidth: 580,
+                                child: TransactionDetailsView(
+                                  coin: coin,
+                                  transaction: transactionIfSentFromStack!,
+                                  walletId: walletId!,
+                                ),
+                              ),
+                              const RouteSettings(
+                                name: TransactionDetailsView.routeName,
                               ),
                             ),
-                          ]),
+                          );
+                        } else {
+                          Navigator.of(context).pushNamed(
+                            TransactionDetailsView.routeName,
+                            arguments: Tuple3(
+                                transactionIfSentFromStack!, coin, walletId!),
+                          );
+                        }
+                      },
                     ),
-                  ),
-                if (sentFromStack)
-                  const SizedBox(
-                    height: 12,
-                  ),
-                if (sentFromStack)
-                  RoundedWhiteContainer(
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        Text(
-                          "Sent from",
-                          style: STextStyles.itemSubtitle(context),
-                        ),
-                        const SizedBox(
-                          height: 4,
-                        ),
-                        SelectableText(
-                          widget.walletName!,
-                          style: STextStyles.itemSubtitle12(context),
-                        ),
-                        const SizedBox(
-                          height: 10,
-                        ),
-                        GestureDetector(
-                          onTap: () {
-                            final Coin coin = coinFromTickerCaseInsensitive(
-                                trade.payInCurrency);
-
-                            Navigator.of(context).pushNamed(
-                              TransactionDetailsView.routeName,
-                              arguments: Tuple3(
-                                  transactionIfSentFromStack!, coin, walletId!),
-                            );
-                          },
-                          child: Text(
-                            "View transaction",
-                            style: STextStyles.link2(context),
-                          ),
-                        ),
-                      ],
+                  ],
+                ),
+              ),
+            if (sentFromStack)
+              isDesktop
+                  ? const _Divider()
+                  : const SizedBox(
+                      height: 12,
                     ),
-                  ),
-                if (sentFromStack)
-                  const SizedBox(
-                    height: 12,
-                  ),
-                if (sentFromStack)
-                  RoundedWhiteContainer(
-                    child: Column(
+            if (sentFromStack)
+              RoundedWhiteContainer(
+                padding: isDesktop
+                    ? const EdgeInsets.all(16)
+                    : const EdgeInsets.all(12),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Column(
                       crossAxisAlignment: CrossAxisAlignment.start,
                       children: [
                         Text(
@@ -347,252 +474,224 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                         ),
                       ],
                     ),
-                  ),
-                if (!sentFromStack && !hasTx)
-                  const SizedBox(
-                    height: 12,
-                  ),
-                if (!sentFromStack && !hasTx)
-                  RoundedWhiteContainer(
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
+                    if (isDesktop)
+                      IconCopyButton(
+                        data: trade.payInAddress,
+                      ),
+                  ],
+                ),
+              ),
+            if (!sentFromStack && !hasTx)
+              isDesktop
+                  ? const _Divider()
+                  : const SizedBox(
+                      height: 12,
+                    ),
+            if (!sentFromStack && !hasTx)
+              RoundedWhiteContainer(
+                padding: isDesktop
+                    ? const EdgeInsets.all(16)
+                    : const EdgeInsets.all(12),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                       children: [
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: [
-                            Text(
-                              "Send ${trade.payInCurrency.toUpperCase()} to this address",
-                              style: STextStyles.itemSubtitle(context),
-                            ),
-                            GestureDetector(
-                              onTap: () async {
-                                final address = trade.payInAddress;
-                                await Clipboard.setData(
-                                  ClipboardData(
-                                    text: address,
-                                  ),
-                                );
-                                unawaited(showFloatingFlushBar(
-                                  type: FlushBarType.info,
-                                  message: "Copied to clipboard",
-                                  context: context,
-                                ));
-                              },
-                              child: Row(
+                        Text(
+                          "Send ${trade.payInCurrency.toUpperCase()} to this address",
+                          style: STextStyles.itemSubtitle(context),
+                        ),
+                        isDesktop
+                            ? IconCopyButton(
+                                data: trade.payInAddress,
+                              )
+                            : GestureDetector(
+                                onTap: () async {
+                                  final address = trade.payInAddress;
+                                  await Clipboard.setData(
+                                    ClipboardData(
+                                      text: address,
+                                    ),
+                                  );
+                                  unawaited(showFloatingFlushBar(
+                                    type: FlushBarType.info,
+                                    message: "Copied to clipboard",
+                                    context: context,
+                                  ));
+                                },
+                                child: Row(
+                                  children: [
+                                    SvgPicture.asset(
+                                      Assets.svg.copy,
+                                      width: 12,
+                                      height: 12,
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .infoItemIcons,
+                                    ),
+                                    const SizedBox(
+                                      width: 4,
+                                    ),
+                                    Text(
+                                      "Copy",
+                                      style: STextStyles.link2(context),
+                                    ),
+                                  ],
+                                ),
+                              ),
+                      ],
+                    ),
+                    const SizedBox(
+                      height: 4,
+                    ),
+                    SelectableText(
+                      trade.payInAddress,
+                      style: STextStyles.itemSubtitle12(context),
+                    ),
+                    const SizedBox(
+                      height: 10,
+                    ),
+                    GestureDetector(
+                      onTap: () {
+                        showDialog<dynamic>(
+                          context: context,
+                          useSafeArea: false,
+                          barrierDismissible: true,
+                          builder: (_) {
+                            final width = MediaQuery.of(context).size.width / 2;
+                            return StackDialogBase(
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.stretch,
                                 children: [
-                                  SvgPicture.asset(
-                                    Assets.svg.copy,
-                                    width: 12,
-                                    height: 12,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .infoItemIcons,
+                                  Center(
+                                    child: Text(
+                                      "Send ${trade.payInCurrency.toUpperCase()} to this address",
+                                      style: STextStyles.pageTitleH2(context),
+                                    ),
                                   ),
                                   const SizedBox(
-                                    width: 4,
+                                    height: 12,
                                   ),
-                                  Text(
-                                    "Copy",
-                                    style: STextStyles.link2(context),
+                                  Center(
+                                    child: RepaintBoundary(
+                                      // key: _qrKey,
+                                      child: SizedBox(
+                                        width: width + 20,
+                                        height: width + 20,
+                                        child: QrImage(
+                                            data: trade.payInAddress,
+                                            size: width,
+                                            backgroundColor: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .popupBG,
+                                            foregroundColor: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .accentColorDark),
+                                      ),
+                                    ),
+                                  ),
+                                  const SizedBox(
+                                    height: 12,
+                                  ),
+                                  Center(
+                                    child: SizedBox(
+                                      width: width,
+                                      child: TextButton(
+                                        onPressed: () async {
+                                          // await _capturePng(true);
+                                          Navigator.of(context).pop();
+                                        },
+                                        style: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .getSecondaryEnabledButtonColor(
+                                                context),
+                                        child: Text(
+                                          "Cancel",
+                                          style: STextStyles.button(context)
+                                              .copyWith(
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .accentColorDark),
+                                        ),
+                                      ),
+                                    ),
                                   ),
                                 ],
                               ),
-                            ),
-                          ],
-                        ),
-                        const SizedBox(
-                          height: 4,
-                        ),
-                        SelectableText(
-                          trade.payInAddress,
-                          style: STextStyles.itemSubtitle12(context),
-                        ),
-                        const SizedBox(
-                          height: 10,
-                        ),
-                        GestureDetector(
-                          onTap: () {
-                            showDialog<dynamic>(
-                              context: context,
-                              useSafeArea: false,
-                              barrierDismissible: true,
-                              builder: (_) {
-                                final width =
-                                    MediaQuery.of(context).size.width / 2;
-                                return StackDialogBase(
-                                  child: Column(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.stretch,
-                                    children: [
-                                      Center(
-                                        child: Text(
-                                          "Send ${trade.payInCurrency.toUpperCase()} to this address",
-                                          style:
-                                              STextStyles.pageTitleH2(context),
-                                        ),
-                                      ),
-                                      const SizedBox(
-                                        height: 12,
-                                      ),
-                                      Center(
-                                        child: RepaintBoundary(
-                                          // key: _qrKey,
-                                          child: SizedBox(
-                                            width: width + 20,
-                                            height: width + 20,
-                                            child: QrImage(
-                                                data: trade.payInAddress,
-                                                size: width,
-                                                backgroundColor: Theme.of(
-                                                        context)
-                                                    .extension<StackColors>()!
-                                                    .popupBG,
-                                                foregroundColor: Theme.of(
-                                                        context)
-                                                    .extension<StackColors>()!
-                                                    .accentColorDark),
-                                          ),
-                                        ),
-                                      ),
-                                      const SizedBox(
-                                        height: 12,
-                                      ),
-                                      Center(
-                                        child: SizedBox(
-                                          width: width,
-                                          child: TextButton(
-                                            onPressed: () async {
-                                              // await _capturePng(true);
-                                              Navigator.of(context).pop();
-                                            },
-                                            style: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .getSecondaryEnabledButtonColor(
-                                                    context),
-                                            child: Text(
-                                              "Cancel",
-                                              style: STextStyles.button(context)
-                                                  .copyWith(
-                                                      color: Theme.of(context)
-                                                          .extension<
-                                                              StackColors>()!
-                                                          .accentColorDark),
-                                            ),
-                                          ),
-                                        ),
-                                      ),
-                                    ],
-                                  ),
-                                );
-                              },
                             );
                           },
-                          child: Row(
-                            children: [
-                              SvgPicture.asset(
-                                Assets.svg.qrcode,
-                                width: 12,
-                                height: 12,
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .infoItemIcons,
-                              ),
-                              const SizedBox(
-                                width: 4,
-                              ),
-                              Text(
-                                "Show QR code",
-                                style: STextStyles.link2(context),
-                              ),
-                            ],
-                          ),
-                        ),
-                      ],
-                    ),
-                  ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      Row(
-                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        );
+                      },
+                      child: Row(
                         children: [
-                          Text(
-                            "Trade note",
-                            style: STextStyles.itemSubtitle(context),
+                          SvgPicture.asset(
+                            Assets.svg.qrcode,
+                            width: 12,
+                            height: 12,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .infoItemIcons,
                           ),
-                          GestureDetector(
-                            onTap: () {
-                              Navigator.of(context).pushNamed(
-                                EditTradeNoteView.routeName,
-                                arguments: Tuple2(
-                                  tradeId,
-                                  ref
-                                      .read(tradeNoteServiceProvider)
-                                      .getNote(tradeId: tradeId),
-                                ),
-                              );
-                            },
-                            child: Row(
-                              children: [
-                                SvgPicture.asset(
-                                  Assets.svg.pencil,
-                                  width: 10,
-                                  height: 10,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .infoItemIcons,
-                                ),
-                                const SizedBox(
-                                  width: 4,
-                                ),
-                                Text(
-                                  "Edit",
-                                  style: STextStyles.link2(context),
-                                ),
-                              ],
-                            ),
+                          const SizedBox(
+                            width: 4,
+                          ),
+                          Text(
+                            "Show QR code",
+                            style: STextStyles.link2(context),
                           ),
                         ],
                       ),
-                      const SizedBox(
-                        height: 4,
-                      ),
-                      SelectableText(
-                        ref.watch(tradeNoteServiceProvider.select(
-                            (value) => value.getNote(tradeId: tradeId))),
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
-                    ],
-                  ),
+                    ),
+                  ],
                 ),
-                if (sentFromStack)
-                  const SizedBox(
+              ),
+            isDesktop
+                ? const _Divider()
+                : const SizedBox(
                     height: 12,
                   ),
-                if (sentFromStack)
-                  RoundedWhiteContainer(
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: [
-                            Text(
-                              "Transaction note",
-                              style: STextStyles.itemSubtitle(context),
-                            ),
-                            GestureDetector(
+            RoundedWhiteContainer(
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Text(
+                        "Trade note",
+                        style: STextStyles.itemSubtitle(context),
+                      ),
+                      isDesktop
+                          ? IconPencilButton(
+                              onPressed: () {
+                                showDialog<void>(
+                                  context: context,
+                                  builder: (context) {
+                                    return DesktopDialog(
+                                      maxWidth: 580,
+                                      maxHeight: 360,
+                                      child: EditTradeNoteView(
+                                        tradeId: tradeId,
+                                        note: _note,
+                                      ),
+                                    );
+                                  },
+                                );
+                              },
+                            )
+                          : GestureDetector(
                               onTap: () {
                                 Navigator.of(context).pushNamed(
-                                  EditNoteView.routeName,
-                                  arguments: Tuple3(
-                                    transactionIfSentFromStack!.txid,
-                                    walletId!,
-                                    _note,
+                                  EditTradeNoteView.routeName,
+                                  arguments: Tuple2(
+                                    tradeId,
+                                    ref
+                                        .read(tradeNoteServiceProvider)
+                                        .getNote(tradeId: tradeId),
                                   ),
                                 );
                               },
@@ -616,193 +715,371 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                                 ],
                               ),
                             ),
-                          ],
-                        ),
-                        const SizedBox(
-                          height: 4,
-                        ),
-                        FutureBuilder(
-                          future: ref.watch(
-                              notesServiceChangeNotifierProvider(walletId!)
-                                  .select((value) => value.getNoteFor(
-                                      txid: transactionIfSentFromStack!.txid))),
-                          builder:
-                              (builderContext, AsyncSnapshot<String> snapshot) {
-                            if (snapshot.connectionState ==
-                                    ConnectionState.done &&
-                                snapshot.hasData) {
-                              _note = snapshot.data ?? "";
-                            }
-                            return SelectableText(
-                              _note,
-                              style: STextStyles.itemSubtitle12(context),
-                            );
-                          },
+                    ],
+                  ),
+                  const SizedBox(
+                    height: 4,
+                  ),
+                  SelectableText(
+                    ref.watch(tradeNoteServiceProvider
+                        .select((value) => value.getNote(tradeId: tradeId))),
+                    style: STextStyles.itemSubtitle12(context),
+                  ),
+                ],
+              ),
+            ),
+            if (sentFromStack)
+              isDesktop
+                  ? const _Divider()
+                  : const SizedBox(
+                      height: 12,
+                    ),
+            if (sentFromStack)
+              RoundedWhiteContainer(
+                padding: isDesktop
+                    ? const EdgeInsets.all(16)
+                    : const EdgeInsets.all(12),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Text(
+                          "Transaction note",
+                          style: STextStyles.itemSubtitle(context),
                         ),
+                        isDesktop
+                            ? IconPencilButton(
+                                onPressed: () {
+                                  showDialog<void>(
+                                    context: context,
+                                    builder: (context) {
+                                      return DesktopDialog(
+                                        maxWidth: 580,
+                                        maxHeight: 360,
+                                        child: EditNoteView(
+                                          txid:
+                                              transactionIfSentFromStack!.txid,
+                                          walletId: walletId!,
+                                          note: _note,
+                                        ),
+                                      );
+                                    },
+                                  );
+                                },
+                              )
+                            : GestureDetector(
+                                onTap: () {
+                                  Navigator.of(context).pushNamed(
+                                    EditNoteView.routeName,
+                                    arguments: Tuple3(
+                                      transactionIfSentFromStack!.txid,
+                                      walletId!,
+                                      _note,
+                                    ),
+                                  );
+                                },
+                                child: Row(
+                                  children: [
+                                    SvgPicture.asset(
+                                      Assets.svg.pencil,
+                                      width: 10,
+                                      height: 10,
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .infoItemIcons,
+                                    ),
+                                    const SizedBox(
+                                      width: 4,
+                                    ),
+                                    Text(
+                                      "Edit",
+                                      style: STextStyles.link2(context),
+                                    ),
+                                  ],
+                                ),
+                              ),
                       ],
                     ),
-                  ),
-                const SizedBox(
-                  height: 12,
+                    const SizedBox(
+                      height: 4,
+                    ),
+                    FutureBuilder(
+                      future: ref.watch(
+                          notesServiceChangeNotifierProvider(walletId!).select(
+                              (value) => value.getNoteFor(
+                                  txid: transactionIfSentFromStack!.txid))),
+                      builder:
+                          (builderContext, AsyncSnapshot<String> snapshot) {
+                        if (snapshot.connectionState == ConnectionState.done &&
+                            snapshot.hasData) {
+                          _note = snapshot.data ?? "";
+                        }
+                        return SelectableText(
+                          _note,
+                          style: STextStyles.itemSubtitle12(context),
+                        );
+                      },
+                    ),
+                  ],
                 ),
-                RoundedWhiteContainer(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              ),
+            isDesktop
+                ? const _Divider()
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Column(
+                    mainAxisSize: MainAxisSize.min,
+                    crossAxisAlignment: CrossAxisAlignment.start,
                     children: [
                       Text(
                         "Date",
                         style: STextStyles.itemSubtitle(context),
                       ),
-                      // Flexible(
-                      //   child: FittedBox(
-                      //     fit: BoxFit.scaleDown,
-                      //     child:
-                      SelectableText(
-                        Format.extractDateFrom(
-                            trade.timestamp.millisecondsSinceEpoch ~/ 1000),
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
-                      //   ),
-                      // ),
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 2,
+                        ),
+                      if (isDesktop)
+                        SelectableText(
+                          Format.extractDateFrom(
+                              trade.timestamp.millisecondsSinceEpoch ~/ 1000),
+                          style: STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark,
+                          ),
+                        ),
                     ],
                   ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  if (!isDesktop)
+                    SelectableText(
+                      Format.extractDateFrom(
+                          trade.timestamp.millisecondsSinceEpoch ~/ 1000),
+                      style: STextStyles.itemSubtitle12(context),
+                    ),
+                  if (isDesktop)
+                    IconCopyButton(
+                      data: Format.extractDateFrom(
+                          trade.timestamp.millisecondsSinceEpoch ~/ 1000),
+                    ),
+                ],
+              ),
+            ),
+            isDesktop
+                ? const _Divider()
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
                     children: [
                       Text(
                         "Exchange",
                         style: STextStyles.itemSubtitle(context),
                       ),
-                      SelectableText(
-                        trade.exchangeName,
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 2,
+                        ),
+                      if (isDesktop)
+                        SelectableText(
+                          trade.exchangeName,
+                          style: STextStyles.itemSubtitle12(context),
+                        ),
                     ],
                   ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Row(
+                  if (isDesktop)
+                    IconCopyButton(
+                      data: trade.exchangeName,
+                    ),
+                  if (!isDesktop)
+                    SelectableText(
+                      trade.exchangeName,
+                      style: STextStyles.itemSubtitle12(context),
+                    ),
+                ],
+              ),
+            ),
+            isDesktop
+                ? const _Divider()
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
                     children: [
                       Text(
                         "Trade ID",
                         style: STextStyles.itemSubtitle(context),
                       ),
-                      const Spacer(),
-                      Row(
-                        children: [
-                          Text(
-                            trade.tradeId,
-                            style: STextStyles.itemSubtitle12(context),
-                          ),
-                          const SizedBox(
-                            width: 10,
-                          ),
-                          GestureDetector(
-                            onTap: () async {
-                              final data = ClipboardData(text: trade.tradeId);
-                              await clipboard.setData(data);
-                              unawaited(showFloatingFlushBar(
-                                type: FlushBarType.info,
-                                message: "Copied to clipboard",
-                                context: context,
-                              ));
-                            },
-                            child: SvgPicture.asset(
-                              Assets.svg.copy,
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .infoItemIcons,
-                              width: 12,
-                            ),
-                          )
-                        ],
-                      )
-                    ],
-                  ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      Text(
-                        "Tracking",
-                        style: STextStyles.itemSubtitle(context),
-                      ),
-                      const SizedBox(
-                        height: 4,
-                      ),
-                      Builder(builder: (context) {
-                        late final String url;
-                        switch (trade.exchangeName) {
-                          case ChangeNowExchange.exchangeName:
-                            url =
-                                "https://changenow.io/exchange/txs/${trade.tradeId}";
-                            break;
-                          case SimpleSwapExchange.exchangeName:
-                            url =
-                                "https://simpleswap.io/exchange?id=${trade.tradeId}";
-                            break;
-                        }
-                        return GestureDetector(
-                          onTap: () {
-                            launchUrl(
-                              Uri.parse(url),
-                              mode: LaunchMode.externalApplication,
-                            );
-                          },
-                          child: Text(
-                            url,
-                            style: STextStyles.link2(context),
-                          ),
-                        );
-                      }),
-                    ],
-                  ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                if (isStackCoin(trade.payInCurrency) &&
-                    (trade.status == "New" ||
-                        trade.status == "new" ||
-                        trade.status == "waiting" ||
-                        trade.status == "Waiting"))
-                  SecondaryButton(
-                    label: "Send from Stack",
-                    onPressed: () {
-                      final amount = sendAmount;
-                      final address = trade.payInAddress;
-
-                      final coin =
-                          coinFromTickerCaseInsensitive(trade.payInCurrency);
-
-                      Navigator.of(context).pushNamed(
-                        SendFromView.routeName,
-                        arguments: Tuple4(
-                          coin,
-                          amount,
-                          address,
-                          trade,
+                      if (isDesktop)
+                        const SizedBox(
+                          height: 2,
                         ),
-                      );
-                    },
+                      if (isDesktop)
+                        Text(
+                          trade.tradeId,
+                          style: STextStyles.itemSubtitle12(context),
+                        ),
+                    ],
                   ),
-              ],
+                  if (isDesktop)
+                    IconCopyButton(
+                      data: trade.tradeId,
+                    ),
+                  if (!isDesktop)
+                    Row(
+                      children: [
+                        Text(
+                          trade.tradeId,
+                          style: STextStyles.itemSubtitle12(context),
+                        ),
+                        const SizedBox(
+                          width: 10,
+                        ),
+                        GestureDetector(
+                          onTap: () async {
+                            final data = ClipboardData(text: trade.tradeId);
+                            await clipboard.setData(data);
+                            unawaited(showFloatingFlushBar(
+                              type: FlushBarType.info,
+                              message: "Copied to clipboard",
+                              context: context,
+                            ));
+                          },
+                          child: SvgPicture.asset(
+                            Assets.svg.copy,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .infoItemIcons,
+                            width: 12,
+                          ),
+                        )
+                      ],
+                    ),
+                ],
+              ),
             ),
-          ),
+            isDesktop
+                ? const _Divider()
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              padding: isDesktop
+                  ? const EdgeInsets.all(16)
+                  : const EdgeInsets.all(12),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Text(
+                    "Tracking",
+                    style: STextStyles.itemSubtitle(context),
+                  ),
+                  const SizedBox(
+                    height: 4,
+                  ),
+                  Builder(builder: (context) {
+                    late final String url;
+                    switch (trade.exchangeName) {
+                      case ChangeNowExchange.exchangeName:
+                        url =
+                            "https://changenow.io/exchange/txs/${trade.tradeId}";
+                        break;
+                      case SimpleSwapExchange.exchangeName:
+                        url =
+                            "https://simpleswap.io/exchange?id=${trade.tradeId}";
+                        break;
+                    }
+                    return GestureDetector(
+                      onTap: () {
+                        launchUrl(
+                          Uri.parse(url),
+                          mode: LaunchMode.externalApplication,
+                        );
+                      },
+                      child: Text(
+                        url,
+                        style: STextStyles.link2(context),
+                      ),
+                    );
+                  }),
+                ],
+              ),
+            ),
+            isDesktop
+                ? const _Divider()
+                : const SizedBox(
+                    height: 12,
+                  ),
+            if (isStackCoin(trade.payInCurrency) &&
+                (trade.status == "New" ||
+                    trade.status == "new" ||
+                    trade.status == "waiting" ||
+                    trade.status == "Waiting"))
+              SecondaryButton(
+                label: "Send from Stack",
+                onPressed: () {
+                  final amount = sendAmount;
+                  final address = trade.payInAddress;
+
+                  final coin =
+                      coinFromTickerCaseInsensitive(trade.payInCurrency);
+
+                  Navigator.of(context).pushNamed(
+                    SendFromView.routeName,
+                    arguments: Tuple4(
+                      coin,
+                      amount,
+                      address,
+                      trade,
+                    ),
+                  );
+                },
+              ),
+          ],
         ),
       ),
     );
   }
 }
+
+class _Divider extends StatelessWidget {
+  const _Divider({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      height: 1,
+      color: Theme.of(context).extension<StackColors>()!.background,
+    );
+  }
+}
diff --git a/lib/pages/wallet_view/sub_widgets/transactions_list.dart b/lib/pages/wallet_view/sub_widgets/transactions_list.dart
index d23d3082f..11353c7c6 100644
--- a/lib/pages/wallet_view/sub_widgets/transactions_list.dart
+++ b/lib/pages/wallet_view/sub_widgets/transactions_list.dart
@@ -7,10 +7,14 @@ 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/global/trades_service_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/services/coins/manager.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/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/trade_card.dart';
 import 'package:stackwallet/widgets/transaction_card.dart';
@@ -94,18 +98,79 @@ class _TransactionsListState extends ConsumerState<TransactionsList> {
               // this may mess with combined firo transactions
               key: Key(tx.toString() + trade.uuid), //
               trade: trade,
-              onTap: () {
-                unawaited(
-                  Navigator.of(context).pushNamed(
-                    TradeDetailsView.routeName,
-                    arguments: Tuple4(
-                      trade.tradeId,
-                      tx,
-                      widget.walletId,
-                      ref.read(managerProvider).walletName,
+              onTap: () async {
+                if (Util.isDesktop) {
+                  await showDialog<void>(
+                    context: context,
+                    builder: (context) => Navigator(
+                      initialRoute: TradeDetailsView.routeName,
+                      onGenerateRoute: RouteGenerator.generateRoute,
+                      onGenerateInitialRoutes: (_, __) {
+                        return [
+                          FadePageRoute(
+                            DesktopDialog(
+                              // maxHeight:
+                              //     MediaQuery.of(context).size.height - 64,
+                              maxHeight: double.infinity,
+                              maxWidth: 580,
+                              child: Column(
+                                mainAxisSize: MainAxisSize.min,
+                                children: [
+                                  Padding(
+                                    padding: const EdgeInsets.only(
+                                      left: 32,
+                                      bottom: 16,
+                                    ),
+                                    child: Row(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceBetween,
+                                      children: [
+                                        Text(
+                                          "Trade details",
+                                          style: STextStyles.desktopH3(context),
+                                        ),
+                                        DesktopDialogCloseButton(
+                                          onPressedOverride: Navigator.of(
+                                            context,
+                                            rootNavigator: true,
+                                          ).pop,
+                                        ),
+                                      ],
+                                    ),
+                                  ),
+                                  Flexible(
+                                    child: TradeDetailsView(
+                                      tradeId: trade.tradeId,
+                                      transactionIfSentFromStack: tx,
+                                      walletName:
+                                          ref.read(managerProvider).walletName,
+                                      walletId: widget.walletId,
+                                    ),
+                                  ),
+                                ],
+                              ),
+                            ),
+                            const RouteSettings(
+                              name: TradeDetailsView.routeName,
+                            ),
+                          ),
+                        ];
+                      },
                     ),
-                  ),
-                );
+                  );
+                } else {
+                  unawaited(
+                    Navigator.of(context).pushNamed(
+                      TradeDetailsView.routeName,
+                      arguments: Tuple4(
+                        trade.tradeId,
+                        tx,
+                        widget.walletId,
+                        ref.read(managerProvider).walletName,
+                      ),
+                    ),
+                  );
+                }
               },
             )
           ],

From 2bdf5f152c606cd83311ef5e5b899e3a9b8cb0d7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 9 Nov 2022 16:43:26 -0600
Subject: [PATCH 188/426] dynamic secure storage provider

---
 lib/hive/db.dart                              |   2 +
 lib/main.dart                                 |  29 +-
 ...w_wallet_recovery_phrase_warning_view.dart |   2 +
 .../restore_wallet_view.dart                  |   2 +
 lib/pages/pinpad_views/create_pin_view.dart   |   8 +-
 lib/pages/pinpad_views/lock_screen_view.dart  |   8 +-
 .../add_edit_node_view.dart                   |   8 +-
 .../manage_nodes_views/node_details_view.dart |   8 +-
 .../change_pin_view/change_pin_view.dart      |  16 +-
 .../create_auto_backup_view.dart              |  16 +-
 .../create_backup_view.dart                   | 424 +++++++++---------
 .../edit_auto_backup_view.dart                |  16 +-
 .../helpers/restore_create_backup.dart        | 112 +++--
 .../stack_restore_progress_view.dart          |   2 +
 .../create_password/create_password_view.dart |   7 -
 .../global/auto_swb_service_provider.dart     |   8 +-
 .../global/node_service_provider.dart         |   5 +-
 .../global/secure_store_provider.dart         |  18 +
 .../global/wallets_service_provider.dart      |   7 +-
 lib/services/auto_swb_service.dart            |   5 +-
 .../coins/bitcoin/bitcoin_wallet.dart         |  11 +-
 .../coins/bitcoincash/bitcoincash_wallet.dart |  11 +-
 lib/services/coins/coin_service.dart          |  16 +
 .../coins/dogecoin/dogecoin_wallet.dart       |  11 +-
 .../coins/epiccash/epiccash_wallet.dart       |   9 +-
 lib/services/coins/firo/firo_wallet.dart      |  11 +-
 .../coins/litecoin/litecoin_wallet.dart       |  11 +-
 lib/services/coins/monero/monero_wallet.dart  |   8 +-
 .../coins/namecoin/namecoin_wallet.dart       |  11 +-
 .../coins/wownero/wownero_wallet.dart         |   8 +-
 lib/services/node_service.dart                |   5 +-
 lib/services/wallets.dart                     |   3 +-
 lib/services/wallets_service.dart             |   6 +-
 lib/utilities/db_version_migration.dart       |  16 +-
 lib/utilities/desktop_password_service.dart   |  33 +-
 .../flutter_secure_storage_interface.dart     | 119 +++--
 ...flutter_secure_storage_interface_test.dart |   6 +-
 .../coins/bitcoin/bitcoin_wallet_test.dart    |  10 +-
 .../bitcoincash/bitcoincash_wallet_test.dart  |  10 +-
 .../coins/dogecoin/dogecoin_wallet_test.dart  |   8 +-
 .../coins/namecoin/namecoin_wallet_test.dart  | 210 ++++-----
 test/services/node_service_test.dart          |   3 +-
 test/services/wallets_service_test.dart       |  24 +-
 test/services/wallets_service_test.mocks.dart |   2 +-
 44 files changed, 701 insertions(+), 564 deletions(-)
 create mode 100644 lib/providers/global/secure_store_provider.dart

diff --git a/lib/hive/db.dart b/lib/hive/db.dart
index e1232696b..d5402752e 100644
--- a/lib/hive/db.dart
+++ b/lib/hive/db.dart
@@ -33,6 +33,7 @@ class DB {
   static const String boxNamePriceCache = "priceAPIPrice24hCache";
   static const String boxNameDBInfo = "dbInfo";
   static const String boxNameTheme = "theme";
+  static const String boxNameDesktopData = "desktopData";
 
   String boxNameTxCache({required Coin coin}) => "${coin.name}_txCache";
   String boxNameSetCache({required Coin coin}) =>
@@ -58,6 +59,7 @@ class DB {
   late final Box<dynamic> _boxPrefs;
   late final Box<TradeWalletLookup> _boxTradeLookup;
   late final Box<dynamic> _boxDBInfo;
+  late final Box<String> _boxDesktopData;
 
   final Map<String, Box<dynamic>> _walletBoxes = {};
 
diff --git a/lib/main.dart b/lib/main.dart
index 77a8b1441..7f7c4a44d 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -10,6 +10,7 @@ import 'package:flutter/services.dart';
 import 'package:flutter_libmonero/monero/monero.dart';
 import 'package:flutter_libmonero/wownero/wownero.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:google_fonts/google_fonts.dart';
 import 'package:hive_flutter/hive_flutter.dart';
 import 'package:isar/isar.dart';
@@ -51,6 +52,7 @@ import 'package:stackwallet/services/wallets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/db_version_migration.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/theme/color_theme.dart';
@@ -143,15 +145,24 @@ void main() async {
   await Hive.initFlutter(appDirectory.path);
 
   await Hive.openBox<dynamic>(DB.boxNameDBInfo);
-  int dbVersion = DB.instance.get<dynamic>(
-          boxName: DB.boxNameDBInfo, key: "hive_data_version") as int? ??
-      0;
-  if (dbVersion < Constants.currentHiveDbVersion) {
-    try {
-      await DbVersionMigrator().migrate(dbVersion);
-    } catch (e, s) {
-      Logging.instance.log("Cannot migrate database\n$e $s",
-          level: LogLevel.Error, printFullLength: true);
+
+  if (!Util.isDesktop) {
+    int dbVersion = DB.instance.get<dynamic>(
+            boxName: DB.boxNameDBInfo, key: "hive_data_version") as int? ??
+        0;
+    if (dbVersion < Constants.currentHiveDbVersion) {
+      try {
+        await DbVersionMigrator().migrate(
+          dbVersion,
+          secureStore: const SecureStorageWrapper(
+            store: FlutterSecureStorage(),
+            isDesktop: false,
+          ),
+        );
+      } catch (e, s) {
+        Logging.instance.log("Cannot migrate database\n$e $s",
+            level: LogLevel.Error, printFullLength: true);
+      }
     }
   }
 
diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart
index 83dc43933..24a2e1a44 100644
--- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart
+++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/coins/coin_service.dart';
 import 'package:stackwallet/services/coins/manager.dart';
@@ -241,6 +242,7 @@ class _NewWalletRecoveryPhraseWarningViewState
                                       coin,
                                       walletId,
                                       walletName,
+                                      ref.read(secureStoreProvider),
                                       node,
                                       txTracker,
                                       ref.read(prefsChangeNotifierProvider),
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
index a6b7e7e77..2f325f536 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
@@ -18,6 +18,7 @@ import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widge
 import 'package:stackwallet/pages/home_view/home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/coins/coin_service.dart';
 import 'package:stackwallet/services/coins/manager.dart';
@@ -265,6 +266,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
           widget.coin,
           walletId,
           widget.walletName,
+          ref.read(secureStoreProvider),
           node,
           txTracker,
           ref.read(prefsChangeNotifierProvider),
diff --git a/lib/pages/pinpad_views/create_pin_view.dart b/lib/pages/pinpad_views/create_pin_view.dart
index f8b84cfb4..5ea8bc363 100644
--- a/lib/pages/pinpad_views/create_pin_view.dart
+++ b/lib/pages/pinpad_views/create_pin_view.dart
@@ -2,10 +2,10 @@ import 'dart:io';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/home_view/home_view.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/biometrics.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -20,15 +20,11 @@ class CreatePinView extends ConsumerStatefulWidget {
   const CreatePinView({
     Key? key,
     this.popOnSuccess = false,
-    this.secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
     this.biometrics = const Biometrics(),
   }) : super(key: key);
 
   static const String routeName = "/createPin";
 
-  final FlutterSecureStorageInterface secureStore;
   final Biometrics biometrics;
   final bool popOnSuccess;
 
@@ -63,7 +59,7 @@ class _CreatePinViewState extends ConsumerState<CreatePinView> {
 
   @override
   initState() {
-    _secureStore = widget.secureStore;
+    _secureStore = ref.read(secureStoreProvider);
     biometrics = widget.biometrics;
     super.initState();
   }
diff --git a/lib/pages/pinpad_views/lock_screen_view.dart b/lib/pages/pinpad_views/lock_screen_view.dart
index 00d8b1914..137f3d55d 100644
--- a/lib/pages/pinpad_views/lock_screen_view.dart
+++ b/lib/pages/pinpad_views/lock_screen_view.dart
@@ -2,12 +2,12 @@ import 'dart:async';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/home_view/home_view.dart';
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
 // import 'package:stackwallet/providers/global/has_authenticated_start_state_provider.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 // import 'package:stackwallet/providers/global/should_show_lockscreen_on_resume_state_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -33,9 +33,6 @@ class LockscreenView extends ConsumerStatefulWidget {
     this.popOnSuccess = false,
     this.isInitialAppLogin = false,
     this.routeOnSuccessArguments,
-    this.secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
     this.biometrics = const Biometrics(),
     this.onSuccess,
   }) : super(key: key);
@@ -50,7 +47,6 @@ class LockscreenView extends ConsumerStatefulWidget {
   final String biometricsAuthenticationTitle;
   final String biometricsLocalizedReason;
   final String biometricsCancelButtonString;
-  final FlutterSecureStorageInterface secureStore;
   final Biometrics biometrics;
   final VoidCallback? onSuccess;
 
@@ -134,7 +130,7 @@ class _LockscreenViewState extends ConsumerState<LockscreenView> {
   void initState() {
     _shakeController = ShakeController();
 
-    _secureStore = widget.secureStore;
+    _secureStore = ref.read(secureStoreProvider);
     biometrics = widget.biometrics;
     _attempts = 0;
     _timeout = Duration.zero;
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 382e3f09e..39ab493f0 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -3,11 +3,11 @@ import 'dart:async';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -40,9 +40,6 @@ class AddEditNodeView extends ConsumerStatefulWidget {
     required this.coin,
     required this.nodeId,
     required this.routeOnSuccessOrDelete,
-    this.secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
   }) : super(key: key);
 
   static const String routeName = "/addEditNode";
@@ -51,7 +48,6 @@ class AddEditNodeView extends ConsumerStatefulWidget {
   final Coin coin;
   final String routeOnSuccessOrDelete;
   final String? nodeId;
-  final FlutterSecureStorageInterface secureStore;
 
   @override
   ConsumerState<AddEditNodeView> createState() => _AddEditNodeViewState();
@@ -533,7 +529,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
           children: [
             NodeForm(
               node: node,
-              secureStore: widget.secureStore,
+              secureStore: ref.read(secureStoreProvider),
               readOnly: false,
               coin: widget.coin,
               onChanged: (canSave, canTest) {
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index f9b64c460..6d9641b7d 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -2,11 +2,11 @@ import 'dart:async';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
@@ -32,14 +32,10 @@ class NodeDetailsView extends ConsumerStatefulWidget {
     required this.coin,
     required this.nodeId,
     required this.popRouteName,
-    this.secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
   }) : super(key: key);
 
   static const String routeName = "/nodeDetails";
 
-  final FlutterSecureStorageInterface secureStore;
   final Coin coin;
   final String nodeId;
   final String popRouteName;
@@ -58,7 +54,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
 
   @override
   initState() {
-    secureStore = widget.secureStore;
+    secureStore = ref.read(secureStoreProvider);
     coin = widget.coin;
     nodeId = widget.nodeId;
     popRouteName = widget.popRouteName;
diff --git a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart
index 39c95cad7..46c2fd9cf 100644
--- a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart
+++ b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart
@@ -1,7 +1,8 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/security_views/security_view.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@@ -11,23 +12,18 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_pin_put/custom_pin_put.dart';
 
-class ChangePinView extends StatefulWidget {
+class ChangePinView extends ConsumerStatefulWidget {
   const ChangePinView({
     Key? key,
-    this.secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
   }) : super(key: key);
 
   static const String routeName = "/changePin";
 
-  final FlutterSecureStorageInterface secureStore;
-
   @override
-  State<ChangePinView> createState() => _ChangePinViewState();
+  ConsumerState<ChangePinView> createState() => _ChangePinViewState();
 }
 
-class _ChangePinViewState extends State<ChangePinView> {
+class _ChangePinViewState extends ConsumerState<ChangePinView> {
   BoxDecoration get _pinPutDecoration {
     return BoxDecoration(
       color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
@@ -53,7 +49,7 @@ class _ChangePinViewState extends State<ChangePinView> {
 
   @override
   void initState() {
-    _secureStore = widget.secureStore;
+    _secureStore = ref.read(secureStoreProvider);
     super.initState();
   }
 
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
index 3b5dbd0b0..1082acc99 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
@@ -4,7 +4,6 @@ import 'dart:io';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stack_wallet_backup/stack_wallet_backup.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
@@ -13,6 +12,7 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/backup_frequency_type_select_sheet.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@@ -21,26 +21,20 @@ import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:zxcvbn/zxcvbn.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class CreateAutoBackupView extends ConsumerStatefulWidget {
   const CreateAutoBackupView({
     Key? key,
-    this.secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
   }) : super(key: key);
 
   static const String routeName = "/createAutoBackup";
 
-  final FlutterSecureStorageInterface secureStore;
-
   @override
   ConsumerState<CreateAutoBackupView> createState() =>
       _EnableAutoBackupViewState();
@@ -75,7 +69,7 @@ class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
 
   @override
   void initState() {
-    secureStore = widget.secureStore;
+    secureStore = ref.read(secureStoreProvider);
     stackFileSystem = StackFileSystem();
     fileLocationController = TextEditingController();
     passwordController = TextEditingController();
@@ -585,7 +579,9 @@ class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
                               final String fileToSave =
                                   createAutoBackupFilename(pathToSave, now);
 
-                              final backup = await SWB.createStackWalletJSON();
+                              final backup = await SWB.createStackWalletJSON(
+                                secureStorage: secureStore,
+                              );
 
                               bool result = await SWB.encryptStackWalletWithADK(
                                 fileToSave,
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index eacdda66a..fc4719fe1 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -8,6 +8,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@@ -443,222 +444,229 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
             ),
             if (!isDesktop) const Spacer(),
             !isDesktop
-                ? TextButton(
-                    style: shouldEnableCreate
-                        ? Theme.of(context)
-                            .extension<StackColors>()!
-                            .getPrimaryEnabledButtonColor(context)
-                        : Theme.of(context)
-                            .extension<StackColors>()!
-                            .getPrimaryDisabledButtonColor(context),
-                    onPressed: !shouldEnableCreate
-                        ? null
-                        : () async {
-                            final String pathToSave =
-                                fileLocationController.text;
-                            final String passphrase = passwordController.text;
-                            final String repeatPassphrase =
-                                passwordRepeatController.text;
+                ? Consumer(builder: (context, ref, __) {
+                    return TextButton(
+                      style: shouldEnableCreate
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .getPrimaryEnabledButtonColor(context)
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .getPrimaryDisabledButtonColor(context),
+                      onPressed: !shouldEnableCreate
+                          ? null
+                          : () async {
+                              final String pathToSave =
+                                  fileLocationController.text;
+                              final String passphrase = passwordController.text;
+                              final String repeatPassphrase =
+                                  passwordRepeatController.text;
 
-                            if (pathToSave.isEmpty) {
-                              unawaited(showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "Directory not chosen",
-                                context: context,
-                              ));
-                              return;
-                            }
-                            if (!(await Directory(pathToSave).exists())) {
-                              unawaited(showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "Directory does not exist",
-                                context: context,
-                              ));
-                              return;
-                            }
-                            if (passphrase.isEmpty) {
-                              unawaited(showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "A passphrase is required",
-                                context: context,
-                              ));
-                              return;
-                            }
-                            if (passphrase != repeatPassphrase) {
-                              unawaited(showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "Passphrase does not match",
-                                context: context,
-                              ));
-                              return;
-                            }
-
-                            unawaited(showDialog<dynamic>(
-                              context: context,
-                              barrierDismissible: false,
-                              builder: (_) => const StackDialog(
-                                title: "Encrypting backup",
-                                message: "This shouldn't take long",
-                              ),
-                            ));
-                            // make sure the dialog is able to be displayed for at least 1 second
-                            await Future<void>.delayed(
-                                const Duration(seconds: 1));
-
-                            final DateTime now = DateTime.now();
-                            final String fileToSave =
-                                "$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
-
-                            final backup = await SWB.createStackWalletJSON();
-
-                            bool result =
-                                await SWB.encryptStackWalletWithPassphrase(
-                              fileToSave,
-                              passphrase,
-                              jsonEncode(backup),
-                            );
-
-                            if (mounted) {
-                              // pop encryption progress dialog
-                              Navigator.of(context).pop();
-
-                              if (result) {
-                                await showDialog<dynamic>(
+                              if (pathToSave.isEmpty) {
+                                unawaited(showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "Directory not chosen",
                                   context: context,
-                                  barrierDismissible: false,
-                                  builder: (_) => Platform.isAndroid
-                                      ? StackOkDialog(
-                                          title: "Backup saved to:",
-                                          message: fileToSave,
-                                        )
-                                      : const StackOkDialog(
-                                          title: "Backup creation succeeded"),
-                                );
-                                passwordController.text = "";
-                                passwordRepeatController.text = "";
-                                setState(() {});
-                              } else {
-                                await showDialog<dynamic>(
-                                  context: context,
-                                  barrierDismissible: false,
-                                  builder: (_) => const StackOkDialog(
-                                      title: "Backup creation failed"),
-                                );
+                                ));
+                                return;
                               }
-                            }
-                          },
-                    child: Text(
-                      "Create backup",
-                      style: STextStyles.button(context),
-                    ),
-                  )
+                              if (!(await Directory(pathToSave).exists())) {
+                                unawaited(showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "Directory does not exist",
+                                  context: context,
+                                ));
+                                return;
+                              }
+                              if (passphrase.isEmpty) {
+                                unawaited(showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "A passphrase is required",
+                                  context: context,
+                                ));
+                                return;
+                              }
+                              if (passphrase != repeatPassphrase) {
+                                unawaited(showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "Passphrase does not match",
+                                  context: context,
+                                ));
+                                return;
+                              }
+
+                              unawaited(showDialog<dynamic>(
+                                context: context,
+                                barrierDismissible: false,
+                                builder: (_) => const StackDialog(
+                                  title: "Encrypting backup",
+                                  message: "This shouldn't take long",
+                                ),
+                              ));
+                              // make sure the dialog is able to be displayed for at least 1 second
+                              await Future<void>.delayed(
+                                  const Duration(seconds: 1));
+
+                              final DateTime now = DateTime.now();
+                              final String fileToSave =
+                                  "$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
+
+                              final backup = await SWB.createStackWalletJSON(
+                                  secureStorage: ref.read(secureStoreProvider));
+
+                              bool result =
+                                  await SWB.encryptStackWalletWithPassphrase(
+                                fileToSave,
+                                passphrase,
+                                jsonEncode(backup),
+                              );
+
+                              if (mounted) {
+                                // pop encryption progress dialog
+                                Navigator.of(context).pop();
+
+                                if (result) {
+                                  await showDialog<dynamic>(
+                                    context: context,
+                                    barrierDismissible: false,
+                                    builder: (_) => Platform.isAndroid
+                                        ? StackOkDialog(
+                                            title: "Backup saved to:",
+                                            message: fileToSave,
+                                          )
+                                        : const StackOkDialog(
+                                            title: "Backup creation succeeded"),
+                                  );
+                                  passwordController.text = "";
+                                  passwordRepeatController.text = "";
+                                  setState(() {});
+                                } else {
+                                  await showDialog<dynamic>(
+                                    context: context,
+                                    barrierDismissible: false,
+                                    builder: (_) => const StackOkDialog(
+                                        title: "Backup creation failed"),
+                                  );
+                                }
+                              }
+                            },
+                      child: Text(
+                        "Create backup",
+                        style: STextStyles.button(context),
+                      ),
+                    );
+                  })
                 : Row(
                     children: [
-                      PrimaryButton(
-                        width: 183,
-                        desktopMed: true,
-                        label: "Create backup",
-                        enabled: shouldEnableCreate,
-                        onPressed: !shouldEnableCreate
-                            ? null
-                            : () async {
-                                final String pathToSave =
-                                    fileLocationController.text;
-                                final String passphrase =
-                                    passwordController.text;
-                                final String repeatPassphrase =
-                                    passwordRepeatController.text;
+                      Consumer(builder: (context, ref, __) {
+                        return PrimaryButton(
+                          width: 183,
+                          desktopMed: true,
+                          label: "Create backup",
+                          enabled: shouldEnableCreate,
+                          onPressed: !shouldEnableCreate
+                              ? null
+                              : () async {
+                                  final String pathToSave =
+                                      fileLocationController.text;
+                                  final String passphrase =
+                                      passwordController.text;
+                                  final String repeatPassphrase =
+                                      passwordRepeatController.text;
 
-                                if (pathToSave.isEmpty) {
-                                  unawaited(showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "Directory not chosen",
-                                    context: context,
-                                  ));
-                                  return;
-                                }
-                                if (!(await Directory(pathToSave).exists())) {
-                                  unawaited(showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "Directory does not exist",
-                                    context: context,
-                                  ));
-                                  return;
-                                }
-                                if (passphrase.isEmpty) {
-                                  unawaited(showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "A passphrase is required",
-                                    context: context,
-                                  ));
-                                  return;
-                                }
-                                if (passphrase != repeatPassphrase) {
-                                  unawaited(showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "Passphrase does not match",
-                                    context: context,
-                                  ));
-                                  return;
-                                }
-
-                                unawaited(showDialog<dynamic>(
-                                  context: context,
-                                  barrierDismissible: false,
-                                  builder: (_) => const StackDialog(
-                                    title: "Encrypting backup",
-                                    message: "This shouldn't take long",
-                                  ),
-                                ));
-                                // make sure the dialog is able to be displayed for at least 1 second
-                                await Future<void>.delayed(
-                                    const Duration(seconds: 1));
-
-                                final DateTime now = DateTime.now();
-                                final String fileToSave =
-                                    "$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
-
-                                final backup =
-                                    await SWB.createStackWalletJSON();
-
-                                bool result =
-                                    await SWB.encryptStackWalletWithPassphrase(
-                                  fileToSave,
-                                  passphrase,
-                                  jsonEncode(backup),
-                                );
-
-                                if (mounted) {
-                                  // pop encryption progress dialog
-                                  Navigator.of(context).pop();
-
-                                  if (result) {
-                                    await showDialog<dynamic>(
+                                  if (pathToSave.isEmpty) {
+                                    unawaited(showFloatingFlushBar(
+                                      type: FlushBarType.warning,
+                                      message: "Directory not chosen",
                                       context: context,
-                                      barrierDismissible: false,
-                                      builder: (_) => Platform.isAndroid
-                                          ? StackOkDialog(
-                                              title: "Backup saved to:",
-                                              message: fileToSave,
-                                            )
-                                          : const StackOkDialog(
-                                              title:
-                                                  "Backup creation succeeded"),
-                                    );
-                                    passwordController.text = "";
-                                    passwordRepeatController.text = "";
-                                    setState(() {});
-                                  } else {
-                                    await showDialog<dynamic>(
-                                      context: context,
-                                      barrierDismissible: false,
-                                      builder: (_) => const StackOkDialog(
-                                          title: "Backup creation failed"),
-                                    );
+                                    ));
+                                    return;
                                   }
-                                }
-                              },
-                      ),
+                                  if (!(await Directory(pathToSave).exists())) {
+                                    unawaited(showFloatingFlushBar(
+                                      type: FlushBarType.warning,
+                                      message: "Directory does not exist",
+                                      context: context,
+                                    ));
+                                    return;
+                                  }
+                                  if (passphrase.isEmpty) {
+                                    unawaited(showFloatingFlushBar(
+                                      type: FlushBarType.warning,
+                                      message: "A passphrase is required",
+                                      context: context,
+                                    ));
+                                    return;
+                                  }
+                                  if (passphrase != repeatPassphrase) {
+                                    unawaited(showFloatingFlushBar(
+                                      type: FlushBarType.warning,
+                                      message: "Passphrase does not match",
+                                      context: context,
+                                    ));
+                                    return;
+                                  }
+
+                                  unawaited(showDialog<dynamic>(
+                                    context: context,
+                                    barrierDismissible: false,
+                                    builder: (_) => const StackDialog(
+                                      title: "Encrypting backup",
+                                      message: "This shouldn't take long",
+                                    ),
+                                  ));
+                                  // make sure the dialog is able to be displayed for at least 1 second
+                                  await Future<void>.delayed(
+                                      const Duration(seconds: 1));
+
+                                  final DateTime now = DateTime.now();
+                                  final String fileToSave =
+                                      "$pathToSave/stackbackup_${now.year}_${now.month}_${now.day}_${now.hour}_${now.minute}_${now.second}.swb";
+
+                                  final backup =
+                                      await SWB.createStackWalletJSON(
+                                          secureStorage:
+                                              ref.read(secureStoreProvider));
+
+                                  bool result = await SWB
+                                      .encryptStackWalletWithPassphrase(
+                                    fileToSave,
+                                    passphrase,
+                                    jsonEncode(backup),
+                                  );
+
+                                  if (mounted) {
+                                    // pop encryption progress dialog
+                                    Navigator.of(context).pop();
+
+                                    if (result) {
+                                      await showDialog<dynamic>(
+                                        context: context,
+                                        barrierDismissible: false,
+                                        builder: (_) => Platform.isAndroid
+                                            ? StackOkDialog(
+                                                title: "Backup saved to:",
+                                                message: fileToSave,
+                                              )
+                                            : const StackOkDialog(
+                                                title:
+                                                    "Backup creation succeeded"),
+                                      );
+                                      passwordController.text = "";
+                                      passwordRepeatController.text = "";
+                                      setState(() {});
+                                    } else {
+                                      await showDialog<dynamic>(
+                                        context: context,
+                                        barrierDismissible: false,
+                                        builder: (_) => const StackOkDialog(
+                                            title: "Backup creation failed"),
+                                      );
+                                    }
+                                  }
+                                },
+                        );
+                      }),
                       const SizedBox(
                         width: 16,
                       ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
index 105146aa0..d5ba21634 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
@@ -4,7 +4,6 @@ import 'dart:io';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stack_wallet_backup/stack_wallet_backup.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
@@ -13,6 +12,7 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/backup_frequency_type_select_sheet.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
@@ -21,26 +21,20 @@ import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:zxcvbn/zxcvbn.dart';
 
-import '../../../../utilities/util.dart';
-
 class EditAutoBackupView extends ConsumerStatefulWidget {
   const EditAutoBackupView({
     Key? key,
-    this.secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
   }) : super(key: key);
 
   static const String routeName = "/editAutoBackup";
 
-  final FlutterSecureStorageInterface secureStore;
-
   @override
   ConsumerState<EditAutoBackupView> createState() => _EditAutoBackupViewState();
 }
@@ -74,7 +68,7 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
 
   @override
   void initState() {
-    secureStore = widget.secureStore;
+    secureStore = ref.read(secureStoreProvider);
     stackFileSystem = StackFileSystem();
     fileLocationController = TextEditingController();
     passwordController = TextEditingController();
@@ -586,7 +580,9 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
                               final String fileToSave =
                                   createAutoBackupFilename(pathToSave, now);
 
-                              final backup = await SWB.createStackWalletJSON();
+                              final backup = await SWB.createStackWalletJSON(
+                                secureStorage: ref.read(secureStoreProvider),
+                              );
 
                               bool result = await SWB.encryptStackWalletWithADK(
                                 fileToSave,
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart
index 6d803eb6d..9b755c95a 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart
@@ -3,10 +3,7 @@ import 'dart:convert';
 import 'dart:io';
 import 'dart:typed_data';
 
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:stack_wallet_backup/stack_wallet_backup.dart';
-import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
-import 'package:stackwallet/electrumx_rpc/electrumx.dart';
 import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/models/contact_address_entry.dart';
@@ -91,10 +88,13 @@ abstract class SWB {
 
   static bool _shouldCancelRestore = false;
 
-  static bool _checkShouldCancel(PreRestoreState? revertToState) {
+  static bool _checkShouldCancel(
+    PreRestoreState? revertToState,
+    FlutterSecureStorageInterface secureStorageInterface,
+  ) {
     if (_shouldCancelRestore) {
       if (revertToState != null) {
-        _revert(revertToState);
+        _revert(revertToState, secureStorageInterface);
       } else {
         _cancelCompleter!.complete();
         _shouldCancelRestore = false;
@@ -193,15 +193,15 @@ abstract class SWB {
 
   /// [secureStorage] parameter exposed for testing purposes
   static Future<Map<String, dynamic>> createStackWalletJSON({
-    FlutterSecureStorageInterface? secureStorage,
+    required FlutterSecureStorageInterface secureStorage,
   }) async {
     Logging.instance
         .log("Starting createStackWalletJSON...", level: LogLevel.Info);
     final _wallets = Wallets.sharedInstance;
     Map<String, dynamic> backupJson = {};
-    NodeService nodeService = NodeService();
-    final _secureStore =
-        secureStorage ?? const SecureStorageWrapper(FlutterSecureStorage());
+    NodeService nodeService =
+        NodeService(secureStorageInterface: secureStorage);
+    final _secureStore = secureStorage;
 
     Logging.instance.log("createStackWalletJSON awaiting DB.instance.mutex...",
         level: LogLevel.Info);
@@ -448,6 +448,7 @@ abstract class SWB {
     Map<String, dynamic> validJSON,
     StackRestoringUIState? uiState,
     Map<String, String> oldToNewWalletIdMap,
+    FlutterSecureStorageInterface secureStorageInterface,
   ) async {
     Map<String, dynamic> prefs = validJSON["prefs"] as Map<String, dynamic>;
     List<dynamic>? addressBookEntries =
@@ -486,7 +487,11 @@ abstract class SWB {
       "SWB restoring nodes",
       level: LogLevel.Warning,
     );
-    await _restoreNodes(nodes, primaryNodes);
+    await _restoreNodes(
+      nodes,
+      primaryNodes,
+      secureStorageInterface,
+    );
 
     uiState?.nodes = StackRestoringStatus.success;
     uiState?.trades = StackRestoringStatus.restoring;
@@ -543,6 +548,7 @@ abstract class SWB {
   static Future<bool?> restoreStackWalletJSON(
     String jsonBackup,
     StackRestoringUIState? uiState,
+    FlutterSecureStorageInterface secureStorageInterface,
   ) async {
     if (!Platform.isLinux) await Wakelock.enable();
 
@@ -550,7 +556,8 @@ abstract class SWB {
       "SWB creating temp backup",
       level: LogLevel.Warning,
     );
-    final preRestoreJSON = await createStackWalletJSON();
+    final preRestoreJSON =
+        await createStackWalletJSON(secureStorage: secureStorageInterface);
     Logging.instance.log(
       "SWB temp backup created",
       level: LogLevel.Warning,
@@ -587,19 +594,34 @@ abstract class SWB {
 
     // basic cancel check here
     // no reverting required yet as nothing has been written to store
-    if (_checkShouldCancel(null)) {
+    if (_checkShouldCancel(
+      null,
+      secureStorageInterface,
+    )) {
       return false;
     }
 
-    await _restoreEverythingButWallets(validJSON, uiState, oldToNewWalletIdMap);
+    await _restoreEverythingButWallets(
+      validJSON,
+      uiState,
+      oldToNewWalletIdMap,
+      secureStorageInterface,
+    );
 
     // check if cancel was requested and restore previous state
-    if (_checkShouldCancel(preRestoreState)) {
+    if (_checkShouldCancel(
+      preRestoreState,
+      secureStorageInterface,
+    )) {
       return false;
     }
 
-    final nodeService = NodeService();
-    final walletsService = WalletsService();
+    final nodeService = NodeService(
+      secureStorageInterface: secureStorageInterface,
+    );
+    final walletsService = WalletsService(
+      secureStorageInterface: secureStorageInterface,
+    );
     final _prefs = Prefs.instance;
     await _prefs.init();
 
@@ -609,7 +631,10 @@ abstract class SWB {
 
     for (var walletbackup in wallets) {
       // check if cancel was requested and restore previous state
-      if (_checkShouldCancel(preRestoreState)) {
+      if (_checkShouldCancel(
+        preRestoreState,
+        secureStorageInterface,
+      )) {
         return false;
       }
 
@@ -647,7 +672,10 @@ abstract class SWB {
       final failovers = nodeService.failoverNodesFor(coin: coin);
 
       // check if cancel was requested and restore previous state
-      if (_checkShouldCancel(preRestoreState)) {
+      if (_checkShouldCancel(
+        preRestoreState,
+        secureStorageInterface,
+      )) {
         return false;
       }
 
@@ -655,6 +683,7 @@ abstract class SWB {
         coin,
         walletId,
         walletName,
+        secureStorageInterface,
         node,
         txTracker,
         _prefs,
@@ -665,7 +694,10 @@ abstract class SWB {
 
       managers.add(Tuple2(walletbackup, manager));
       // check if cancel was requested and restore previous state
-      if (_checkShouldCancel(preRestoreState)) {
+      if (_checkShouldCancel(
+        preRestoreState,
+        secureStorageInterface,
+      )) {
         return false;
       }
 
@@ -679,7 +711,10 @@ abstract class SWB {
     }
 
     // check if cancel was requested and restore previous state
-    if (_checkShouldCancel(preRestoreState)) {
+    if (_checkShouldCancel(
+      preRestoreState,
+      secureStorageInterface,
+    )) {
       return false;
     }
 
@@ -690,7 +725,10 @@ abstract class SWB {
     // start restoring wallets
     for (final tuple in managers) {
       // check if cancel was requested and restore previous state
-      if (_checkShouldCancel(preRestoreState)) {
+      if (_checkShouldCancel(
+        preRestoreState,
+        secureStorageInterface,
+      )) {
         return false;
       }
       final bools = await asyncRestore(tuple, uiState, walletsService);
@@ -698,13 +736,19 @@ abstract class SWB {
     }
 
     // check if cancel was requested and restore previous state
-    if (_checkShouldCancel(preRestoreState)) {
+    if (_checkShouldCancel(
+      preRestoreState,
+      secureStorageInterface,
+    )) {
       return false;
     }
 
     for (Future<bool> status in restoreStatuses) {
       // check if cancel was requested and restore previous state
-      if (_checkShouldCancel(preRestoreState)) {
+      if (_checkShouldCancel(
+        preRestoreState,
+        secureStorageInterface,
+      )) {
         return false;
       }
       await status;
@@ -712,7 +756,10 @@ abstract class SWB {
 
     if (!Platform.isLinux) await Wakelock.disable();
     // check if cancel was requested and restore previous state
-    if (_checkShouldCancel(preRestoreState)) {
+    if (_checkShouldCancel(
+      preRestoreState,
+      secureStorageInterface,
+    )) {
       return false;
     }
 
@@ -720,7 +767,10 @@ abstract class SWB {
     return true;
   }
 
-  static Future<void> _revert(PreRestoreState revertToState) async {
+  static Future<void> _revert(
+    PreRestoreState revertToState,
+    FlutterSecureStorageInterface secureStorageInterface,
+  ) async {
     Map<String, dynamic> prefs =
         revertToState.validJSON["prefs"] as Map<String, dynamic>;
     List<dynamic>? addressBookEntries =
@@ -788,7 +838,9 @@ abstract class SWB {
     }
 
     // nodes
-    NodeService nodeService = NodeService();
+    NodeService nodeService = NodeService(
+      secureStorageInterface: secureStorageInterface,
+    );
     final currentNodes = nodeService.nodes;
     if (nodes == null) {
       // no pre nodes found so we delete all but defaults
@@ -914,7 +966,8 @@ abstract class SWB {
     }
 
     // finally remove any added wallets
-    final walletsService = WalletsService();
+    final walletsService =
+        WalletsService(secureStorageInterface: secureStorageInterface);
     final namesData = await walletsService.walletNames;
     for (final entry in namesData.entries) {
       if (!revertToState.walletIds.contains(entry.value.walletId)) {
@@ -989,8 +1042,11 @@ abstract class SWB {
   static Future<void> _restoreNodes(
     List<dynamic>? nodes,
     List<dynamic>? primaryNodes,
+    FlutterSecureStorageInterface secureStorageInterface,
   ) async {
-    NodeService nodeService = NodeService();
+    NodeService nodeService = NodeService(
+      secureStorageInterface: secureStorageInterface,
+    );
     if (nodes != null) {
       for (var node in nodes) {
         await nodeService.add(
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
index 5e5142425..3097ec72a 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
@@ -10,6 +10,7 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/stack_backup_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/stack_restore/stack_restoring_ui_state_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -107,6 +108,7 @@ class _StackRestoreProgressViewState
       finished = await SWB.restoreStackWalletJSON(
         widget.jsonString,
         uiState,
+        ref.read(secureStoreProvider),
       );
     } catch (e, s) {
       Logging.instance.log("$e\n$s", level: LogLevel.Warning);
diff --git a/lib/pages_desktop_specific/create_password/create_password_view.dart b/lib/pages_desktop_specific/create_password/create_password_view.dart
index 0a8429058..1e137500d 100644
--- a/lib/pages_desktop_specific/create_password/create_password_view.dart
+++ b/lib/pages_desktop_specific/create_password/create_password_view.dart
@@ -2,7 +2,6 @@ import 'dart:async';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
@@ -10,7 +9,6 @@ import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.da
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
-import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -23,15 +21,10 @@ import 'package:zxcvbn/zxcvbn.dart';
 class CreatePasswordView extends ConsumerStatefulWidget {
   const CreatePasswordView({
     Key? key,
-    this.secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
   }) : super(key: key);
 
   static const String routeName = "/createPasswordDesktop";
 
-  final FlutterSecureStorageInterface secureStore;
-
   @override
   ConsumerState<CreatePasswordView> createState() => _CreatePasswordViewState();
 }
diff --git a/lib/providers/global/auto_swb_service_provider.dart b/lib/providers/global/auto_swb_service_provider.dart
index 51a7c4e59..10cf2592f 100644
--- a/lib/providers/global/auto_swb_service_provider.dart
+++ b/lib/providers/global/auto_swb_service_provider.dart
@@ -1,5 +1,9 @@
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/services/auto_swb_service.dart';
 
-final autoSWBServiceProvider =
-    ChangeNotifierProvider<AutoSWBService>((_) => AutoSWBService());
+final autoSWBServiceProvider = ChangeNotifierProvider<AutoSWBService>(
+  (ref) => AutoSWBService(
+    secureStorageInterface: ref.read(secureStoreProvider),
+  ),
+);
diff --git a/lib/providers/global/node_service_provider.dart b/lib/providers/global/node_service_provider.dart
index 97cea48f9..81ab22426 100644
--- a/lib/providers/global/node_service_provider.dart
+++ b/lib/providers/global/node_service_provider.dart
@@ -1,15 +1,16 @@
 import 'package:flutter/foundation.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/services/node_service.dart';
 
 int _count = 0;
 final nodeServiceChangeNotifierProvider =
-    ChangeNotifierProvider<NodeService>((_) {
+    ChangeNotifierProvider<NodeService>((ref) {
   if (kDebugMode) {
     _count++;
     debugPrint(
         "nodeServiceChangeNotifierProvider instantiation count: $_count");
   }
 
-  return NodeService();
+  return NodeService(secureStorageInterface: ref.read(secureStoreProvider));
 });
diff --git a/lib/providers/global/secure_store_provider.dart b/lib/providers/global/secure_store_provider.dart
new file mode 100644
index 000000000..299ea0f5c
--- /dev/null
+++ b/lib/providers/global/secure_store_provider.dart
@@ -0,0 +1,18 @@
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
+import 'package:stackwallet/utilities/util.dart';
+
+final secureStoreProvider = Provider<FlutterSecureStorageInterface>((ref) {
+  if (Util.isDesktop) {
+    final handler = ref.read(storageCryptoHandlerProvider).handler;
+    return SecureStorageWrapper(
+        store: DesktopPWStore(handler), isDesktop: true);
+  } else {
+    return const SecureStorageWrapper(
+      store: FlutterSecureStorage(),
+      isDesktop: false,
+    );
+  }
+});
diff --git a/lib/providers/global/wallets_service_provider.dart b/lib/providers/global/wallets_service_provider.dart
index 7e46d076b..363d57613 100644
--- a/lib/providers/global/wallets_service_provider.dart
+++ b/lib/providers/global/wallets_service_provider.dart
@@ -1,16 +1,19 @@
 import 'package:flutter/foundation.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/services/wallets_service.dart';
 
 int _count = 0;
 
 final walletsServiceChangeNotifierProvider =
-    ChangeNotifierProvider<WalletsService>((_) {
+    ChangeNotifierProvider<WalletsService>((ref) {
   if (kDebugMode) {
     _count++;
     debugPrint(
         "walletsServiceChangeNotifierProvider instantiation count: $_count");
   }
 
-  return WalletsService();
+  return WalletsService(
+    secureStorageInterface: ref.read(secureStoreProvider),
+  );
 });
diff --git a/lib/services/auto_swb_service.dart b/lib/services/auto_swb_service.dart
index e3ce02f15..06ec7a2fb 100644
--- a/lib/services/auto_swb_service.dart
+++ b/lib/services/auto_swb_service.dart
@@ -3,7 +3,6 @@ import 'dart:convert';
 import 'dart:io';
 
 import 'package:flutter/foundation.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
@@ -27,9 +26,7 @@ class AutoSWBService extends ChangeNotifier {
 
   final FlutterSecureStorageInterface secureStorageInterface;
 
-  AutoSWBService(
-      {this.secureStorageInterface =
-          const SecureStorageWrapper(FlutterSecureStorage())});
+  AutoSWBService({required this.secureStorageInterface});
 
   /// Attempt a backup.
   Future<void> doBackup() async {
diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart
index d0920075d..e3c2f13fd 100644
--- a/lib/services/coins/bitcoin/bitcoin_wallet.dart
+++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart
@@ -12,7 +12,6 @@ import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
 import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
 import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@@ -1369,7 +1368,7 @@ class BitcoinWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    FlutterSecureStorageInterface? secureStore,
+    required FlutterSecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
@@ -1379,13 +1378,12 @@ class BitcoinWallet extends CoinServiceAPI {
     _cachedElectrumXClient = cachedClient;
 
     _priceAPI = priceAPI ?? PriceAPI(Client());
-    _secureStore =
-        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+    _secureStore = secureStore;
   }
 
   @override
   Future<void> updateNode(bool shouldRefresh) async {
-    final failovers = NodeService()
+    final failovers = NodeService(secureStorageInterface: _secureStore)
         .failoverNodesFor(coin: coin)
         .map((e) => ElectrumXNode(
               address: e.host,
@@ -1423,7 +1421,8 @@ class BitcoinWallet extends CoinServiceAPI {
   }
 
   Future<ElectrumXNode> getCurrentNode() async {
-    final node = NodeService().getPrimaryNodeFor(coin: coin) ??
+    final node = NodeService(secureStorageInterface: _secureStore)
+            .getPrimaryNodeFor(coin: coin) ??
         DefaultNodes.getNodeFor(coin);
 
     return ElectrumXNode(
diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index 5b3b54663..063c74315 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -13,7 +13,6 @@ import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
 import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
 import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@@ -1274,7 +1273,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    FlutterSecureStorageInterface? secureStore,
+    required FlutterSecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
@@ -1284,13 +1283,12 @@ class BitcoinCashWallet extends CoinServiceAPI {
     _cachedElectrumXClient = cachedClient;
 
     _priceAPI = priceAPI ?? PriceAPI(Client());
-    _secureStore =
-        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+    _secureStore = secureStore;
   }
 
   @override
   Future<void> updateNode(bool shouldRefresh) async {
-    final failovers = NodeService()
+    final failovers = NodeService(secureStorageInterface: _secureStore)
         .failoverNodesFor(coin: coin)
         .map((e) => ElectrumXNode(
               address: e.host,
@@ -1328,7 +1326,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
   }
 
   Future<ElectrumXNode> getCurrentNode() async {
-    final node = NodeService().getPrimaryNodeFor(coin: coin) ??
+    final node = NodeService(secureStorageInterface: _secureStore)
+            .getPrimaryNodeFor(coin: coin) ??
         DefaultNodes.getNodeFor(coin);
 
     return ElectrumXNode(
diff --git a/lib/services/coins/coin_service.dart b/lib/services/coins/coin_service.dart
index 655865494..e63ff86e1 100644
--- a/lib/services/coins/coin_service.dart
+++ b/lib/services/coins/coin_service.dart
@@ -13,6 +13,7 @@ import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart';
 import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
 import 'package:stackwallet/services/transaction_notification_tracker.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 
 import 'litecoin/litecoin_wallet.dart';
@@ -24,6 +25,7 @@ abstract class CoinServiceAPI {
     Coin coin,
     String walletId,
     String walletName,
+    FlutterSecureStorageInterface secureStorageInterface,
     NodeModel node,
     TransactionNotificationTracker tracker,
     Prefs prefs,
@@ -68,6 +70,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
@@ -77,6 +80,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
@@ -87,6 +91,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
@@ -97,6 +102,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
@@ -107,6 +113,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
@@ -117,6 +124,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
@@ -127,6 +135,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
@@ -137,6 +146,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
@@ -147,6 +157,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
@@ -157,6 +168,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           // tracker: tracker,
         );
 
@@ -165,6 +177,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           // tracker: tracker,
         );
 
@@ -173,6 +186,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           // tracker: tracker,
         );
 
@@ -181,6 +195,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           tracker: tracker,
           cachedClient: cachedClient,
           client: client,
@@ -191,6 +206,7 @@ abstract class CoinServiceAPI {
           walletId: walletId,
           walletName: walletName,
           coin: coin,
+          secureStore: secureStorageInterface,
           client: client,
           cachedClient: cachedClient,
           tracker: tracker,
diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart
index 67be291a2..c3100b0f7 100644
--- a/lib/services/coins/dogecoin/dogecoin_wallet.dart
+++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart
@@ -12,7 +12,6 @@ import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
 import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
 import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@@ -1137,7 +1136,7 @@ class DogecoinWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    FlutterSecureStorageInterface? secureStore,
+    required FlutterSecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
@@ -1147,13 +1146,12 @@ class DogecoinWallet extends CoinServiceAPI {
     _cachedElectrumXClient = cachedClient;
 
     _priceAPI = priceAPI ?? PriceAPI(Client());
-    _secureStore =
-        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+    _secureStore = secureStore;
   }
 
   @override
   Future<void> updateNode(bool shouldRefresh) async {
-    final failovers = NodeService()
+    final failovers = NodeService(secureStorageInterface: _secureStore)
         .failoverNodesFor(coin: coin)
         .map((e) => ElectrumXNode(
               address: e.host,
@@ -1191,7 +1189,8 @@ class DogecoinWallet extends CoinServiceAPI {
   }
 
   Future<ElectrumXNode> getCurrentNode() async {
-    final node = NodeService().getPrimaryNodeFor(coin: coin) ??
+    final node = NodeService(secureStorageInterface: _secureStore)
+            .getPrimaryNodeFor(coin: coin) ??
         DefaultNodes.getNodeFor(coin);
 
     return ElectrumXNode(
diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart
index 6c71f39e4..d7b7f35dd 100644
--- a/lib/services/coins/epiccash/epiccash_wallet.dart
+++ b/lib/services/coins/epiccash/epiccash_wallet.dart
@@ -6,7 +6,6 @@ import 'dart:isolate';
 import 'package:decimal/decimal.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter_libepiccash/epic_cash.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:hive/hive.dart';
 import 'package:http/http.dart';
 import 'package:mutex/mutex.dart';
@@ -518,14 +517,13 @@ class EpicCashWallet extends CoinServiceAPI {
       required String walletName,
       required Coin coin,
       PriceAPI? priceAPI,
-      FlutterSecureStorageInterface? secureStore}) {
+      required FlutterSecureStorageInterface secureStore}) {
     _walletId = walletId;
     _walletName = walletName;
     _coin = coin;
 
     _priceAPI = priceAPI ?? PriceAPI(Client());
-    _secureStore =
-        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+    _secureStore = secureStore;
 
     Logging.instance.log("$walletName isolate length: ${isolates.length}",
         level: LogLevel.Info);
@@ -537,7 +535,8 @@ class EpicCashWallet extends CoinServiceAPI {
 
   @override
   Future<void> updateNode(bool shouldRefresh) async {
-    _epicNode = NodeService().getPrimaryNodeFor(coin: coin) ??
+    _epicNode = NodeService(secureStorageInterface: _secureStore)
+            .getPrimaryNodeFor(coin: coin) ??
         DefaultNodes.getNodeFor(coin);
     // TODO notify ui/ fire event for node changed?
 
diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart
index d19c4f1ab..d0f99ef1d 100644
--- a/lib/services/coins/firo/firo_wallet.dart
+++ b/lib/services/coins/firo/firo_wallet.dart
@@ -11,7 +11,6 @@ import 'package:bitcoindart/bitcoindart.dart';
 import 'package:decimal/decimal.dart';
 import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
 import 'package:lelantus/lelantus.dart';
 import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
@@ -1321,7 +1320,7 @@ class FiroWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    FlutterSecureStorageInterface? secureStore,
+    required FlutterSecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
@@ -1331,8 +1330,7 @@ class FiroWallet extends CoinServiceAPI {
     _cachedElectrumXClient = cachedClient;
 
     _priceAPI = priceAPI ?? PriceAPI(Client());
-    _secureStore =
-        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+    _secureStore = secureStore;
 
     Logging.instance.log("$walletName isolates length: ${isolates.length}",
         level: LogLevel.Info);
@@ -1870,7 +1868,7 @@ class FiroWallet extends CoinServiceAPI {
 
   @override
   Future<void> updateNode(bool shouldRefresh) async {
-    final failovers = NodeService()
+    final failovers = NodeService(secureStorageInterface: _secureStore)
         .failoverNodesFor(coin: coin)
         .map(
           (e) => ElectrumXNode(
@@ -3071,7 +3069,8 @@ class FiroWallet extends CoinServiceAPI {
   }
 
   Future<ElectrumXNode> _getCurrentNode() async {
-    final node = NodeService().getPrimaryNodeFor(coin: coin) ??
+    final node = NodeService(secureStorageInterface: _secureStore)
+            .getPrimaryNodeFor(coin: coin) ??
         DefaultNodes.getNodeFor(coin);
 
     return ElectrumXNode(
diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart
index 4551325f7..30d6ede39 100644
--- a/lib/services/coins/litecoin/litecoin_wallet.dart
+++ b/lib/services/coins/litecoin/litecoin_wallet.dart
@@ -12,7 +12,6 @@ import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
 import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
 import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@@ -1371,7 +1370,7 @@ class LitecoinWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    FlutterSecureStorageInterface? secureStore,
+    required FlutterSecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
@@ -1381,13 +1380,12 @@ class LitecoinWallet extends CoinServiceAPI {
     _cachedElectrumXClient = cachedClient;
 
     _priceAPI = priceAPI ?? PriceAPI(Client());
-    _secureStore =
-        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+    _secureStore = secureStore;
   }
 
   @override
   Future<void> updateNode(bool shouldRefresh) async {
-    final failovers = NodeService()
+    final failovers = NodeService(secureStorageInterface: _secureStore)
         .failoverNodesFor(coin: coin)
         .map((e) => ElectrumXNode(
               address: e.host,
@@ -1425,7 +1423,8 @@ class LitecoinWallet extends CoinServiceAPI {
   }
 
   Future<ElectrumXNode> getCurrentNode() async {
-    final node = NodeService().getPrimaryNodeFor(coin: coin) ??
+    final node = NodeService(secureStorageInterface: _secureStore)
+            .getPrimaryNodeFor(coin: coin) ??
         DefaultNodes.getNodeFor(coin);
 
     return ElectrumXNode(
diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index 662d4077b..569498a15 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -72,7 +72,8 @@ class MoneroWallet extends CoinServiceAPI {
   late PriceAPI _priceAPI;
 
   Future<NodeModel> getCurrentNode() async {
-    return NodeService().getPrimaryNodeFor(coin: coin) ??
+    return NodeService(secureStorageInterface: _secureStore)
+            .getPrimaryNodeFor(coin: coin) ??
         DefaultNodes.getNodeFor(coin);
   }
 
@@ -81,14 +82,13 @@ class MoneroWallet extends CoinServiceAPI {
       required String walletName,
       required Coin coin,
       PriceAPI? priceAPI,
-      FlutterSecureStorageInterface? secureStore}) {
+      required FlutterSecureStorageInterface secureStore}) {
     _walletId = walletId;
     _walletName = walletName;
     _coin = coin;
 
     _priceAPI = priceAPI ?? PriceAPI(Client());
-    _secureStore =
-        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+    _secureStore = secureStore;
   }
 
   bool _shouldAutoSync = false;
diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart
index 8a4b26012..1ebf87233 100644
--- a/lib/services/coins/namecoin/namecoin_wallet.dart
+++ b/lib/services/coins/namecoin/namecoin_wallet.dart
@@ -12,7 +12,6 @@ import 'package:crypto/crypto.dart';
 import 'package:decimal/decimal.dart';
 import 'package:devicelocale/devicelocale.dart';
 import 'package:flutter/foundation.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
 import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@@ -1362,7 +1361,7 @@ class NamecoinWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    FlutterSecureStorageInterface? secureStore,
+    required FlutterSecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
@@ -1372,13 +1371,12 @@ class NamecoinWallet extends CoinServiceAPI {
     _cachedElectrumXClient = cachedClient;
 
     _priceAPI = priceAPI ?? PriceAPI(Client());
-    _secureStore =
-        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+    _secureStore = secureStore;
   }
 
   @override
   Future<void> updateNode(bool shouldRefresh) async {
-    final failovers = NodeService()
+    final failovers = NodeService(secureStorageInterface: _secureStore)
         .failoverNodesFor(coin: coin)
         .map((e) => ElectrumXNode(
               address: e.host,
@@ -1416,7 +1414,8 @@ class NamecoinWallet extends CoinServiceAPI {
   }
 
   Future<ElectrumXNode> getCurrentNode() async {
-    final node = NodeService().getPrimaryNodeFor(coin: coin) ??
+    final node = NodeService(secureStorageInterface: _secureStore)
+            .getPrimaryNodeFor(coin: coin) ??
         DefaultNodes.getNodeFor(coin);
 
     return ElectrumXNode(
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 788f2f9d8..7a219158a 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -73,7 +73,8 @@ class WowneroWallet extends CoinServiceAPI {
   late PriceAPI _priceAPI;
 
   Future<NodeModel> getCurrentNode() async {
-    return NodeService().getPrimaryNodeFor(coin: coin) ??
+    return NodeService(secureStorageInterface: _secureStore)
+            .getPrimaryNodeFor(coin: coin) ??
         DefaultNodes.getNodeFor(coin);
   }
 
@@ -82,14 +83,13 @@ class WowneroWallet extends CoinServiceAPI {
       required String walletName,
       required Coin coin,
       PriceAPI? priceAPI,
-      FlutterSecureStorageInterface? secureStore}) {
+      required FlutterSecureStorageInterface secureStore}) {
     _walletId = walletId;
     _walletName = walletName;
     _coin = coin;
 
     _priceAPI = priceAPI ?? PriceAPI(Client());
-    _secureStore =
-        secureStore ?? const SecureStorageWrapper(FlutterSecureStorage());
+    _secureStore = secureStore;
   }
 
   bool _shouldAutoSync = false;
diff --git a/lib/services/node_service.dart b/lib/services/node_service.dart
index 5b9fe5063..0dd706781 100644
--- a/lib/services/node_service.dart
+++ b/lib/services/node_service.dart
@@ -1,7 +1,6 @@
 import 'dart:convert';
 
 import 'package:flutter/material.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
 import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/models/node_model.dart';
@@ -17,9 +16,7 @@ class NodeService extends ChangeNotifier {
 
   /// Exposed [secureStorageInterface] in order to inject mock for tests
   NodeService({
-    this.secureStorageInterface = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
+    required this.secureStorageInterface,
   });
 
   Future<void> updateDefaults() async {
diff --git a/lib/services/wallets.dart b/lib/services/wallets.dart
index db3011d4e..cebba2ce5 100644
--- a/lib/services/wallets.dart
+++ b/lib/services/wallets.dart
@@ -205,13 +205,14 @@ class Wallets extends ChangeNotifier {
             final txTracker =
                 TransactionNotificationTracker(walletId: walletId);
 
-            final failovers = NodeService().failoverNodesFor(coin: coin);
+            final failovers = nodeService.failoverNodesFor(coin: coin);
 
             // load wallet
             final wallet = CoinServiceAPI.from(
               coin,
               walletId,
               entry.value.name,
+              nodeService.secureStorageInterface,
               node,
               txTracker,
               prefs,
diff --git a/lib/services/wallets_service.dart b/lib/services/wallets_service.dart
index b30f9e9e5..237df8026 100644
--- a/lib/services/wallets_service.dart
+++ b/lib/services/wallets_service.dart
@@ -3,7 +3,6 @@ import 'dart:convert';
 import 'package:flutter/material.dart';
 import 'package:flutter_libmonero/monero/monero.dart';
 import 'package:flutter_libmonero/wownero/wownero.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
 import 'package:stackwallet/services/notifications_service.dart';
@@ -55,10 +54,7 @@ class WalletsService extends ChangeNotifier {
       _walletNames ??= _fetchWalletNames();
 
   WalletsService({
-    FlutterSecureStorageInterface secureStorageInterface =
-        const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
+    required FlutterSecureStorageInterface secureStorageInterface,
   }) {
     _secureStore = secureStorageInterface;
   }
diff --git a/lib/utilities/db_version_migration.dart b/lib/utilities/db_version_migration.dart
index d1763e266..afb38a487 100644
--- a/lib/utilities/db_version_migration.dart
+++ b/lib/utilities/db_version_migration.dart
@@ -1,4 +1,3 @@
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:hive/hive.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx.dart';
 import 'package:stackwallet/hive/db.dart';
@@ -17,9 +16,7 @@ import 'package:stackwallet/utilities/prefs.dart';
 class DbVersionMigrator {
   Future<void> migrate(
     int fromVersion, {
-    FlutterSecureStorageInterface secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
+    required FlutterSecureStorageInterface secureStore,
   }) async {
     Logging.instance.log(
       "Running migrate fromVersion $fromVersion",
@@ -29,8 +26,9 @@ class DbVersionMigrator {
       case 0:
         await Hive.openBox<dynamic>(DB.boxNameAllWalletsData);
         await Hive.openBox<dynamic>(DB.boxNamePrefs);
-        final walletsService = WalletsService();
-        final nodeService = NodeService();
+        final walletsService =
+            WalletsService(secureStorageInterface: secureStore);
+        final nodeService = NodeService(secureStorageInterface: secureStore);
         final prefs = Prefs.instance;
         final walletInfoList = await walletsService.walletNames;
         await prefs.init();
@@ -118,7 +116,7 @@ class DbVersionMigrator {
             boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 1);
 
         // try to continue migrating
-        return await migrate(1);
+        return await migrate(1, secureStore: secureStore);
 
       case 1:
         await Hive.openBox<ExchangeTransaction>(DB.boxNameTrades);
@@ -142,7 +140,7 @@ class DbVersionMigrator {
             boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 2);
 
         // try to continue migrating
-        return await migrate(2);
+        return await migrate(2, secureStore: secureStore);
       case 2:
         await Hive.openBox<dynamic>(DB.boxNamePrefs);
         final prefs = Prefs.instance;
@@ -154,7 +152,7 @@ class DbVersionMigrator {
         // update version
         await DB.instance.put<dynamic>(
             boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 3);
-        return await migrate(3);
+        return await migrate(3, secureStore: secureStore);
 
       default:
         // finally return
diff --git a/lib/utilities/desktop_password_service.dart b/lib/utilities/desktop_password_service.dart
index da537b3c2..7a2047c30 100644
--- a/lib/utilities/desktop_password_service.dart
+++ b/lib/utilities/desktop_password_service.dart
@@ -1,6 +1,6 @@
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:hive/hive.dart';
 import 'package:stack_wallet_backup/secure_storage.dart';
-import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
+import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/utilities/logger.dart';
 
 const String _kKeyBlobKey = "swbKeyBlobKeyStringID";
@@ -24,7 +24,6 @@ String _getMessageFromException(Object exception) {
 
 class DPS {
   StorageCryptoHandler? _handler;
-  final SecureStorageWrapper secureStorageWrapper;
 
   StorageCryptoHandler get handler {
     if (_handler == null) {
@@ -34,11 +33,7 @@ class DPS {
     return _handler!;
   }
 
-  DPS({
-    this.secureStorageWrapper = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
-  });
+  DPS();
 
   Future<void> initFromNew(String passphrase) async {
     if (_handler != null) {
@@ -47,10 +42,14 @@ class DPS {
 
     try {
       _handler = await StorageCryptoHandler.fromNewPassphrase(passphrase);
-      await secureStorageWrapper.write(
+
+      final box = await Hive.openBox<String>(DB.boxNameDesktopData);
+      await DB.instance.put<String>(
+        boxName: DB.boxNameDesktopData,
         key: _kKeyBlobKey,
         value: await _handler!.getKeyBlob(),
       );
+      await box.close();
     } catch (e, s) {
       Logging.instance.log(
         "${_getMessageFromException(e)}\n$s",
@@ -65,7 +64,13 @@ class DPS {
       throw Exception(
           "DPS: attempted to re initialize with existing passphrase");
     }
-    final keyBlob = await secureStorageWrapper.read(key: _kKeyBlobKey);
+
+    final box = await Hive.openBox<String>(DB.boxNameDesktopData);
+    final keyBlob = DB.instance.get<String>(
+      boxName: DB.boxNameDesktopData,
+      key: _kKeyBlobKey,
+    );
+    await box.close();
 
     if (keyBlob == null) {
       throw Exception(
@@ -84,6 +89,12 @@ class DPS {
   }
 
   Future<bool> hasPassword() async {
-    return (await secureStorageWrapper.read(key: _kKeyBlobKey)) != null;
+    final box = await Hive.openBox<String>(DB.boxNameDesktopData);
+    final keyBlob = DB.instance.get<String>(
+      boxName: DB.boxNameDesktopData,
+      key: _kKeyBlobKey,
+    );
+    await box.close();
+    return keyBlob != null;
   }
 }
diff --git a/lib/utilities/flutter_secure_storage_interface.dart b/lib/utilities/flutter_secure_storage_interface.dart
index f8163ae49..f36af94f7 100644
--- a/lib/utilities/flutter_secure_storage_interface.dart
+++ b/lib/utilities/flutter_secure_storage_interface.dart
@@ -1,4 +1,6 @@
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:isar/isar.dart';
+import 'package:stack_wallet_backup/secure_storage.dart';
 
 abstract class FlutterSecureStorageInterface {
   Future<void> write({
@@ -33,10 +35,49 @@ abstract class FlutterSecureStorageInterface {
   });
 }
 
-class SecureStorageWrapper implements FlutterSecureStorageInterface {
-  final FlutterSecureStorage secureStore;
+class DesktopPWStore {
+  final StorageCryptoHandler handler;
+  late final Isar isar;
 
-  const SecureStorageWrapper(this.secureStore);
+  DesktopPWStore(this.handler);
+
+  Future<void> init() async {}
+
+  Future<String?> read({
+    required String key,
+  }) async {
+    // final String encryptedString =
+
+    return "";
+  }
+
+  Future<void> write({
+    required String key,
+    required String? value,
+  }) async {
+    return;
+  }
+
+  Future<void> delete({
+    required String key,
+  }) async {
+    return;
+  }
+}
+
+/// all *Options params ignored on desktop
+class SecureStorageWrapper implements FlutterSecureStorageInterface {
+  final dynamic _store;
+  final bool _isDesktop;
+
+  const SecureStorageWrapper({
+    required dynamic store,
+    required bool isDesktop,
+  })  : assert(isDesktop
+            ? store is DesktopPWStore
+            : store is FlutterSecureStorage),
+        _store = store,
+        _isDesktop = isDesktop;
 
   @override
   Future<String?> read({
@@ -47,16 +88,20 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
     WebOptions? webOptions,
     MacOsOptions? mOptions,
     WindowsOptions? wOptions,
-  }) {
-    return secureStore.read(
-      key: key,
-      iOptions: iOptions,
-      aOptions: aOptions,
-      lOptions: lOptions,
-      webOptions: webOptions,
-      mOptions: mOptions,
-      wOptions: wOptions,
-    );
+  }) async {
+    if (_isDesktop) {
+      return await (_store as DesktopPWStore).read(key: key);
+    } else {
+      return await (_store as FlutterSecureStorage).read(
+        key: key,
+        iOptions: iOptions,
+        aOptions: aOptions,
+        lOptions: lOptions,
+        webOptions: webOptions,
+        mOptions: mOptions,
+        wOptions: wOptions,
+      );
+    }
   }
 
   @override
@@ -69,17 +114,21 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
     WebOptions? webOptions,
     MacOsOptions? mOptions,
     WindowsOptions? wOptions,
-  }) {
-    return secureStore.write(
-      key: key,
-      value: value,
-      iOptions: iOptions,
-      aOptions: aOptions,
-      lOptions: lOptions,
-      webOptions: webOptions,
-      mOptions: mOptions,
-      wOptions: wOptions,
-    );
+  }) async {
+    if (_isDesktop) {
+      return await (_store as DesktopPWStore).write(key: key, value: value);
+    } else {
+      return await (_store as FlutterSecureStorage).write(
+        key: key,
+        value: value,
+        iOptions: iOptions,
+        aOptions: aOptions,
+        lOptions: lOptions,
+        webOptions: webOptions,
+        mOptions: mOptions,
+        wOptions: wOptions,
+      );
+    }
   }
 
   @override
@@ -92,15 +141,19 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
     MacOsOptions? mOptions,
     WindowsOptions? wOptions,
   }) async {
-    await secureStore.delete(
-      key: key,
-      iOptions: iOptions,
-      aOptions: aOptions,
-      lOptions: lOptions,
-      webOptions: webOptions,
-      mOptions: mOptions,
-      wOptions: wOptions,
-    );
+    if (_isDesktop) {
+      return (_store as DesktopPWStore).delete(key: key);
+    } else {
+      return await (_store as FlutterSecureStorage).delete(
+        key: key,
+        iOptions: iOptions,
+        aOptions: aOptions,
+        lOptions: lOptions,
+        webOptions: webOptions,
+        mOptions: mOptions,
+        wOptions: wOptions,
+      );
+    }
   }
 }
 
diff --git a/test/flutter_secure_storage_interface_test.dart b/test/flutter_secure_storage_interface_test.dart
index 90dfdcf13..a421b14c1 100644
--- a/test/flutter_secure_storage_interface_test.dart
+++ b/test/flutter_secure_storage_interface_test.dart
@@ -13,7 +13,7 @@ void main() {
     when(secureStore.write(key: "testKey", value: "some value"))
         .thenAnswer((_) async => null);
 
-    final wrapper = SecureStorageWrapper(secureStore);
+    final wrapper = SecureStorageWrapper(store: secureStore, isDesktop: false);
 
     await expectLater(
         () async => await wrapper.write(key: "testKey", value: "some value"),
@@ -27,7 +27,7 @@ void main() {
     final secureStore = MockFlutterSecureStorage();
     when(secureStore.read(key: "testKey"))
         .thenAnswer((_) async => "some value");
-    final wrapper = SecureStorageWrapper(secureStore);
+    final wrapper = SecureStorageWrapper(store: secureStore, isDesktop: false);
 
     final result = await wrapper.read(key: "testKey");
 
@@ -40,7 +40,7 @@ void main() {
   test("SecureStorageWrapper delete", () async {
     final secureStore = MockFlutterSecureStorage();
     when(secureStore.delete(key: "testKey")).thenAnswer((_) async {});
-    final wrapper = SecureStorageWrapper(secureStore);
+    final wrapper = SecureStorageWrapper(store: secureStore, isDesktop: false);
 
     await expectLater(
         () async => await wrapper.delete(key: "testKey"), returnsNormally);
diff --git a/test/services/coins/bitcoin/bitcoin_wallet_test.dart b/test/services/coins/bitcoin/bitcoin_wallet_test.dart
index 8a240a3dd..e33ffafdf 100644
--- a/test/services/coins/bitcoin/bitcoin_wallet_test.dart
+++ b/test/services/coins/bitcoin/bitcoin_wallet_test.dart
@@ -103,7 +103,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinWallet? testnetWallet;
@@ -194,7 +194,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinWallet? mainnetWallet;
@@ -363,7 +363,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinWallet? btc;
@@ -428,7 +428,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinWallet? btc;
@@ -640,7 +640,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinWallet? btc;
diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart
index 077163809..1c32802c9 100644
--- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart
+++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart
@@ -64,7 +64,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinCashWallet? mainnetWallet;
@@ -203,7 +203,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinCashWallet? mainnetWallet;
@@ -314,7 +314,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinCashWallet? bch;
@@ -383,7 +383,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinCashWallet? bch;
@@ -606,7 +606,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     BitcoinCashWallet? bch;
diff --git a/test/services/coins/dogecoin/dogecoin_wallet_test.dart b/test/services/coins/dogecoin/dogecoin_wallet_test.dart
index 7fcb1cdbd..7c1535ec5 100644
--- a/test/services/coins/dogecoin/dogecoin_wallet_test.dart
+++ b/test/services/coins/dogecoin/dogecoin_wallet_test.dart
@@ -97,7 +97,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     DogecoinWallet? mainnetWallet;
@@ -196,7 +196,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     DogecoinWallet? doge;
@@ -266,7 +266,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     DogecoinWallet? doge;
@@ -489,7 +489,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     DogecoinWallet? doge;
diff --git a/test/services/coins/namecoin/namecoin_wallet_test.dart b/test/services/coins/namecoin/namecoin_wallet_test.dart
index f6bc1b065..46afd06bd 100644
--- a/test/services/coins/namecoin/namecoin_wallet_test.dart
+++ b/test/services/coins/namecoin/namecoin_wallet_test.dart
@@ -103,7 +103,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     NamecoinWallet? mainnetWallet;
@@ -132,7 +132,7 @@ void main() {
           mainnetWallet?.addressType(
               address: "N673DDbjPcrNgJmrhJ1xQXF9LLizQzvjEs"),
           DerivePathType.bip44);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(tracker);
@@ -144,7 +144,7 @@ void main() {
           mainnetWallet?.addressType(
               address: "nc1q6k4x8ye6865z3rc8zkt8gyu52na7njqt6hsk4v"),
           DerivePathType.bip84);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(tracker);
@@ -156,7 +156,7 @@ void main() {
           () => mainnetWallet?.addressType(
               address: "tb1qzzlm6mnc8k54mx6akehl8p9ray8r439va5ndyq"),
           throwsArgumentError);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(tracker);
@@ -168,7 +168,7 @@ void main() {
           () => mainnetWallet?.addressType(
               address: "mpMk94ETazqonHutyC1v6ajshgtP8oiFKU"),
           throwsArgumentError);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(tracker);
@@ -180,7 +180,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     NamecoinWallet? nmc;
@@ -208,7 +208,7 @@ void main() {
       when(client?.ping()).thenAnswer((_) async => false);
       final bool? result = await nmc?.testNetworkConnection();
       expect(result, false);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verify(client?.ping()).called(1);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
@@ -219,7 +219,7 @@ void main() {
       when(client?.ping()).thenThrow(Exception);
       final bool? result = await nmc?.testNetworkConnection();
       expect(result, false);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verify(client?.ping()).called(1);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
@@ -230,7 +230,7 @@ void main() {
       when(client?.ping()).thenAnswer((_) async => true);
       final bool? result = await nmc?.testNetworkConnection();
       expect(result, true);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verify(client?.ping()).called(1);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
@@ -245,7 +245,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     NamecoinWallet? nmc;
@@ -271,7 +271,7 @@ void main() {
 
     test("get networkType main", () async {
       expect(Coin.namecoin, Coin.namecoin);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -289,7 +289,7 @@ void main() {
         secureStore: secureStore,
       );
       expect(Coin.namecoin, Coin.namecoin);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -297,7 +297,7 @@ void main() {
 
     test("get cryptoCurrency", () async {
       expect(Coin.namecoin, Coin.namecoin);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -305,7 +305,7 @@ void main() {
 
     test("get coinName", () async {
       expect(Coin.namecoin, Coin.namecoin);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -313,7 +313,7 @@ void main() {
 
     test("get coinTicker", () async {
       expect(Coin.namecoin, Coin.namecoin);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -323,7 +323,7 @@ void main() {
       expect(Coin.namecoin, Coin.namecoin);
       nmc?.walletName = "new name";
       expect(nmc?.walletName, "new name");
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -338,7 +338,7 @@ void main() {
       expect(nmc?.estimateTxFee(vSize: 356, feeRatePerKB: 1699), 712);
       expect(nmc?.estimateTxFee(vSize: 356, feeRatePerKB: 2000), 712);
       expect(nmc?.estimateTxFee(vSize: 356, feeRatePerKB: 12345), 4628);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -372,7 +372,7 @@ void main() {
       verify(client?.estimateFee(blocks: 1)).called(1);
       verify(client?.estimateFee(blocks: 5)).called(1);
       verify(client?.estimateFee(blocks: 20)).called(1);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -409,7 +409,7 @@ void main() {
       verify(client?.estimateFee(blocks: 1)).called(1);
       verify(client?.estimateFee(blocks: 5)).called(1);
       verify(client?.estimateFee(blocks: 20)).called(1);
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -440,7 +440,7 @@ void main() {
     //   verify(client?.estimateFee(blocks: 1)).called(1);
     //   verify(client?.estimateFee(blocks: 5)).called(1);
     //   verify(client?.estimateFee(blocks: 20)).called(1);
-    //   expect(secureStore?.interactions, 0);
+    //   expect(secureStore.interactions, 0);
     //   verifyNoMoreInteractions(client);
     //   verifyNoMoreInteractions(cachedClient);
     //   verifyNoMoreInteractions(tracker);
@@ -457,7 +457,7 @@ void main() {
     MockElectrumX? client;
     MockCachedElectrumX? cachedClient;
     MockPriceAPI? priceAPI;
-    FakeSecureStorage? secureStore;
+    late FakeSecureStorage secureStore;
     MockTransactionNotificationTracker? tracker;
 
     NamecoinWallet? nmc;
@@ -504,7 +504,7 @@ void main() {
     // test("initializeWallet no network", () async {
     //   when(client?.ping()).thenAnswer((_) async => false);
     //   expect(await nmc?.initializeWallet(), false);
-    //   expect(secureStore?.interactions, 0);
+    //   expect(secureStore.interactions, 0);
     //   verify(client?.ping()).called(1);
     //   verifyNoMoreInteractions(client);
     //   verifyNoMoreInteractions(cachedClient);
@@ -515,7 +515,7 @@ void main() {
     //   when(client?.ping()).thenThrow(Exception("Network connection failed"));
     //   final wallets = await Hive.openBox(testWalletId);
     //   expect(await nmc?.initializeExisting(), false);
-    //   expect(secureStore?.interactions, 0);
+    //   expect(secureStore.interactions, 0);
     //   verify(client?.ping()).called(1);
     //   verifyNoMoreInteractions(client);
     //   verifyNoMoreInteractions(cachedClient);
@@ -539,7 +539,7 @@ void main() {
 
       expectLater(() => nmc?.initializeExisting(), throwsA(isA<Exception>()))
           .then((_) {
-        expect(secureStore?.interactions, 0);
+        expect(secureStore.interactions, 0);
         // verify(client?.ping()).called(1);
         // verify(client?.getServerFeatures()).called(1);
         verifyNoMoreInteractions(client);
@@ -560,13 +560,13 @@ void main() {
             "hash_function": "sha256",
             "services": []
           });
-      await secureStore?.write(
+      await secureStore.write(
           key: "${testWalletId}_mnemonic", value: "some mnemonic");
 
       final wallets = await Hive.openBox(testWalletId);
       expectLater(() => nmc?.initializeExisting(), throwsA(isA<Exception>()))
           .then((_) {
-        expect(secureStore?.interactions, 1);
+        expect(secureStore.interactions, 1);
         // verify(client?.ping()).called(1);
         // verify(client?.getServerFeatures()).called(1);
         verifyNoMoreInteractions(client);
@@ -603,7 +603,7 @@ void main() {
 
       verify(client?.getServerFeatures()).called(1);
 
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -623,7 +623,7 @@ void main() {
             "services": []
           });
 
-      await secureStore?.write(
+      await secureStore.write(
           key: "${testWalletId}_mnemonic", value: "some mnemonic words");
 
       bool hasThrown = false;
@@ -640,7 +640,7 @@ void main() {
 
       verify(client?.getServerFeatures()).called(1);
 
-      expect(secureStore?.interactions, 2);
+      expect(secureStore.interactions, 2);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -691,10 +691,10 @@ void main() {
       verify(client?.getBatchHistory(args: historyBatchArgs4)).called(1);
       verify(client?.getBatchHistory(args: historyBatchArgs5)).called(1);
 
-      expect(secureStore?.interactions, 20);
-      expect(secureStore?.writes, 7);
-      expect(secureStore?.reads, 13);
-      expect(secureStore?.deletes, 0);
+      expect(secureStore.interactions, 20);
+      expect(secureStore.writes, 7);
+      expect(secureStore.reads, 13);
+      expect(secureStore.deletes, 0);
 
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
@@ -814,10 +814,10 @@ void main() {
             true);
       }
 
-      expect(secureStore?.interactions, 14);
-      expect(secureStore?.writes, 7);
-      expect(secureStore?.reads, 7);
-      expect(secureStore?.deletes, 0);
+      expect(secureStore.interactions, 14);
+      expect(secureStore.writes, 7);
+      expect(secureStore.reads, 7);
+      expect(secureStore.deletes, 0);
 
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
@@ -911,17 +911,17 @@ void main() {
       final preChangeIndexP2SH = await wallet.get('changeIndexP2SH');
       final preChangeIndexP2WPKH = await wallet.get('changeIndexP2WPKH');
       final preUtxoData = await wallet.get('latest_utxo_model');
-      final preReceiveDerivationsStringP2PKH = await secureStore?.read(
+      final preReceiveDerivationsStringP2PKH = await secureStore.read(
           key: "${testWalletId}_receiveDerivationsP2PKH");
-      final preChangeDerivationsStringP2PKH = await secureStore?.read(
-          key: "${testWalletId}_changeDerivationsP2PKH");
-      final preReceiveDerivationsStringP2SH = await secureStore?.read(
-          key: "${testWalletId}_receiveDerivationsP2SH");
+      final preChangeDerivationsStringP2PKH =
+          await secureStore.read(key: "${testWalletId}_changeDerivationsP2PKH");
+      final preReceiveDerivationsStringP2SH =
+          await secureStore.read(key: "${testWalletId}_receiveDerivationsP2SH");
       final preChangeDerivationsStringP2SH =
-          await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
-      final preReceiveDerivationsStringP2WPKH = await secureStore?.read(
+          await secureStore.read(key: "${testWalletId}_changeDerivationsP2SH");
+      final preReceiveDerivationsStringP2WPKH = await secureStore.read(
           key: "${testWalletId}_receiveDerivationsP2WPKH");
-      final preChangeDerivationsStringP2WPKH = await secureStore?.read(
+      final preChangeDerivationsStringP2WPKH = await secureStore.read(
           key: "${testWalletId}_changeDerivationsP2WPKH");
 
       // destroy the data that the rescan will fix
@@ -943,17 +943,17 @@ void main() {
       await wallet.put('changeIndexP2PKH', 123);
       await wallet.put('changeIndexP2SH', 123);
       await wallet.put('changeIndexP2WPKH', 123);
-      await secureStore?.write(
+      await secureStore.write(
           key: "${testWalletId}_receiveDerivationsP2PKH", value: "{}");
-      await secureStore?.write(
+      await secureStore.write(
           key: "${testWalletId}_changeDerivationsP2PKH", value: "{}");
-      await secureStore?.write(
+      await secureStore.write(
           key: "${testWalletId}_receiveDerivationsP2SH", value: "{}");
-      await secureStore?.write(
+      await secureStore.write(
           key: "${testWalletId}_changeDerivationsP2SH", value: "{}");
-      await secureStore?.write(
+      await secureStore.write(
           key: "${testWalletId}_receiveDerivationsP2WPKH", value: "{}");
-      await secureStore?.write(
+      await secureStore.write(
           key: "${testWalletId}_changeDerivationsP2WPKH", value: "{}");
 
       bool hasThrown = false;
@@ -980,17 +980,17 @@ void main() {
       final changeIndexP2SH = await wallet.get('changeIndexP2SH');
       final changeIndexP2WPKH = await wallet.get('changeIndexP2WPKH');
       final utxoData = await wallet.get('latest_utxo_model');
-      final receiveDerivationsStringP2PKH = await secureStore?.read(
+      final receiveDerivationsStringP2PKH = await secureStore.read(
           key: "${testWalletId}_receiveDerivationsP2PKH");
-      final changeDerivationsStringP2PKH = await secureStore?.read(
-          key: "${testWalletId}_changeDerivationsP2PKH");
-      final receiveDerivationsStringP2SH = await secureStore?.read(
-          key: "${testWalletId}_receiveDerivationsP2SH");
+      final changeDerivationsStringP2PKH =
+          await secureStore.read(key: "${testWalletId}_changeDerivationsP2PKH");
+      final receiveDerivationsStringP2SH =
+          await secureStore.read(key: "${testWalletId}_receiveDerivationsP2SH");
       final changeDerivationsStringP2SH =
-          await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
-      final receiveDerivationsStringP2WPKH = await secureStore?.read(
+          await secureStore.read(key: "${testWalletId}_changeDerivationsP2SH");
+      final receiveDerivationsStringP2WPKH = await secureStore.read(
           key: "${testWalletId}_receiveDerivationsP2WPKH");
-      final changeDerivationsStringP2WPKH = await secureStore?.read(
+      final changeDerivationsStringP2WPKH = await secureStore.read(
           key: "${testWalletId}_changeDerivationsP2WPKH");
 
       expect(preReceivingAddressesP2PKH, receivingAddressesP2PKH);
@@ -1082,9 +1082,9 @@ void main() {
       //
       // argCount.forEach((key, value) => print("arg: $key\ncount: $value"));
 
-      expect(secureStore?.writes, 25);
-      expect(secureStore?.reads, 32);
-      expect(secureStore?.deletes, 6);
+      expect(secureStore.writes, 25);
+      expect(secureStore.reads, 32);
+      expect(secureStore.deletes, 6);
 
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
@@ -1182,17 +1182,17 @@ void main() {
       final preChangeIndexP2SH = await wallet.get('changeIndexP2SH');
       final preChangeIndexP2WPKH = await wallet.get('changeIndexP2WPKH');
       final preUtxoData = await wallet.get('latest_utxo_model');
-      final preReceiveDerivationsStringP2PKH = await secureStore?.read(
+      final preReceiveDerivationsStringP2PKH = await secureStore.read(
           key: "${testWalletId}_receiveDerivationsP2PKH");
-      final preChangeDerivationsStringP2PKH = await secureStore?.read(
-          key: "${testWalletId}_changeDerivationsP2PKH");
-      final preReceiveDerivationsStringP2SH = await secureStore?.read(
-          key: "${testWalletId}_receiveDerivationsP2SH");
+      final preChangeDerivationsStringP2PKH =
+          await secureStore.read(key: "${testWalletId}_changeDerivationsP2PKH");
+      final preReceiveDerivationsStringP2SH =
+          await secureStore.read(key: "${testWalletId}_receiveDerivationsP2SH");
       final preChangeDerivationsStringP2SH =
-          await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
-      final preReceiveDerivationsStringP2WPKH = await secureStore?.read(
+          await secureStore.read(key: "${testWalletId}_changeDerivationsP2SH");
+      final preReceiveDerivationsStringP2WPKH = await secureStore.read(
           key: "${testWalletId}_receiveDerivationsP2WPKH");
-      final preChangeDerivationsStringP2WPKH = await secureStore?.read(
+      final preChangeDerivationsStringP2WPKH = await secureStore.read(
           key: "${testWalletId}_changeDerivationsP2WPKH");
 
       when(client?.getBatchHistory(args: historyBatchArgs0))
@@ -1222,17 +1222,17 @@ void main() {
       final changeIndexP2SH = await wallet.get('changeIndexP2SH');
       final changeIndexP2WPKH = await wallet.get('changeIndexP2WPKH');
       final utxoData = await wallet.get('latest_utxo_model');
-      final receiveDerivationsStringP2PKH = await secureStore?.read(
+      final receiveDerivationsStringP2PKH = await secureStore.read(
           key: "${testWalletId}_receiveDerivationsP2PKH");
-      final changeDerivationsStringP2PKH = await secureStore?.read(
-          key: "${testWalletId}_changeDerivationsP2PKH");
-      final receiveDerivationsStringP2SH = await secureStore?.read(
-          key: "${testWalletId}_receiveDerivationsP2SH");
+      final changeDerivationsStringP2PKH =
+          await secureStore.read(key: "${testWalletId}_changeDerivationsP2PKH");
+      final receiveDerivationsStringP2SH =
+          await secureStore.read(key: "${testWalletId}_receiveDerivationsP2SH");
       final changeDerivationsStringP2SH =
-          await secureStore?.read(key: "${testWalletId}_changeDerivationsP2SH");
-      final receiveDerivationsStringP2WPKH = await secureStore?.read(
+          await secureStore.read(key: "${testWalletId}_changeDerivationsP2SH");
+      final receiveDerivationsStringP2WPKH = await secureStore.read(
           key: "${testWalletId}_receiveDerivationsP2WPKH");
-      final changeDerivationsStringP2WPKH = await secureStore?.read(
+      final changeDerivationsStringP2WPKH = await secureStore.read(
           key: "${testWalletId}_changeDerivationsP2WPKH");
 
       expect(preReceivingAddressesP2PKH, receivingAddressesP2PKH);
@@ -1296,9 +1296,9 @@ void main() {
       verify(cachedClient?.clearSharedTransactionCache(coin: Coin.namecoin))
           .called(1);
 
-      expect(secureStore?.writes, 19);
-      expect(secureStore?.reads, 32);
-      expect(secureStore?.deletes, 12);
+      expect(secureStore.writes, 19);
+      expect(secureStore.reads, 32);
+      expect(secureStore.deletes, 12);
 
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
@@ -1366,21 +1366,21 @@ void main() {
           height: 4000);
 
       // modify addresses to properly mock data to build a tx
-      final rcv44 = await secureStore?.read(
+      final rcv44 = await secureStore.read(
           key: testWalletId + "_receiveDerivationsP2PKH");
-      await secureStore?.write(
+      await secureStore.write(
           key: testWalletId + "_receiveDerivationsP2PKH",
           value: rcv44?.replaceFirst("1RMSPixoLPuaXuhR2v4HsUMcRjLncKDaw",
               "16FuTPaeRSPVxxCnwQmdyx2PQWxX6HWzhQ"));
-      final rcv49 = await secureStore?.read(
-          key: testWalletId + "_receiveDerivationsP2SH");
-      await secureStore?.write(
+      final rcv49 =
+          await secureStore.read(key: testWalletId + "_receiveDerivationsP2SH");
+      await secureStore.write(
           key: testWalletId + "_receiveDerivationsP2SH",
           value: rcv49?.replaceFirst("3AV74rKfibWmvX34F99yEvUcG4LLQ9jZZk",
               "36NvZTcMsMowbt78wPzJaHHWaNiyR73Y4g"));
-      final rcv84 = await secureStore?.read(
+      final rcv84 = await secureStore.read(
           key: testWalletId + "_receiveDerivationsP2WPKH");
-      await secureStore?.write(
+      await secureStore.write(
           key: testWalletId + "_receiveDerivationsP2WPKH",
           value: rcv84?.replaceFirst(
               "bc1qggtj4ka8jsaj44hhd5mpamx7mp34m2d3w7k0m0",
@@ -1436,10 +1436,10 @@ void main() {
             true);
       }
 
-      expect(secureStore?.interactions, 20);
-      expect(secureStore?.writes, 10);
-      expect(secureStore?.reads, 10);
-      expect(secureStore?.deletes, 0);
+      expect(secureStore.interactions, 20);
+      expect(secureStore.writes, 10);
+      expect(secureStore.reads, 10);
+      expect(secureStore.deletes, 0);
 
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
@@ -1456,7 +1456,7 @@ void main() {
 
       expect(didThrow, true);
 
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -1472,7 +1472,7 @@ void main() {
 
       expect(didThrow, true);
 
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -1492,7 +1492,7 @@ void main() {
               rawTx: "a string", requestID: anyNamed("requestID")))
           .called(1);
 
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -1513,7 +1513,7 @@ void main() {
               rawTx: "a string", requestID: anyNamed("requestID")))
           .called(1);
 
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(priceAPI);
@@ -1538,7 +1538,7 @@ void main() {
               rawTx: "a string", requestID: anyNamed("requestID")))
           .called(1);
 
-      expect(secureStore?.interactions, 0);
+      expect(secureStore.interactions, 0);
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
       verifyNoMoreInteractions(tracker);
@@ -1658,10 +1658,10 @@ void main() {
             true);
       }
 
-      expect(secureStore?.interactions, 14);
-      expect(secureStore?.writes, 7);
-      expect(secureStore?.reads, 7);
-      expect(secureStore?.deletes, 0);
+      expect(secureStore.interactions, 14);
+      expect(secureStore.writes, 7);
+      expect(secureStore.reads, 7);
+      expect(secureStore.deletes, 0);
 
       verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
@@ -1726,10 +1726,10 @@ void main() {
         verify(client?.getBatchHistory(args: map)).called(1);
       }
 
-      expect(secureStore?.interactions, 14);
-      expect(secureStore?.writes, 7);
-      expect(secureStore?.reads, 7);
-      expect(secureStore?.deletes, 0);
+      expect(secureStore.interactions, 14);
+      expect(secureStore.writes, 7);
+      expect(secureStore.reads, 7);
+      expect(secureStore.deletes, 0);
 
       // verifyNoMoreInteractions(client);
       verifyNoMoreInteractions(cachedClient);
diff --git a/test/services/node_service_test.dart b/test/services/node_service_test.dart
index 81f8ca6ed..cea30be2d 100644
--- a/test/services/node_service_test.dart
+++ b/test/services/node_service_test.dart
@@ -141,7 +141,8 @@ void main() {
     );
 
     setUp(() async {
-      await NodeService().updateDefaults();
+      await NodeService(secureStorageInterface: FakeSecureStorage())
+          .updateDefaults();
     });
 
     test("setPrimaryNodeFor and getPrimaryNodeFor", () async {
diff --git a/test/services/wallets_service_test.dart b/test/services/wallets_service_test.dart
index 1cb712759..9cd808b7c 100644
--- a/test/services/wallets_service_test.dart
+++ b/test/services/wallets_service_test.dart
@@ -32,7 +32,7 @@ void main() {
   });
 
   test("get walletNames", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect((await service.walletNames).toString(),
         '{wallet_id: WalletInfo: {"name":"My Firo Wallet","id":"wallet_id","coin":"bitcoin"}, wallet_id2: WalletInfo: {"name":"wallet2","id":"wallet_id2","coin":"bitcoin"}}');
   });
@@ -40,13 +40,13 @@ void main() {
   test("get null wallet names", () async {
     final wallets = await Hive.openBox<dynamic>('wallets');
     await wallets.put('names', null);
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(await service.walletNames, <String, WalletInfo>{});
     expect((await service.walletNames).toString(), '{}');
   });
 
   test("rename wallet to same name", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(
         await service.renameWallet(
             from: "My Firo Wallet",
@@ -58,7 +58,7 @@ void main() {
   });
 
   test("rename wallet to new name", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(
         await service.renameWallet(
             from: "My Firo Wallet",
@@ -71,7 +71,7 @@ void main() {
   });
 
   test("attempt rename wallet to another existing name", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(
         await service.renameWallet(
             from: "My Firo Wallet",
@@ -83,7 +83,7 @@ void main() {
   });
 
   test("add new wallet name", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(
         await service.addNewWallet(
             name: "wallet3", coin: Coin.bitcoin, shouldNotifyListeners: false),
@@ -92,7 +92,7 @@ void main() {
   });
 
   test("add duplicate wallet name fails", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(
         await service.addNewWallet(
             name: "wallet2", coin: Coin.bitcoin, shouldNotifyListeners: false),
@@ -103,27 +103,27 @@ void main() {
   test("check for duplicates when null names", () async {
     final wallets = await Hive.openBox<dynamic>('wallets');
     await wallets.put('names', null);
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(await service.checkForDuplicate("anything"), false);
   });
 
   test("check for duplicates when some names with no matches", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(await service.checkForDuplicate("anything"), false);
   });
 
   test("check for duplicates when some names with a match", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(await service.checkForDuplicate("wallet2"), true);
   });
 
   test("get existing wallet id", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expect(await service.getWalletId("wallet2"), "wallet_id2");
   });
 
   test("get non existent wallet id", () async {
-    final service = WalletsService();
+    final service = WalletsService(secureStorageInterface: FakeSecureStorage());
     expectLater(await service.getWalletId("wallet 99"), null);
   });
 
diff --git a/test/services/wallets_service_test.mocks.dart b/test/services/wallets_service_test.mocks.dart
index c553bbf93..0950a2cbf 100644
--- a/test/services/wallets_service_test.mocks.dart
+++ b/test/services/wallets_service_test.mocks.dart
@@ -42,7 +42,7 @@ class MockSecureStorageWrapper extends _i1.Mock
   }
 
   @override
-  _i2.FlutterSecureStorage get secureStore => (super.noSuchMethod(
+  _i2.FlutterSecureStorage get _secureStore => (super.noSuchMethod(
         Invocation.getter(#secureStore),
         returnValue: _FakeFlutterSecureStorage_0(
           this,

From 3ee0e97628060446550a4809d974d45eee224d5f Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 9 Nov 2022 17:48:43 -0600
Subject: [PATCH 189/426] DesktopSecureStore implementation using Isar as
 backend, renamed FlutterSecureStorageInterface

---
 .../isar/models/encrypted_string_value.dart   |  18 +
 .../isar/models/encrypted_string_value.g.dart | 748 ++++++++++++++++++
 lib/models/node_model.dart                    |   3 +-
 lib/pages/pinpad_views/create_pin_view.dart   |   2 +-
 lib/pages/pinpad_views/lock_screen_view.dart  |   2 +-
 .../add_edit_node_view.dart                   |   2 +-
 .../manage_nodes_views/node_details_view.dart |   2 +-
 .../change_pin_view/change_pin_view.dart      |   2 +-
 .../create_auto_backup_view.dart              |   2 +-
 .../edit_auto_backup_view.dart                |   2 +-
 .../helpers/restore_create_backup.dart        |  12 +-
 .../create_password/create_password_view.dart |   5 +
 .../desktop_login_view.dart                   |  39 +-
 .../global/secure_store_provider.dart         |   4 +-
 lib/services/auto_swb_service.dart            |   2 +-
 .../coins/bitcoin/bitcoin_wallet.dart         |   4 +-
 .../coins/bitcoincash/bitcoincash_wallet.dart |   4 +-
 lib/services/coins/coin_service.dart          |   2 +-
 .../coins/dogecoin/dogecoin_wallet.dart       |   4 +-
 .../coins/epiccash/epiccash_wallet.dart       |   6 +-
 lib/services/coins/firo/firo_wallet.dart      |   4 +-
 .../coins/litecoin/litecoin_wallet.dart       |   4 +-
 lib/services/coins/monero/monero_wallet.dart  |   4 +-
 .../coins/namecoin/namecoin_wallet.dart       |   4 +-
 .../coins/wownero/wownero_wallet.dart         |   4 +-
 lib/services/node_service.dart                |   2 +-
 lib/services/wallets_service.dart             |   4 +-
 lib/utilities/db_version_migration.dart       |   2 +-
 lib/utilities/desktop_password_service.dart   |   2 +-
 .../flutter_secure_storage_interface.dart     |  59 +-
 test/cached_electrumx_test.mocks.dart         |   8 +
 test/electrumx_test.mocks.dart                |   8 +
 .../pages/send_view/send_view_test.mocks.dart |  45 +-
 .../exchange/exchange_view_test.mocks.dart    |   8 +
 .../lockscreen_view_screen_test.mocks.dart    |   7 +-
 .../create_pin_view_screen_test.mocks.dart    |   7 +-
 ...restore_wallet_view_screen_test.mocks.dart |   6 +-
 ...dd_custom_node_view_screen_test.mocks.dart |   7 +-
 .../node_details_view_screen_test.mocks.dart  |   7 +-
 ...twork_settings_view_screen_test.mocks.dart |   7 +-
 ...allet_settings_view_screen_test.mocks.dart |  16 +
 .../bitcoin/bitcoin_wallet_test.mocks.dart    |  16 +
 .../bitcoincash_wallet_test.mocks.dart        |  16 +
 .../dogecoin/dogecoin_wallet_test.mocks.dart  |  16 +
 .../coins/firo/firo_wallet_test.mocks.dart    |  16 +
 test/services/coins/manager_test.mocks.dart   |  18 +
 .../namecoin/namecoin_wallet_test.mocks.dart  |  16 +
 test/services/wallets_service_test.mocks.dart |  85 +-
 .../managed_favorite_test.mocks.dart          |  35 +-
 test/widget_tests/node_card_test.mocks.dart   |   7 +-
 .../node_options_sheet_test.mocks.dart        |  14 +-
 .../table_view/table_view_row_test.mocks.dart |  28 +
 .../transaction_card_test.mocks.dart          |  36 +
 test/widget_tests/wallet_card_test.mocks.dart |  18 +
 ...et_info_row_balance_future_test.mocks.dart |  35 +-
 .../wallet_info_row_test.mocks.dart           |  35 +-
 56 files changed, 1306 insertions(+), 165 deletions(-)
 create mode 100644 lib/models/isar/models/encrypted_string_value.dart
 create mode 100644 lib/models/isar/models/encrypted_string_value.g.dart

diff --git a/lib/models/isar/models/encrypted_string_value.dart b/lib/models/isar/models/encrypted_string_value.dart
new file mode 100644
index 000000000..79e9fcaae
--- /dev/null
+++ b/lib/models/isar/models/encrypted_string_value.dart
@@ -0,0 +1,18 @@
+import 'package:isar/isar.dart';
+
+part 'encrypted_string_value.g.dart';
+
+@Collection()
+class EncryptedStringValue {
+  Id id = Isar.autoIncrement;
+
+  @Index(unique: true, replace: true)
+  late String key;
+
+  late String value;
+
+  @override
+  String toString() {
+    return "EncryptedStringValue {\n    key=$key\n    value=$value\n}";
+  }
+}
diff --git a/lib/models/isar/models/encrypted_string_value.g.dart b/lib/models/isar/models/encrypted_string_value.g.dart
new file mode 100644
index 000000000..2315c5d85
--- /dev/null
+++ b/lib/models/isar/models/encrypted_string_value.g.dart
@@ -0,0 +1,748 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'encrypted_string_value.dart';
+
+// **************************************************************************
+// IsarCollectionGenerator
+// **************************************************************************
+
+// coverage:ignore-file
+// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, join_return_with_assignment, avoid_js_rounded_ints, prefer_final_locals
+
+extension GetEncryptedStringValueCollection on Isar {
+  IsarCollection<EncryptedStringValue> get encryptedStringValues =>
+      this.collection();
+}
+
+const EncryptedStringValueSchema = CollectionSchema(
+  name: r'EncryptedStringValue',
+  id: 4826543019451092626,
+  properties: {
+    r'key': PropertySchema(
+      id: 0,
+      name: r'key',
+      type: IsarType.string,
+    ),
+    r'value': PropertySchema(
+      id: 1,
+      name: r'value',
+      type: IsarType.string,
+    )
+  },
+  estimateSize: _encryptedStringValueEstimateSize,
+  serializeNative: _encryptedStringValueSerializeNative,
+  deserializeNative: _encryptedStringValueDeserializeNative,
+  deserializePropNative: _encryptedStringValueDeserializePropNative,
+  serializeWeb: _encryptedStringValueSerializeWeb,
+  deserializeWeb: _encryptedStringValueDeserializeWeb,
+  deserializePropWeb: _encryptedStringValueDeserializePropWeb,
+  idName: r'id',
+  indexes: {
+    r'key': IndexSchema(
+      id: -4906094122524121629,
+      name: r'key',
+      unique: true,
+      replace: true,
+      properties: [
+        IndexPropertySchema(
+          name: r'key',
+          type: IndexType.hash,
+          caseSensitive: true,
+        )
+      ],
+    )
+  },
+  links: {},
+  embeddedSchemas: {},
+  getId: _encryptedStringValueGetId,
+  getLinks: _encryptedStringValueGetLinks,
+  attach: _encryptedStringValueAttach,
+  version: 5,
+);
+
+int _encryptedStringValueEstimateSize(
+  EncryptedStringValue object,
+  List<int> offsets,
+  Map<Type, List<int>> allOffsets,
+) {
+  var bytesCount = offsets.last;
+  bytesCount += 3 + object.key.length * 3;
+  bytesCount += 3 + object.value.length * 3;
+  return bytesCount;
+}
+
+int _encryptedStringValueSerializeNative(
+  EncryptedStringValue object,
+  IsarBinaryWriter writer,
+  List<int> offsets,
+  Map<Type, List<int>> allOffsets,
+) {
+  writer.writeString(offsets[0], object.key);
+  writer.writeString(offsets[1], object.value);
+  return writer.usedBytes;
+}
+
+EncryptedStringValue _encryptedStringValueDeserializeNative(
+  int id,
+  IsarBinaryReader reader,
+  List<int> offsets,
+  Map<Type, List<int>> allOffsets,
+) {
+  final object = EncryptedStringValue();
+  object.id = id;
+  object.key = reader.readString(offsets[0]);
+  object.value = reader.readString(offsets[1]);
+  return object;
+}
+
+P _encryptedStringValueDeserializePropNative<P>(
+  Id id,
+  IsarBinaryReader reader,
+  int propertyId,
+  int offset,
+  Map<Type, List<int>> allOffsets,
+) {
+  switch (propertyId) {
+    case 0:
+      return (reader.readString(offset)) as P;
+    case 1:
+      return (reader.readString(offset)) as P;
+    default:
+      throw IsarError('Unknown property with id $propertyId');
+  }
+}
+
+Object _encryptedStringValueSerializeWeb(
+    IsarCollection<EncryptedStringValue> collection,
+    EncryptedStringValue object) {
+  /*final jsObj = IsarNative.newJsObject();*/ throw UnimplementedError();
+}
+
+EncryptedStringValue _encryptedStringValueDeserializeWeb(
+    IsarCollection<EncryptedStringValue> collection, Object jsObj) {
+  /*final object = EncryptedStringValue();object.id = IsarNative.jsObjectGet(jsObj, r'id') ?? (double.negativeInfinity as int);object.key = IsarNative.jsObjectGet(jsObj, r'key') ?? '';object.value = IsarNative.jsObjectGet(jsObj, r'value') ?? '';*/
+  //return object;
+  throw UnimplementedError();
+}
+
+P _encryptedStringValueDeserializePropWeb<P>(
+    Object jsObj, String propertyName) {
+  switch (propertyName) {
+    default:
+      throw IsarError('Illegal propertyName');
+  }
+}
+
+int? _encryptedStringValueGetId(EncryptedStringValue object) {
+  if (object.id == Isar.autoIncrement) {
+    return null;
+  } else {
+    return object.id;
+  }
+}
+
+List<IsarLinkBase<dynamic>> _encryptedStringValueGetLinks(
+    EncryptedStringValue object) {
+  return [];
+}
+
+void _encryptedStringValueAttach(
+    IsarCollection<dynamic> col, Id id, EncryptedStringValue object) {
+  object.id = id;
+}
+
+extension EncryptedStringValueByIndex on IsarCollection<EncryptedStringValue> {
+  Future<EncryptedStringValue?> getByKey(String key) {
+    return getByIndex(r'key', [key]);
+  }
+
+  EncryptedStringValue? getByKeySync(String key) {
+    return getByIndexSync(r'key', [key]);
+  }
+
+  Future<bool> deleteByKey(String key) {
+    return deleteByIndex(r'key', [key]);
+  }
+
+  bool deleteByKeySync(String key) {
+    return deleteByIndexSync(r'key', [key]);
+  }
+
+  Future<List<EncryptedStringValue?>> getAllByKey(List<String> keyValues) {
+    final values = keyValues.map((e) => [e]).toList();
+    return getAllByIndex(r'key', values);
+  }
+
+  List<EncryptedStringValue?> getAllByKeySync(List<String> keyValues) {
+    final values = keyValues.map((e) => [e]).toList();
+    return getAllByIndexSync(r'key', values);
+  }
+
+  Future<int> deleteAllByKey(List<String> keyValues) {
+    final values = keyValues.map((e) => [e]).toList();
+    return deleteAllByIndex(r'key', values);
+  }
+
+  int deleteAllByKeySync(List<String> keyValues) {
+    final values = keyValues.map((e) => [e]).toList();
+    return deleteAllByIndexSync(r'key', values);
+  }
+
+  Future<int> putByKey(EncryptedStringValue object) {
+    return putByIndex(r'key', object);
+  }
+
+  int putByKeySync(EncryptedStringValue object, {bool saveLinks = true}) {
+    return putByIndexSync(r'key', object, saveLinks: saveLinks);
+  }
+
+  Future<List<int>> putAllByKey(List<EncryptedStringValue> objects) {
+    return putAllByIndex(r'key', objects);
+  }
+
+  List<int> putAllByKeySync(List<EncryptedStringValue> objects,
+      {bool saveLinks = true}) {
+    return putAllByIndexSync(r'key', objects, saveLinks: saveLinks);
+  }
+}
+
+extension EncryptedStringValueQueryWhereSort
+    on QueryBuilder<EncryptedStringValue, EncryptedStringValue, QWhere> {
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterWhere>
+      anyId() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addWhereClause(const IdWhereClause.any());
+    });
+  }
+}
+
+extension EncryptedStringValueQueryWhere
+    on QueryBuilder<EncryptedStringValue, EncryptedStringValue, QWhereClause> {
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterWhereClause>
+      idEqualTo(int id) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addWhereClause(IdWhereClause.between(
+        lower: id,
+        upper: id,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterWhereClause>
+      idNotEqualTo(int id) {
+    return QueryBuilder.apply(this, (query) {
+      if (query.whereSort == Sort.asc) {
+        return query
+            .addWhereClause(
+              IdWhereClause.lessThan(upper: id, includeUpper: false),
+            )
+            .addWhereClause(
+              IdWhereClause.greaterThan(lower: id, includeLower: false),
+            );
+      } else {
+        return query
+            .addWhereClause(
+              IdWhereClause.greaterThan(lower: id, includeLower: false),
+            )
+            .addWhereClause(
+              IdWhereClause.lessThan(upper: id, includeUpper: false),
+            );
+      }
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterWhereClause>
+      idGreaterThan(int id, {bool include = false}) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addWhereClause(
+        IdWhereClause.greaterThan(lower: id, includeLower: include),
+      );
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterWhereClause>
+      idLessThan(int id, {bool include = false}) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addWhereClause(
+        IdWhereClause.lessThan(upper: id, includeUpper: include),
+      );
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterWhereClause>
+      idBetween(
+    int lowerId,
+    int upperId, {
+    bool includeLower = true,
+    bool includeUpper = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addWhereClause(IdWhereClause.between(
+        lower: lowerId,
+        includeLower: includeLower,
+        upper: upperId,
+        includeUpper: includeUpper,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterWhereClause>
+      keyEqualTo(String key) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addWhereClause(IndexWhereClause.equalTo(
+        indexName: r'key',
+        value: [key],
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterWhereClause>
+      keyNotEqualTo(String key) {
+    return QueryBuilder.apply(this, (query) {
+      if (query.whereSort == Sort.asc) {
+        return query
+            .addWhereClause(IndexWhereClause.between(
+              indexName: r'key',
+              lower: [],
+              upper: [key],
+              includeUpper: false,
+            ))
+            .addWhereClause(IndexWhereClause.between(
+              indexName: r'key',
+              lower: [key],
+              includeLower: false,
+              upper: [],
+            ));
+      } else {
+        return query
+            .addWhereClause(IndexWhereClause.between(
+              indexName: r'key',
+              lower: [key],
+              includeLower: false,
+              upper: [],
+            ))
+            .addWhereClause(IndexWhereClause.between(
+              indexName: r'key',
+              lower: [],
+              upper: [key],
+              includeUpper: false,
+            ));
+      }
+    });
+  }
+}
+
+extension EncryptedStringValueQueryFilter on QueryBuilder<EncryptedStringValue,
+    EncryptedStringValue, QFilterCondition> {
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> idEqualTo(int value) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.equalTo(
+        property: r'id',
+        value: value,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> idGreaterThan(
+    int value, {
+    bool include = false,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.greaterThan(
+        include: include,
+        property: r'id',
+        value: value,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> idLessThan(
+    int value, {
+    bool include = false,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.lessThan(
+        include: include,
+        property: r'id',
+        value: value,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> idBetween(
+    int lower,
+    int upper, {
+    bool includeLower = true,
+    bool includeUpper = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.between(
+        property: r'id',
+        lower: lower,
+        includeLower: includeLower,
+        upper: upper,
+        includeUpper: includeUpper,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> keyEqualTo(
+    String value, {
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.equalTo(
+        property: r'key',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> keyGreaterThan(
+    String value, {
+    bool include = false,
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.greaterThan(
+        include: include,
+        property: r'key',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> keyLessThan(
+    String value, {
+    bool include = false,
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.lessThan(
+        include: include,
+        property: r'key',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> keyBetween(
+    String lower,
+    String upper, {
+    bool includeLower = true,
+    bool includeUpper = true,
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.between(
+        property: r'key',
+        lower: lower,
+        includeLower: includeLower,
+        upper: upper,
+        includeUpper: includeUpper,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> keyStartsWith(
+    String value, {
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.startsWith(
+        property: r'key',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> keyEndsWith(
+    String value, {
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.endsWith(
+        property: r'key',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+          QAfterFilterCondition>
+      keyContains(String value, {bool caseSensitive = true}) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.contains(
+        property: r'key',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+          QAfterFilterCondition>
+      keyMatches(String pattern, {bool caseSensitive = true}) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.matches(
+        property: r'key',
+        wildcard: pattern,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> valueEqualTo(
+    String value, {
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.equalTo(
+        property: r'value',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> valueGreaterThan(
+    String value, {
+    bool include = false,
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.greaterThan(
+        include: include,
+        property: r'value',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> valueLessThan(
+    String value, {
+    bool include = false,
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.lessThan(
+        include: include,
+        property: r'value',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> valueBetween(
+    String lower,
+    String upper, {
+    bool includeLower = true,
+    bool includeUpper = true,
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.between(
+        property: r'value',
+        lower: lower,
+        includeLower: includeLower,
+        upper: upper,
+        includeUpper: includeUpper,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> valueStartsWith(
+    String value, {
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.startsWith(
+        property: r'value',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+      QAfterFilterCondition> valueEndsWith(
+    String value, {
+    bool caseSensitive = true,
+  }) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.endsWith(
+        property: r'value',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+          QAfterFilterCondition>
+      valueContains(String value, {bool caseSensitive = true}) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.contains(
+        property: r'value',
+        value: value,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue,
+          QAfterFilterCondition>
+      valueMatches(String pattern, {bool caseSensitive = true}) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addFilterCondition(FilterCondition.matches(
+        property: r'value',
+        wildcard: pattern,
+        caseSensitive: caseSensitive,
+      ));
+    });
+  }
+}
+
+extension EncryptedStringValueQueryObject on QueryBuilder<EncryptedStringValue,
+    EncryptedStringValue, QFilterCondition> {}
+
+extension EncryptedStringValueQueryLinks on QueryBuilder<EncryptedStringValue,
+    EncryptedStringValue, QFilterCondition> {}
+
+extension EncryptedStringValueQuerySortBy
+    on QueryBuilder<EncryptedStringValue, EncryptedStringValue, QSortBy> {
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      sortByKey() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'key', Sort.asc);
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      sortByKeyDesc() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'key', Sort.desc);
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      sortByValue() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'value', Sort.asc);
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      sortByValueDesc() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'value', Sort.desc);
+    });
+  }
+}
+
+extension EncryptedStringValueQuerySortThenBy
+    on QueryBuilder<EncryptedStringValue, EncryptedStringValue, QSortThenBy> {
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      thenById() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'id', Sort.asc);
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      thenByIdDesc() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'id', Sort.desc);
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      thenByKey() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'key', Sort.asc);
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      thenByKeyDesc() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'key', Sort.desc);
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      thenByValue() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'value', Sort.asc);
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QAfterSortBy>
+      thenByValueDesc() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addSortBy(r'value', Sort.desc);
+    });
+  }
+}
+
+extension EncryptedStringValueQueryWhereDistinct
+    on QueryBuilder<EncryptedStringValue, EncryptedStringValue, QDistinct> {
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QDistinct>
+      distinctByKey({bool caseSensitive = true}) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addDistinctBy(r'key', caseSensitive: caseSensitive);
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, EncryptedStringValue, QDistinct>
+      distinctByValue({bool caseSensitive = true}) {
+    return QueryBuilder.apply(this, (query) {
+      return query.addDistinctBy(r'value', caseSensitive: caseSensitive);
+    });
+  }
+}
+
+extension EncryptedStringValueQueryProperty on QueryBuilder<
+    EncryptedStringValue, EncryptedStringValue, QQueryProperty> {
+  QueryBuilder<EncryptedStringValue, int, QQueryOperations> idProperty() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addPropertyName(r'id');
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, String, QQueryOperations> keyProperty() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addPropertyName(r'key');
+    });
+  }
+
+  QueryBuilder<EncryptedStringValue, String, QQueryOperations> valueProperty() {
+    return QueryBuilder.apply(this, (query) {
+      return query.addPropertyName(r'value');
+    });
+  }
+}
diff --git a/lib/models/node_model.dart b/lib/models/node_model.dart
index 342f8b2ef..2628c5dd9 100644
--- a/lib/models/node_model.dart
+++ b/lib/models/node_model.dart
@@ -65,8 +65,7 @@ class NodeModel {
   }
 
   /// convenience getter to retrieve login password
-  Future<String?> getPassword(
-      FlutterSecureStorageInterface secureStorage) async {
+  Future<String?> getPassword(SecureStorageInterface secureStorage) async {
     return await secureStorage.read(key: "${id}_nodePW");
   }
 
diff --git a/lib/pages/pinpad_views/create_pin_view.dart b/lib/pages/pinpad_views/create_pin_view.dart
index 5ea8bc363..766f10fa5 100644
--- a/lib/pages/pinpad_views/create_pin_view.dart
+++ b/lib/pages/pinpad_views/create_pin_view.dart
@@ -54,7 +54,7 @@ class _CreatePinViewState extends ConsumerState<CreatePinView> {
   final TextEditingController _pinPutController2 = TextEditingController();
   final FocusNode _pinPutFocusNode2 = FocusNode();
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
   late Biometrics biometrics;
 
   @override
diff --git a/lib/pages/pinpad_views/lock_screen_view.dart b/lib/pages/pinpad_views/lock_screen_view.dart
index 137f3d55d..60d317e21 100644
--- a/lib/pages/pinpad_views/lock_screen_view.dart
+++ b/lib/pages/pinpad_views/lock_screen_view.dart
@@ -158,7 +158,7 @@ class _LockscreenViewState extends ConsumerState<LockscreenView> {
   final _pinTextController = TextEditingController();
   final FocusNode _pinFocusNode = FocusNode();
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
   late Biometrics biometrics;
 
   Scaffold get _body => Scaffold(
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 39ab493f0..890953caf 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -634,7 +634,7 @@ class NodeForm extends ConsumerStatefulWidget {
   }) : super(key: key);
 
   final NodeModel? node;
-  final FlutterSecureStorageInterface secureStore;
+  final SecureStorageInterface secureStore;
   final bool readOnly;
   final Coin coin;
   final void Function(bool canSave, bool canTestConnection)? onChanged;
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index 6d9641b7d..a80a64147 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -45,7 +45,7 @@ class NodeDetailsView extends ConsumerStatefulWidget {
 }
 
 class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
-  late final FlutterSecureStorageInterface secureStore;
+  late final SecureStorageInterface secureStore;
   late final Coin coin;
   late final String nodeId;
   late final String popRouteName;
diff --git a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart
index 46c2fd9cf..c88da0521 100644
--- a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart
+++ b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart
@@ -45,7 +45,7 @@ class _ChangePinViewState extends ConsumerState<ChangePinView> {
   final TextEditingController _pinPutController2 = TextEditingController();
   final FocusNode _pinPutFocusNode2 = FocusNode();
 
-  late final FlutterSecureStorageInterface _secureStore;
+  late final SecureStorageInterface _secureStore;
 
   @override
   void initState() {
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
index 1082acc99..334d50e35 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
@@ -41,7 +41,7 @@ class CreateAutoBackupView extends ConsumerStatefulWidget {
 }
 
 class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
-  late final FlutterSecureStorageInterface secureStore;
+  late final SecureStorageInterface secureStore;
 
   late final TextEditingController fileLocationController;
   late final TextEditingController passwordController;
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
index d5ba21634..0be718549 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
@@ -40,7 +40,7 @@ class EditAutoBackupView extends ConsumerStatefulWidget {
 }
 
 class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
-  late final FlutterSecureStorageInterface secureStore;
+  late final SecureStorageInterface secureStore;
 
   late final TextEditingController fileLocationController;
   late final TextEditingController passwordController;
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart
index 9b755c95a..3d599f717 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart
@@ -90,7 +90,7 @@ abstract class SWB {
 
   static bool _checkShouldCancel(
     PreRestoreState? revertToState,
-    FlutterSecureStorageInterface secureStorageInterface,
+    SecureStorageInterface secureStorageInterface,
   ) {
     if (_shouldCancelRestore) {
       if (revertToState != null) {
@@ -193,7 +193,7 @@ abstract class SWB {
 
   /// [secureStorage] parameter exposed for testing purposes
   static Future<Map<String, dynamic>> createStackWalletJSON({
-    required FlutterSecureStorageInterface secureStorage,
+    required SecureStorageInterface secureStorage,
   }) async {
     Logging.instance
         .log("Starting createStackWalletJSON...", level: LogLevel.Info);
@@ -448,7 +448,7 @@ abstract class SWB {
     Map<String, dynamic> validJSON,
     StackRestoringUIState? uiState,
     Map<String, String> oldToNewWalletIdMap,
-    FlutterSecureStorageInterface secureStorageInterface,
+    SecureStorageInterface secureStorageInterface,
   ) async {
     Map<String, dynamic> prefs = validJSON["prefs"] as Map<String, dynamic>;
     List<dynamic>? addressBookEntries =
@@ -548,7 +548,7 @@ abstract class SWB {
   static Future<bool?> restoreStackWalletJSON(
     String jsonBackup,
     StackRestoringUIState? uiState,
-    FlutterSecureStorageInterface secureStorageInterface,
+    SecureStorageInterface secureStorageInterface,
   ) async {
     if (!Platform.isLinux) await Wakelock.enable();
 
@@ -769,7 +769,7 @@ abstract class SWB {
 
   static Future<void> _revert(
     PreRestoreState revertToState,
-    FlutterSecureStorageInterface secureStorageInterface,
+    SecureStorageInterface secureStorageInterface,
   ) async {
     Map<String, dynamic> prefs =
         revertToState.validJSON["prefs"] as Map<String, dynamic>;
@@ -1042,7 +1042,7 @@ abstract class SWB {
   static Future<void> _restoreNodes(
     List<dynamic>? nodes,
     List<dynamic>? primaryNodes,
-    FlutterSecureStorageInterface secureStorageInterface,
+    SecureStorageInterface secureStorageInterface,
   ) async {
     NodeService nodeService = NodeService(
       secureStorageInterface: secureStorageInterface,
diff --git a/lib/pages_desktop_specific/create_password/create_password_view.dart b/lib/pages_desktop_specific/create_password/create_password_view.dart
index 1e137500d..d5ce42679 100644
--- a/lib/pages_desktop_specific/create_password/create_password_view.dart
+++ b/lib/pages_desktop_specific/create_password/create_password_view.dart
@@ -72,6 +72,11 @@ class _CreatePasswordViewState extends ConsumerState<CreatePasswordView> {
     }
 
     try {
+      if (await ref.read(storageCryptoHandlerProvider).hasPassword()) {
+        throw Exception(
+            "Tried creating a new password and attempted to overwrite an existing entry!");
+      }
+
       await ref.read(storageCryptoHandlerProvider).initFromNew(passphrase);
     } catch (e) {
       unawaited(showFloatingFlushBar(
diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index fe05d719f..0a47c2a96 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -1,9 +1,15 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages_desktop_specific/forgot_password_desktop_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
+import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/flush_bar_type.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';
@@ -11,7 +17,7 @@ import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 
-class DesktopLoginView extends StatefulWidget {
+class DesktopLoginView extends ConsumerStatefulWidget {
   const DesktopLoginView({
     Key? key,
     this.startupWalletId,
@@ -22,10 +28,10 @@ class DesktopLoginView extends StatefulWidget {
   final String? startupWalletId;
 
   @override
-  State<DesktopLoginView> createState() => _DesktopLoginViewState();
+  ConsumerState<DesktopLoginView> createState() => _DesktopLoginViewState();
 }
 
-class _DesktopLoginViewState extends State<DesktopLoginView> {
+class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
   late final TextEditingController passwordController;
 
   late final FocusNode passwordFocusNode;
@@ -153,13 +159,28 @@ class _DesktopLoginViewState extends State<DesktopLoginView> {
                 PrimaryButton(
                   label: "Continue",
                   enabled: _continueEnabled,
-                  onPressed: () {
-                    // todo auth
+                  onPressed: () async {
+                    try {
+                      await ref
+                          .read(storageCryptoHandlerProvider)
+                          .initFromExisting(passwordController.text);
 
-                    Navigator.of(context).pushNamedAndRemoveUntil(
-                      DesktopHomeView.routeName,
-                      (route) => false,
-                    );
+                      // if no errors passphrase is correct
+                      if (mounted) {
+                        unawaited(
+                          Navigator.of(context).pushNamedAndRemoveUntil(
+                            DesktopHomeView.routeName,
+                            (route) => false,
+                          ),
+                        );
+                      }
+                    } catch (e) {
+                      await showFloatingFlushBar(
+                        type: FlushBarType.warning,
+                        message: e.toString(),
+                        context: context,
+                      );
+                    }
                   },
                 ),
                 const SizedBox(
diff --git a/lib/providers/global/secure_store_provider.dart b/lib/providers/global/secure_store_provider.dart
index 299ea0f5c..32304d0f2 100644
--- a/lib/providers/global/secure_store_provider.dart
+++ b/lib/providers/global/secure_store_provider.dart
@@ -4,11 +4,11 @@ import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.da
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/util.dart';
 
-final secureStoreProvider = Provider<FlutterSecureStorageInterface>((ref) {
+final secureStoreProvider = Provider<SecureStorageInterface>((ref) {
   if (Util.isDesktop) {
     final handler = ref.read(storageCryptoHandlerProvider).handler;
     return SecureStorageWrapper(
-        store: DesktopPWStore(handler), isDesktop: true);
+        store: DesktopSecureStore(handler), isDesktop: true);
   } else {
     return const SecureStorageWrapper(
       store: FlutterSecureStorage(),
diff --git a/lib/services/auto_swb_service.dart b/lib/services/auto_swb_service.dart
index 06ec7a2fb..f7efc994e 100644
--- a/lib/services/auto_swb_service.dart
+++ b/lib/services/auto_swb_service.dart
@@ -24,7 +24,7 @@ class AutoSWBService extends ChangeNotifier {
   bool _isActiveTimer = false;
   bool get isActivePeriodicTimer => _isActiveTimer;
 
-  final FlutterSecureStorageInterface secureStorageInterface;
+  final SecureStorageInterface secureStorageInterface;
 
   AutoSWBService({required this.secureStorageInterface});
 
diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart
index e3c2f13fd..dfd5ea180 100644
--- a/lib/services/coins/bitcoin/bitcoin_wallet.dart
+++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart
@@ -1356,7 +1356,7 @@ class BitcoinWallet extends CoinServiceAPI {
 
   CachedElectrumX get cachedElectrumXClient => _cachedElectrumXClient;
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
 
   late PriceAPI _priceAPI;
 
@@ -1368,7 +1368,7 @@ class BitcoinWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    required FlutterSecureStorageInterface secureStore,
+    required SecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index 063c74315..429af898e 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -1261,7 +1261,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
 
   CachedElectrumX get cachedElectrumXClient => _cachedElectrumXClient;
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
 
   late PriceAPI _priceAPI;
 
@@ -1273,7 +1273,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    required FlutterSecureStorageInterface secureStore,
+    required SecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
diff --git a/lib/services/coins/coin_service.dart b/lib/services/coins/coin_service.dart
index e63ff86e1..16015ea0c 100644
--- a/lib/services/coins/coin_service.dart
+++ b/lib/services/coins/coin_service.dart
@@ -25,7 +25,7 @@ abstract class CoinServiceAPI {
     Coin coin,
     String walletId,
     String walletName,
-    FlutterSecureStorageInterface secureStorageInterface,
+    SecureStorageInterface secureStorageInterface,
     NodeModel node,
     TransactionNotificationTracker tracker,
     Prefs prefs,
diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart
index c3100b0f7..41778a9e0 100644
--- a/lib/services/coins/dogecoin/dogecoin_wallet.dart
+++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart
@@ -1124,7 +1124,7 @@ class DogecoinWallet extends CoinServiceAPI {
 
   CachedElectrumX get cachedElectrumXClient => _cachedElectrumXClient;
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
 
   late PriceAPI _priceAPI;
 
@@ -1136,7 +1136,7 @@ class DogecoinWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    required FlutterSecureStorageInterface secureStore,
+    required SecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart
index d7b7f35dd..683e26544 100644
--- a/lib/services/coins/epiccash/epiccash_wallet.dart
+++ b/lib/services/coins/epiccash/epiccash_wallet.dart
@@ -250,7 +250,7 @@ Future<String> _deleteWalletWrapper(String wallet) async {
 
 Future<String> deleteEpicWallet({
   required String walletId,
-  required FlutterSecureStorageInterface secureStore,
+  required SecureStorageInterface secureStore,
 }) async {
   String? config = await secureStore.read(key: '${walletId}_config');
   if (Platform.isIOS) {
@@ -517,7 +517,7 @@ class EpicCashWallet extends CoinServiceAPI {
       required String walletName,
       required Coin coin,
       PriceAPI? priceAPI,
-      required FlutterSecureStorageInterface secureStore}) {
+      required SecureStorageInterface secureStore}) {
     _walletId = walletId;
     _walletName = walletName;
     _coin = coin;
@@ -658,7 +658,7 @@ class EpicCashWallet extends CoinServiceAPI {
   @override
   Coin get coin => _coin;
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
 
   late PriceAPI _priceAPI;
 
diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart
index d0f99ef1d..4bd863f2c 100644
--- a/lib/services/coins/firo/firo_wallet.dart
+++ b/lib/services/coins/firo/firo_wallet.dart
@@ -1305,7 +1305,7 @@ class FiroWallet extends CoinServiceAPI {
   late CachedElectrumX _cachedElectrumXClient;
   CachedElectrumX get cachedElectrumXClient => _cachedElectrumXClient;
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
 
   late PriceAPI _priceAPI;
 
@@ -1320,7 +1320,7 @@ class FiroWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    required FlutterSecureStorageInterface secureStore,
+    required SecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart
index 30d6ede39..db7c9d1fa 100644
--- a/lib/services/coins/litecoin/litecoin_wallet.dart
+++ b/lib/services/coins/litecoin/litecoin_wallet.dart
@@ -1358,7 +1358,7 @@ class LitecoinWallet extends CoinServiceAPI {
 
   CachedElectrumX get cachedElectrumXClient => _cachedElectrumXClient;
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
 
   late PriceAPI _priceAPI;
 
@@ -1370,7 +1370,7 @@ class LitecoinWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    required FlutterSecureStorageInterface secureStore,
+    required SecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index 569498a15..69e0bd38d 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -67,7 +67,7 @@ class MoneroWallet extends CoinServiceAPI {
   Timer? moneroAutosaveTimer;
   late Coin _coin;
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
 
   late PriceAPI _priceAPI;
 
@@ -82,7 +82,7 @@ class MoneroWallet extends CoinServiceAPI {
       required String walletName,
       required Coin coin,
       PriceAPI? priceAPI,
-      required FlutterSecureStorageInterface secureStore}) {
+      required SecureStorageInterface secureStore}) {
     _walletId = walletId;
     _walletName = walletName;
     _coin = coin;
diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart
index 1ebf87233..c8c84fb27 100644
--- a/lib/services/coins/namecoin/namecoin_wallet.dart
+++ b/lib/services/coins/namecoin/namecoin_wallet.dart
@@ -1349,7 +1349,7 @@ class NamecoinWallet extends CoinServiceAPI {
 
   CachedElectrumX get cachedElectrumXClient => _cachedElectrumXClient;
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
 
   late PriceAPI _priceAPI;
 
@@ -1361,7 +1361,7 @@ class NamecoinWallet extends CoinServiceAPI {
     required CachedElectrumX cachedClient,
     required TransactionNotificationTracker tracker,
     PriceAPI? priceAPI,
-    required FlutterSecureStorageInterface secureStore,
+    required SecureStorageInterface secureStore,
   }) {
     txTracker = tracker;
     _walletId = walletId;
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 7a219158a..7476afbef 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -68,7 +68,7 @@ class WowneroWallet extends CoinServiceAPI {
   Timer? wowneroAutosaveTimer;
   late Coin _coin;
 
-  late FlutterSecureStorageInterface _secureStore;
+  late SecureStorageInterface _secureStore;
 
   late PriceAPI _priceAPI;
 
@@ -83,7 +83,7 @@ class WowneroWallet extends CoinServiceAPI {
       required String walletName,
       required Coin coin,
       PriceAPI? priceAPI,
-      required FlutterSecureStorageInterface secureStore}) {
+      required SecureStorageInterface secureStore}) {
     _walletId = walletId;
     _walletName = walletName;
     _coin = coin;
diff --git a/lib/services/node_service.dart b/lib/services/node_service.dart
index 0dd706781..aa8d5a6d9 100644
--- a/lib/services/node_service.dart
+++ b/lib/services/node_service.dart
@@ -12,7 +12,7 @@ import 'package:stackwallet/utilities/logger.dart';
 const kStackCommunityNodesEndpoint = "https://extras.stackwallet.com";
 
 class NodeService extends ChangeNotifier {
-  final FlutterSecureStorageInterface secureStorageInterface;
+  final SecureStorageInterface secureStorageInterface;
 
   /// Exposed [secureStorageInterface] in order to inject mock for tests
   NodeService({
diff --git a/lib/services/wallets_service.dart b/lib/services/wallets_service.dart
index 237df8026..1371b17b6 100644
--- a/lib/services/wallets_service.dart
+++ b/lib/services/wallets_service.dart
@@ -47,14 +47,14 @@ class WalletInfo {
 }
 
 class WalletsService extends ChangeNotifier {
-  late final FlutterSecureStorageInterface _secureStore;
+  late final SecureStorageInterface _secureStore;
 
   Future<Map<String, WalletInfo>>? _walletNames;
   Future<Map<String, WalletInfo>> get walletNames =>
       _walletNames ??= _fetchWalletNames();
 
   WalletsService({
-    required FlutterSecureStorageInterface secureStorageInterface,
+    required SecureStorageInterface secureStorageInterface,
   }) {
     _secureStore = secureStorageInterface;
   }
diff --git a/lib/utilities/db_version_migration.dart b/lib/utilities/db_version_migration.dart
index afb38a487..ae5190fc4 100644
--- a/lib/utilities/db_version_migration.dart
+++ b/lib/utilities/db_version_migration.dart
@@ -16,7 +16,7 @@ import 'package:stackwallet/utilities/prefs.dart';
 class DbVersionMigrator {
   Future<void> migrate(
     int fromVersion, {
-    required FlutterSecureStorageInterface secureStore,
+    required SecureStorageInterface secureStore,
   }) async {
     Logging.instance.log(
       "Running migrate fromVersion $fromVersion",
diff --git a/lib/utilities/desktop_password_service.dart b/lib/utilities/desktop_password_service.dart
index 7a2047c30..178871e69 100644
--- a/lib/utilities/desktop_password_service.dart
+++ b/lib/utilities/desktop_password_service.dart
@@ -84,7 +84,7 @@ class DPS {
         "${_getMessageFromException(e)}\n$s",
         level: LogLevel.Error,
       );
-      rethrow;
+      throw Exception(_getMessageFromException(e));
     }
   }
 
diff --git a/lib/utilities/flutter_secure_storage_interface.dart b/lib/utilities/flutter_secure_storage_interface.dart
index f36af94f7..852c13f3d 100644
--- a/lib/utilities/flutter_secure_storage_interface.dart
+++ b/lib/utilities/flutter_secure_storage_interface.dart
@@ -1,8 +1,11 @@
+import 'dart:io';
+
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:isar/isar.dart';
 import 'package:stack_wallet_backup/secure_storage.dart';
+import 'package:stackwallet/models/isar/models/encrypted_string_value.dart';
 
-abstract class FlutterSecureStorageInterface {
+abstract class SecureStorageInterface {
   Future<void> write({
     required String key,
     required String? value,
@@ -35,38 +38,66 @@ abstract class FlutterSecureStorageInterface {
   });
 }
 
-class DesktopPWStore {
+class DesktopSecureStore {
   final StorageCryptoHandler handler;
   late final Isar isar;
 
-  DesktopPWStore(this.handler);
+  DesktopSecureStore(this.handler);
 
-  Future<void> init() async {}
+  Future<void> init() async {
+    Directory? appDirectory;
+    if (Platform.isLinux) {
+      appDirectory = Directory("${Platform.environment['HOME']}/.stackwallet");
+      await appDirectory.create();
+    }
+    isar = await Isar.open(
+      [EncryptedStringValueSchema],
+      directory: appDirectory!.path,
+      inspector: false,
+    );
+  }
 
   Future<String?> read({
     required String key,
   }) async {
-    // final String encryptedString =
+    final value =
+        await isar.encryptedStringValues.filter().keyEqualTo(key).findFirst();
 
-    return "";
+    // value does not exist;
+    if (value == null) {
+      return null;
+    }
+
+    return await handler.decryptValue(key, value.value);
   }
 
   Future<void> write({
     required String key,
     required String? value,
   }) async {
-    return;
+    if (value == null) {
+      // here we assume that a value is to be deleted
+      await isar.encryptedStringValues.deleteByKey(key);
+    } else {
+      // otherwise created encrypted object value
+      final object = EncryptedStringValue();
+      object.key = key;
+      object.value = await handler.encryptValue(key, value);
+
+      // store object value
+      await isar.encryptedStringValues.put(object);
+    }
   }
 
   Future<void> delete({
     required String key,
   }) async {
-    return;
+    await isar.encryptedStringValues.deleteByKey(key);
   }
 }
 
 /// all *Options params ignored on desktop
-class SecureStorageWrapper implements FlutterSecureStorageInterface {
+class SecureStorageWrapper implements SecureStorageInterface {
   final dynamic _store;
   final bool _isDesktop;
 
@@ -74,7 +105,7 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
     required dynamic store,
     required bool isDesktop,
   })  : assert(isDesktop
-            ? store is DesktopPWStore
+            ? store is DesktopSecureStore
             : store is FlutterSecureStorage),
         _store = store,
         _isDesktop = isDesktop;
@@ -90,7 +121,7 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
     WindowsOptions? wOptions,
   }) async {
     if (_isDesktop) {
-      return await (_store as DesktopPWStore).read(key: key);
+      return await (_store as DesktopSecureStore).read(key: key);
     } else {
       return await (_store as FlutterSecureStorage).read(
         key: key,
@@ -116,7 +147,7 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
     WindowsOptions? wOptions,
   }) async {
     if (_isDesktop) {
-      return await (_store as DesktopPWStore).write(key: key, value: value);
+      return await (_store as DesktopSecureStore).write(key: key, value: value);
     } else {
       return await (_store as FlutterSecureStorage).write(
         key: key,
@@ -142,7 +173,7 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
     WindowsOptions? wOptions,
   }) async {
     if (_isDesktop) {
-      return (_store as DesktopPWStore).delete(key: key);
+      return (_store as DesktopSecureStore).delete(key: key);
     } else {
       return await (_store as FlutterSecureStorage).delete(
         key: key,
@@ -158,7 +189,7 @@ class SecureStorageWrapper implements FlutterSecureStorageInterface {
 }
 
 // Mock class for testing purposes
-class FakeSecureStorage implements FlutterSecureStorageInterface {
+class FakeSecureStorage implements SecureStorageInterface {
   final Map<String, String?> _store = {};
   int _interactions = 0;
   int get interactions => _interactions;
diff --git a/test/cached_electrumx_test.mocks.dart b/test/cached_electrumx_test.mocks.dart
index 1e3e70a0a..a45cdd402 100644
--- a/test/cached_electrumx_test.mocks.dart
+++ b/test/cached_electrumx_test.mocks.dart
@@ -678,6 +678,14 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs {
         returnValueForMissingStub: _i4.Future<void>.value(),
       ) as _i4.Future<void>);
   @override
+  _i4.Future<bool> isExternalCallsSet() => (super.noSuchMethod(
+        Invocation.method(
+          #isExternalCallsSet,
+          [],
+        ),
+        returnValue: _i4.Future<bool>.value(false),
+      ) as _i4.Future<bool>);
+  @override
   void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(
           #addListener,
diff --git a/test/electrumx_test.mocks.dart b/test/electrumx_test.mocks.dart
index fa48ea2fd..9f29ae1e5 100644
--- a/test/electrumx_test.mocks.dart
+++ b/test/electrumx_test.mocks.dart
@@ -399,6 +399,14 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs {
         returnValueForMissingStub: _i3.Future<void>.value(),
       ) as _i3.Future<void>);
   @override
+  _i3.Future<bool> isExternalCallsSet() => (super.noSuchMethod(
+        Invocation.method(
+          #isExternalCallsSet,
+          [],
+        ),
+        returnValue: _i3.Future<bool>.value(false),
+      ) as _i3.Future<bool>);
+  @override
   void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(
           #addListener,
diff --git a/test/pages/send_view/send_view_test.mocks.dart b/test/pages/send_view/send_view_test.mocks.dart
index a07377309..d63dafb04 100644
--- a/test/pages/send_view/send_view_test.mocks.dart
+++ b/test/pages/send_view/send_view_test.mocks.dart
@@ -1,5 +1,5 @@
 // Mocks generated by Mockito 5.3.2 from annotations
-// in stackwallet/test/pages/send_view_test.dart.
+// in stackwallet/test/pages/send_view/send_view_test.dart.
 // Do not manually edit this file.
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
@@ -86,7 +86,7 @@ class _FakeManager_3 extends _i1.SmartFake implements _i6.Manager {
 }
 
 class _FakeFlutterSecureStorageInterface_4 extends _i1.SmartFake
-    implements _i7.FlutterSecureStorageInterface {
+    implements _i7.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_4(
     Object parent,
     Invocation parentInvocation,
@@ -621,14 +621,13 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService {
   }
 
   @override
-  _i7.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i7.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_4(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i7.FlutterSecureStorageInterface);
+      ) as _i7.SecureStorageInterface);
   @override
   List<_i19.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
@@ -890,6 +889,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet {
         returnValueForMissingStub: null,
       );
   @override
+  set cachedTxData(_i9.TransactionData? _cachedTxData) => super.noSuchMethod(
+        Invocation.setter(
+          #cachedTxData,
+          _cachedTxData,
+        ),
+        returnValueForMissingStub: null,
+      );
+  @override
   bool get isActive => (super.noSuchMethod(
         Invocation.getter(#isActive),
         returnValue: false,
@@ -1272,6 +1279,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i20.BitcoinWallet {
         returnValueForMissingStub: _i16.Future<void>.value(),
       ) as _i16.Future<void>);
   @override
+  _i16.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>);
+  @override
   bool validateAddress(String? address) => (super.noSuchMethod(
         Invocation.method(
           #validateAddress,
@@ -1875,6 +1892,14 @@ class MockPrefs extends _i1.Mock implements _i17.Prefs {
         returnValueForMissingStub: _i16.Future<void>.value(),
       ) as _i16.Future<void>);
   @override
+  _i16.Future<bool> isExternalCallsSet() => (super.noSuchMethod(
+        Invocation.method(
+          #isExternalCallsSet,
+          [],
+        ),
+        returnValue: _i16.Future<bool>.value(false),
+      ) as _i16.Future<bool>);
+  @override
   void addListener(_i18.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(
           #addListener,
@@ -2623,4 +2648,14 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI {
         ),
         returnValue: _i16.Future<bool>.value(false),
       ) as _i16.Future<bool>);
+  @override
+  _i16.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>);
 }
diff --git a/test/screen_tests/exchange/exchange_view_test.mocks.dart b/test/screen_tests/exchange/exchange_view_test.mocks.dart
index 1d93023d5..0da12dbd0 100644
--- a/test/screen_tests/exchange/exchange_view_test.mocks.dart
+++ b/test/screen_tests/exchange/exchange_view_test.mocks.dart
@@ -350,6 +350,14 @@ class MockPrefs extends _i1.Mock implements _i3.Prefs {
         returnValueForMissingStub: _i7.Future<void>.value(),
       ) as _i7.Future<void>);
   @override
+  _i7.Future<bool> isExternalCallsSet() => (super.noSuchMethod(
+        Invocation.method(
+          #isExternalCallsSet,
+          [],
+        ),
+        returnValue: _i7.Future<bool>.value(false),
+      ) as _i7.Future<bool>);
+  @override
   void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(
           #addListener,
diff --git a/test/screen_tests/lockscreen_view_screen_test.mocks.dart b/test/screen_tests/lockscreen_view_screen_test.mocks.dart
index 1cd697e05..a33c4ef28 100644
--- a/test/screen_tests/lockscreen_view_screen_test.mocks.dart
+++ b/test/screen_tests/lockscreen_view_screen_test.mocks.dart
@@ -30,7 +30,7 @@ import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'
 // ignore_for_file: subtype_of_sealed_class
 
 class _FakeFlutterSecureStorageInterface_0 extends _i1.SmartFake
-    implements _i2.FlutterSecureStorageInterface {
+    implements _i2.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_0(
     Object parent,
     Invocation parentInvocation,
@@ -309,14 +309,13 @@ class MockWalletsService extends _i1.Mock implements _i6.WalletsService {
 /// See the documentation for Mockito's code generation for more information.
 class MockNodeService extends _i1.Mock implements _i10.NodeService {
   @override
-  _i2.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i2.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_0(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i2.FlutterSecureStorageInterface);
+      ) as _i2.SecureStorageInterface);
   @override
   List<_i11.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
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 62d3c597d..3aed1dcb8 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
@@ -30,7 +30,7 @@ import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'
 // ignore_for_file: subtype_of_sealed_class
 
 class _FakeFlutterSecureStorageInterface_0 extends _i1.SmartFake
-    implements _i2.FlutterSecureStorageInterface {
+    implements _i2.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_0(
     Object parent,
     Invocation parentInvocation,
@@ -309,14 +309,13 @@ class MockWalletsService extends _i1.Mock implements _i6.WalletsService {
 /// See the documentation for Mockito's code generation for more information.
 class MockNodeService extends _i1.Mock implements _i10.NodeService {
   @override
-  _i2.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i2.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_0(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i2.FlutterSecureStorageInterface);
+      ) as _i2.SecureStorageInterface);
   @override
   List<_i11.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
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 cf891e829..cd4986e13 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
@@ -84,7 +84,7 @@ class _FakeTransactionData_4 extends _i1.SmartFake
 }
 
 class _FakeFlutterSecureStorageInterface_5 extends _i1.SmartFake
-    implements _i6.FlutterSecureStorageInterface {
+    implements _i6.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_5(
     Object parent,
     Invocation parentInvocation,
@@ -744,14 +744,14 @@ class MockManager extends _i1.Mock implements _i12.Manager {
 /// See the documentation for Mockito's code generation for more information.
 class MockNodeService extends _i1.Mock implements _i13.NodeService {
   @override
-  _i6.FlutterSecureStorageInterface get secureStorageInterface =>
+  _i6.SecureStorageInterface get secureStorageInterface =>
       (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_5(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i6.FlutterSecureStorageInterface);
+      ) as _i6.SecureStorageInterface);
   @override
   List<_i14.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
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 d80b97852..3ac5afcc7 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
@@ -29,7 +29,7 @@ import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'
 // ignore_for_file: subtype_of_sealed_class
 
 class _FakeFlutterSecureStorageInterface_0 extends _i1.SmartFake
-    implements _i2.FlutterSecureStorageInterface {
+    implements _i2.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_0(
     Object parent,
     Invocation parentInvocation,
@@ -86,14 +86,13 @@ class _FakeTransactionData_4 extends _i1.SmartFake
 /// See the documentation for Mockito's code generation for more information.
 class MockNodeService extends _i1.Mock implements _i6.NodeService {
   @override
-  _i2.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i2.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_0(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i2.FlutterSecureStorageInterface);
+      ) as _i2.SecureStorageInterface);
   @override
   List<_i7.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
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 89820ee97..0f6447a9e 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
@@ -29,7 +29,7 @@ import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'
 // ignore_for_file: subtype_of_sealed_class
 
 class _FakeFlutterSecureStorageInterface_0 extends _i1.SmartFake
-    implements _i2.FlutterSecureStorageInterface {
+    implements _i2.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_0(
     Object parent,
     Invocation parentInvocation,
@@ -86,14 +86,13 @@ class _FakeTransactionData_4 extends _i1.SmartFake
 /// See the documentation for Mockito's code generation for more information.
 class MockNodeService extends _i1.Mock implements _i6.NodeService {
   @override
-  _i2.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i2.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_0(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i2.FlutterSecureStorageInterface);
+      ) as _i2.SecureStorageInterface);
   @override
   List<_i7.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_view_screen_test.mocks.dart
index 7e8ff731e..707da7345 100644
--- a/test/screen_tests/settings_view/settings_subviews/network_settings_view_screen_test.mocks.dart
+++ b/test/screen_tests/settings_view/settings_subviews/network_settings_view_screen_test.mocks.dart
@@ -25,7 +25,7 @@ import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'
 // ignore_for_file: subtype_of_sealed_class
 
 class _FakeFlutterSecureStorageInterface_0 extends _i1.SmartFake
-    implements _i2.FlutterSecureStorageInterface {
+    implements _i2.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_0(
     Object parent,
     Invocation parentInvocation,
@@ -40,14 +40,13 @@ class _FakeFlutterSecureStorageInterface_0 extends _i1.SmartFake
 /// See the documentation for Mockito's code generation for more information.
 class MockNodeService extends _i1.Mock implements _i3.NodeService {
   @override
-  _i2.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i2.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_0(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i2.FlutterSecureStorageInterface);
+      ) as _i2.SecureStorageInterface);
   @override
   List<_i4.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
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 27ae85597..7eb0853dd 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
@@ -139,6 +139,22 @@ class MockCachedElectrumX extends _i1.Mock implements _i6.CachedElectrumX {
             _i8.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
       ) as _i8.Future<Map<String, dynamic>>);
   @override
+  String base64ToHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
+  String base64ToReverseHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToReverseHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
   _i8.Future<Map<String, dynamic>> getTransaction({
     required String? txHash,
     required _i9.Coin? coin,
diff --git a/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart b/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart
index 99e2e6231..32a6c7195 100644
--- a/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart
+++ b/test/services/coins/bitcoin/bitcoin_wallet_test.mocks.dart
@@ -465,6 +465,22 @@ class MockCachedElectrumX extends _i1.Mock implements _i7.CachedElectrumX {
             _i6.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
       ) as _i6.Future<Map<String, dynamic>>);
   @override
+  String base64ToHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
+  String base64ToReverseHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToReverseHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
   _i6.Future<Map<String, dynamic>> getTransaction({
     required String? txHash,
     required _i8.Coin? coin,
diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart
index a5a2018e7..bfc5f793b 100644
--- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart
+++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.mocks.dart
@@ -465,6 +465,22 @@ class MockCachedElectrumX extends _i1.Mock implements _i7.CachedElectrumX {
             _i6.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
       ) as _i6.Future<Map<String, dynamic>>);
   @override
+  String base64ToHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
+  String base64ToReverseHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToReverseHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
   _i6.Future<Map<String, dynamic>> getTransaction({
     required String? txHash,
     required _i8.Coin? coin,
diff --git a/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart b/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart
index 944e5faea..f7220922e 100644
--- a/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart
+++ b/test/services/coins/dogecoin/dogecoin_wallet_test.mocks.dart
@@ -465,6 +465,22 @@ class MockCachedElectrumX extends _i1.Mock implements _i7.CachedElectrumX {
             _i6.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
       ) as _i6.Future<Map<String, dynamic>>);
   @override
+  String base64ToHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
+  String base64ToReverseHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToReverseHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
   _i6.Future<Map<String, dynamic>> getTransaction({
     required String? txHash,
     required _i8.Coin? coin,
diff --git a/test/services/coins/firo/firo_wallet_test.mocks.dart b/test/services/coins/firo/firo_wallet_test.mocks.dart
index 4fe6af52a..2d32cef48 100644
--- a/test/services/coins/firo/firo_wallet_test.mocks.dart
+++ b/test/services/coins/firo/firo_wallet_test.mocks.dart
@@ -465,6 +465,22 @@ class MockCachedElectrumX extends _i1.Mock implements _i7.CachedElectrumX {
             _i6.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
       ) as _i6.Future<Map<String, dynamic>>);
   @override
+  String base64ToHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
+  String base64ToReverseHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToReverseHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
   _i6.Future<Map<String, dynamic>> getTransaction({
     required String? txHash,
     required _i8.Coin? coin,
diff --git a/test/services/coins/manager_test.mocks.dart b/test/services/coins/manager_test.mocks.dart
index 0c20b752d..9a958702f 100644
--- a/test/services/coins/manager_test.mocks.dart
+++ b/test/services/coins/manager_test.mocks.dart
@@ -117,6 +117,14 @@ class MockFiroWallet extends _i1.Mock implements _i7.FiroWallet {
         returnValueForMissingStub: null,
       );
   @override
+  set cachedTxData(_i4.TransactionData? _cachedTxData) => super.noSuchMethod(
+        Invocation.setter(
+          #cachedTxData,
+          _cachedTxData,
+        ),
+        returnValueForMissingStub: null,
+      );
+  @override
   _i2.TransactionNotificationTracker get txTracker => (super.noSuchMethod(
         Invocation.getter(#txTracker),
         returnValue: _FakeTransactionNotificationTracker_0(
@@ -375,6 +383,16 @@ class MockFiroWallet extends _i1.Mock implements _i7.FiroWallet {
         returnValue: false,
       ) as bool);
   @override
+  _i8.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #updateSentCachedTxData,
+          [txData],
+        ),
+        returnValue: _i8.Future<void>.value(),
+        returnValueForMissingStub: _i8.Future<void>.value(),
+      ) as _i8.Future<void>);
+  @override
   _i8.Future<bool> testNetworkConnection() => (super.noSuchMethod(
         Invocation.method(
           #testNetworkConnection,
diff --git a/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart b/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart
index a81c27fe0..91c3e5bfa 100644
--- a/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart
+++ b/test/services/coins/namecoin/namecoin_wallet_test.mocks.dart
@@ -465,6 +465,22 @@ class MockCachedElectrumX extends _i1.Mock implements _i7.CachedElectrumX {
             _i6.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
       ) as _i6.Future<Map<String, dynamic>>);
   @override
+  String base64ToHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
+  String base64ToReverseHex(String? source) => (super.noSuchMethod(
+        Invocation.method(
+          #base64ToReverseHex,
+          [source],
+        ),
+        returnValue: '',
+      ) as String);
+  @override
   _i6.Future<Map<String, dynamic>> getTransaction({
     required String? txHash,
     required _i8.Coin? coin,
diff --git a/test/services/wallets_service_test.mocks.dart b/test/services/wallets_service_test.mocks.dart
index 0950a2cbf..19d525196 100644
--- a/test/services/wallets_service_test.mocks.dart
+++ b/test/services/wallets_service_test.mocks.dart
@@ -3,12 +3,12 @@
 // Do not manually edit this file.
 
 // ignore_for_file: no_leading_underscores_for_library_prefixes
-import 'dart:async' as _i4;
+import 'dart:async' as _i3;
 
-import 'package:flutter_secure_storage/flutter_secure_storage.dart' as _i2;
+import 'package:flutter_secure_storage/flutter_secure_storage.dart' as _i4;
 import 'package:mockito/mockito.dart' as _i1;
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'
-    as _i3;
+    as _i2;
 
 // ignore_for_file: type=lint
 // ignore_for_file: avoid_redundant_argument_values
@@ -21,43 +21,24 @@ import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'
 // ignore_for_file: camel_case_types
 // ignore_for_file: subtype_of_sealed_class
 
-class _FakeFlutterSecureStorage_0 extends _i1.SmartFake
-    implements _i2.FlutterSecureStorage {
-  _FakeFlutterSecureStorage_0(
-    Object parent,
-    Invocation parentInvocation,
-  ) : super(
-          parent,
-          parentInvocation,
-        );
-}
-
 /// A class which mocks [SecureStorageWrapper].
 ///
 /// See the documentation for Mockito's code generation for more information.
 class MockSecureStorageWrapper extends _i1.Mock
-    implements _i3.SecureStorageWrapper {
+    implements _i2.SecureStorageWrapper {
   MockSecureStorageWrapper() {
     _i1.throwOnMissingStub(this);
   }
 
   @override
-  _i2.FlutterSecureStorage get _secureStore => (super.noSuchMethod(
-        Invocation.getter(#secureStore),
-        returnValue: _FakeFlutterSecureStorage_0(
-          this,
-          Invocation.getter(#secureStore),
-        ),
-      ) as _i2.FlutterSecureStorage);
-  @override
-  _i4.Future<String?> read({
+  _i3.Future<String?> read({
     required String? key,
-    _i2.IOSOptions? iOptions,
-    _i2.AndroidOptions? aOptions,
-    _i2.LinuxOptions? lOptions,
-    _i2.WebOptions? webOptions,
-    _i2.MacOsOptions? mOptions,
-    _i2.WindowsOptions? wOptions,
+    _i4.IOSOptions? iOptions,
+    _i4.AndroidOptions? aOptions,
+    _i4.LinuxOptions? lOptions,
+    _i4.WebOptions? webOptions,
+    _i4.MacOsOptions? mOptions,
+    _i4.WindowsOptions? wOptions,
   }) =>
       (super.noSuchMethod(
         Invocation.method(
@@ -73,18 +54,18 @@ class MockSecureStorageWrapper extends _i1.Mock
             #wOptions: wOptions,
           },
         ),
-        returnValue: _i4.Future<String?>.value(),
-      ) as _i4.Future<String?>);
+        returnValue: _i3.Future<String?>.value(),
+      ) as _i3.Future<String?>);
   @override
-  _i4.Future<void> write({
+  _i3.Future<void> write({
     required String? key,
     required String? value,
-    _i2.IOSOptions? iOptions,
-    _i2.AndroidOptions? aOptions,
-    _i2.LinuxOptions? lOptions,
-    _i2.WebOptions? webOptions,
-    _i2.MacOsOptions? mOptions,
-    _i2.WindowsOptions? wOptions,
+    _i4.IOSOptions? iOptions,
+    _i4.AndroidOptions? aOptions,
+    _i4.LinuxOptions? lOptions,
+    _i4.WebOptions? webOptions,
+    _i4.MacOsOptions? mOptions,
+    _i4.WindowsOptions? wOptions,
   }) =>
       (super.noSuchMethod(
         Invocation.method(
@@ -101,18 +82,18 @@ class MockSecureStorageWrapper extends _i1.Mock
             #wOptions: wOptions,
           },
         ),
-        returnValue: _i4.Future<void>.value(),
-        returnValueForMissingStub: _i4.Future<void>.value(),
-      ) as _i4.Future<void>);
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
   @override
-  _i4.Future<void> delete({
+  _i3.Future<void> delete({
     required String? key,
-    _i2.IOSOptions? iOptions,
-    _i2.AndroidOptions? aOptions,
-    _i2.LinuxOptions? lOptions,
-    _i2.WebOptions? webOptions,
-    _i2.MacOsOptions? mOptions,
-    _i2.WindowsOptions? wOptions,
+    _i4.IOSOptions? iOptions,
+    _i4.AndroidOptions? aOptions,
+    _i4.LinuxOptions? lOptions,
+    _i4.WebOptions? webOptions,
+    _i4.MacOsOptions? mOptions,
+    _i4.WindowsOptions? wOptions,
   }) =>
       (super.noSuchMethod(
         Invocation.method(
@@ -128,7 +109,7 @@ class MockSecureStorageWrapper extends _i1.Mock
             #wOptions: wOptions,
           },
         ),
-        returnValue: _i4.Future<void>.value(),
-        returnValueForMissingStub: _i4.Future<void>.value(),
-      ) as _i4.Future<void>);
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
 }
diff --git a/test/widget_tests/managed_favorite_test.mocks.dart b/test/widget_tests/managed_favorite_test.mocks.dart
index 7d1d864df..50f906c3c 100644
--- a/test/widget_tests/managed_favorite_test.mocks.dart
+++ b/test/widget_tests/managed_favorite_test.mocks.dart
@@ -166,7 +166,7 @@ class _FakeElectrumXNode_11 extends _i1.SmartFake
 }
 
 class _FakeFlutterSecureStorageInterface_12 extends _i1.SmartFake
-    implements _i12.FlutterSecureStorageInterface {
+    implements _i12.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_12(
     Object parent,
     Invocation parentInvocation,
@@ -681,6 +681,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet {
         returnValueForMissingStub: null,
       );
   @override
+  set cachedTxData(_i8.TransactionData? _cachedTxData) => super.noSuchMethod(
+        Invocation.setter(
+          #cachedTxData,
+          _cachedTxData,
+        ),
+        returnValueForMissingStub: null,
+      );
+  @override
   bool get isActive => (super.noSuchMethod(
         Invocation.getter(#isActive),
         returnValue: false,
@@ -1063,6 +1071,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet {
         returnValueForMissingStub: _i16.Future<void>.value(),
       ) as _i16.Future<void>);
   @override
+  _i16.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>);
+  @override
   bool validateAddress(String? address) => (super.noSuchMethod(
         Invocation.method(
           #validateAddress,
@@ -1380,14 +1398,13 @@ class MockLocaleService extends _i1.Mock implements _i20.LocaleService {
 /// See the documentation for Mockito's code generation for more information.
 class MockNodeService extends _i1.Mock implements _i3.NodeService {
   @override
-  _i12.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i12.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_12(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i12.FlutterSecureStorageInterface);
+      ) as _i12.SecureStorageInterface);
   @override
   List<_i21.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
@@ -2291,4 +2308,14 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI {
         ),
         returnValue: _i16.Future<bool>.value(false),
       ) as _i16.Future<bool>);
+  @override
+  _i16.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>);
 }
diff --git a/test/widget_tests/node_card_test.mocks.dart b/test/widget_tests/node_card_test.mocks.dart
index 673182ceb..2bb32b58d 100644
--- a/test/widget_tests/node_card_test.mocks.dart
+++ b/test/widget_tests/node_card_test.mocks.dart
@@ -25,7 +25,7 @@ import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'
 // ignore_for_file: subtype_of_sealed_class
 
 class _FakeFlutterSecureStorageInterface_0 extends _i1.SmartFake
-    implements _i2.FlutterSecureStorageInterface {
+    implements _i2.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_0(
     Object parent,
     Invocation parentInvocation,
@@ -44,14 +44,13 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService {
   }
 
   @override
-  _i2.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i2.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_0(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i2.FlutterSecureStorageInterface);
+      ) as _i2.SecureStorageInterface);
   @override
   List<_i4.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
diff --git a/test/widget_tests/node_options_sheet_test.mocks.dart b/test/widget_tests/node_options_sheet_test.mocks.dart
index 173edf1bf..c9e4e2bb8 100644
--- a/test/widget_tests/node_options_sheet_test.mocks.dart
+++ b/test/widget_tests/node_options_sheet_test.mocks.dart
@@ -77,7 +77,7 @@ class _FakeManager_3 extends _i1.SmartFake implements _i6.Manager {
 }
 
 class _FakeFlutterSecureStorageInterface_4 extends _i1.SmartFake
-    implements _i7.FlutterSecureStorageInterface {
+    implements _i7.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_4(
     Object parent,
     Invocation parentInvocation,
@@ -573,6 +573,14 @@ class MockPrefs extends _i1.Mock implements _i11.Prefs {
         returnValueForMissingStub: _i10.Future<void>.value(),
       ) as _i10.Future<void>);
   @override
+  _i10.Future<bool> isExternalCallsSet() => (super.noSuchMethod(
+        Invocation.method(
+          #isExternalCallsSet,
+          [],
+        ),
+        returnValue: _i10.Future<bool>.value(false),
+      ) as _i10.Future<bool>);
+  @override
   void addListener(_i12.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(
           #addListener,
@@ -615,14 +623,14 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService {
   }
 
   @override
-  _i7.FlutterSecureStorageInterface get secureStorageInterface =>
+  _i7.SecureStorageInterface get secureStorageInterface =>
       (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_4(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i7.FlutterSecureStorageInterface);
+      ) as _i7.SecureStorageInterface);
   @override
   List<_i16.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
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 b4a0e9cc7..5a47436ff 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
@@ -666,6 +666,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet {
         returnValueForMissingStub: null,
       );
   @override
+  set cachedTxData(_i8.TransactionData? _cachedTxData) => super.noSuchMethod(
+        Invocation.setter(
+          #cachedTxData,
+          _cachedTxData,
+        ),
+        returnValueForMissingStub: null,
+      );
+  @override
   bool get isActive => (super.noSuchMethod(
         Invocation.getter(#isActive),
         returnValue: false,
@@ -1048,6 +1056,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i18.BitcoinWallet {
         returnValueForMissingStub: _i15.Future<void>.value(),
       ) as _i15.Future<void>);
   @override
+  _i15.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>);
+  @override
   bool validateAddress(String? address) => (super.noSuchMethod(
         Invocation.method(
           #validateAddress,
@@ -2013,4 +2031,14 @@ class MockCoinServiceAPI extends _i1.Mock implements _i12.CoinServiceAPI {
         ),
         returnValue: _i15.Future<bool>.value(false),
       ) as _i15.Future<bool>);
+  @override
+  _i15.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>);
 }
diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart
index df696801a..f258a402b 100644
--- a/test/widget_tests/transaction_card_test.mocks.dart
+++ b/test/widget_tests/transaction_card_test.mocks.dart
@@ -1108,6 +1108,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI {
         ),
         returnValue: _i16.Future<bool>.value(false),
       ) as _i16.Future<bool>);
+  @override
+  _i16.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>);
 }
 
 /// A class which mocks [FiroWallet].
@@ -1127,6 +1137,14 @@ class MockFiroWallet extends _i1.Mock implements _i19.FiroWallet {
         returnValueForMissingStub: null,
       );
   @override
+  set cachedTxData(_i8.TransactionData? _cachedTxData) => super.noSuchMethod(
+        Invocation.setter(
+          #cachedTxData,
+          _cachedTxData,
+        ),
+        returnValueForMissingStub: null,
+      );
+  @override
   _i10.TransactionNotificationTracker get txTracker => (super.noSuchMethod(
         Invocation.getter(#txTracker),
         returnValue: _FakeTransactionNotificationTracker_8(
@@ -1386,6 +1404,16 @@ class MockFiroWallet extends _i1.Mock implements _i19.FiroWallet {
         returnValue: false,
       ) as bool);
   @override
+  _i16.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>);
+  @override
   _i16.Future<bool> testNetworkConnection() => (super.noSuchMethod(
         Invocation.method(
           #testNetworkConnection,
@@ -2312,6 +2340,14 @@ class MockPrefs extends _i1.Mock implements _i17.Prefs {
         returnValueForMissingStub: _i16.Future<void>.value(),
       ) as _i16.Future<void>);
   @override
+  _i16.Future<bool> isExternalCallsSet() => (super.noSuchMethod(
+        Invocation.method(
+          #isExternalCallsSet,
+          [],
+        ),
+        returnValue: _i16.Future<bool>.value(false),
+      ) as _i16.Future<bool>);
+  @override
   void addListener(_i18.VoidCallback? listener) => super.noSuchMethod(
         Invocation.method(
           #addListener,
diff --git a/test/widget_tests/wallet_card_test.mocks.dart b/test/widget_tests/wallet_card_test.mocks.dart
index ec4f90e22..e323911d4 100644
--- a/test/widget_tests/wallet_card_test.mocks.dart
+++ b/test/widget_tests/wallet_card_test.mocks.dart
@@ -429,6 +429,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i17.BitcoinWallet {
         returnValueForMissingStub: null,
       );
   @override
+  set cachedTxData(_i8.TransactionData? _cachedTxData) => super.noSuchMethod(
+        Invocation.setter(
+          #cachedTxData,
+          _cachedTxData,
+        ),
+        returnValueForMissingStub: null,
+      );
+  @override
   bool get isActive => (super.noSuchMethod(
         Invocation.getter(#isActive),
         returnValue: false,
@@ -811,6 +819,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i17.BitcoinWallet {
         returnValueForMissingStub: _i14.Future<void>.value(),
       ) as _i14.Future<void>);
   @override
+  _i14.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #updateSentCachedTxData,
+          [txData],
+        ),
+        returnValue: _i14.Future<void>.value(),
+        returnValueForMissingStub: _i14.Future<void>.value(),
+      ) as _i14.Future<void>);
+  @override
   bool validateAddress(String? address) => (super.noSuchMethod(
         Invocation.method(
           #validateAddress,
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 e5dc17bc4..a249c997d 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
@@ -165,7 +165,7 @@ class _FakeElectrumXNode_11 extends _i1.SmartFake
 }
 
 class _FakeFlutterSecureStorageInterface_12 extends _i1.SmartFake
-    implements _i12.FlutterSecureStorageInterface {
+    implements _i12.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_12(
     Object parent,
     Invocation parentInvocation,
@@ -680,6 +680,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet {
         returnValueForMissingStub: null,
       );
   @override
+  set cachedTxData(_i8.TransactionData? _cachedTxData) => super.noSuchMethod(
+        Invocation.setter(
+          #cachedTxData,
+          _cachedTxData,
+        ),
+        returnValueForMissingStub: null,
+      );
+  @override
   bool get isActive => (super.noSuchMethod(
         Invocation.getter(#isActive),
         returnValue: false,
@@ -1062,6 +1070,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet {
         returnValueForMissingStub: _i16.Future<void>.value(),
       ) as _i16.Future<void>);
   @override
+  _i16.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>);
+  @override
   bool validateAddress(String? address) => (super.noSuchMethod(
         Invocation.method(
           #validateAddress,
@@ -1317,14 +1335,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet {
 /// See the documentation for Mockito's code generation for more information.
 class MockNodeService extends _i1.Mock implements _i3.NodeService {
   @override
-  _i12.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i12.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_12(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i12.FlutterSecureStorageInterface);
+      ) as _i12.SecureStorageInterface);
   @override
   List<_i20.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
@@ -2228,4 +2245,14 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI {
         ),
         returnValue: _i16.Future<bool>.value(false),
       ) as _i16.Future<bool>);
+  @override
+  _i16.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>);
 }
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 2b7bedb15..820fbd96d 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
@@ -165,7 +165,7 @@ class _FakeElectrumXNode_11 extends _i1.SmartFake
 }
 
 class _FakeFlutterSecureStorageInterface_12 extends _i1.SmartFake
-    implements _i12.FlutterSecureStorageInterface {
+    implements _i12.SecureStorageInterface {
   _FakeFlutterSecureStorageInterface_12(
     Object parent,
     Invocation parentInvocation,
@@ -680,6 +680,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet {
         returnValueForMissingStub: null,
       );
   @override
+  set cachedTxData(_i8.TransactionData? _cachedTxData) => super.noSuchMethod(
+        Invocation.setter(
+          #cachedTxData,
+          _cachedTxData,
+        ),
+        returnValueForMissingStub: null,
+      );
+  @override
   bool get isActive => (super.noSuchMethod(
         Invocation.getter(#isActive),
         returnValue: false,
@@ -1062,6 +1070,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet {
         returnValueForMissingStub: _i16.Future<void>.value(),
       ) as _i16.Future<void>);
   @override
+  _i16.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>);
+  @override
   bool validateAddress(String? address) => (super.noSuchMethod(
         Invocation.method(
           #validateAddress,
@@ -1317,14 +1335,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i19.BitcoinWallet {
 /// See the documentation for Mockito's code generation for more information.
 class MockNodeService extends _i1.Mock implements _i3.NodeService {
   @override
-  _i12.FlutterSecureStorageInterface get secureStorageInterface =>
-      (super.noSuchMethod(
+  _i12.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod(
         Invocation.getter(#secureStorageInterface),
         returnValue: _FakeFlutterSecureStorageInterface_12(
           this,
           Invocation.getter(#secureStorageInterface),
         ),
-      ) as _i12.FlutterSecureStorageInterface);
+      ) as _i12.SecureStorageInterface);
   @override
   List<_i20.NodeModel> get primaryNodes => (super.noSuchMethod(
         Invocation.getter(#primaryNodes),
@@ -2228,4 +2245,14 @@ class MockCoinServiceAPI extends _i1.Mock implements _i13.CoinServiceAPI {
         ),
         returnValue: _i16.Future<bool>.value(false),
       ) as _i16.Future<bool>);
+  @override
+  _i16.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>);
 }

From 8b7e222d416ba2d38a1236a7a6b60b64efd21ffe Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 9 Nov 2022 17:54:12 -0600
Subject: [PATCH 190/426] WIP: proper home directory location for linux

---
 lib/main.dart | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/lib/main.dart b/lib/main.dart
index 7f7c4a44d..c88ae2164 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -85,10 +85,20 @@ void main() async {
   if (Platform.isIOS) {
     appDirectory = (await getLibraryDirectory());
   }
-  if (Platform.isLinux || Logging.isArmLinux) {
+
+  if (Logging.isArmLinux) {
     appDirectory = Directory("${appDirectory.path}/.stackwallet");
     await appDirectory.create();
   }
+
+  if (Platform.isLinux) {
+    appDirectory = Directory("${Platform.environment['HOME']}/.stackwallet");
+
+    if (!appDirectory.existsSync()) {
+      await appDirectory.create();
+    }
+  }
+
   // FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
   if (!(Logging.isArmLinux || Logging.isTestEnv)) {
     final isar = await Isar.open(

From 2082e875536c1fea506ba633526bc5c2518a5c56 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 9 Nov 2022 17:55:10 -0600
Subject: [PATCH 191/426] WIP: desktop loading order

---
 lib/main.dart | 93 +++++++++++++++++++++++++++------------------------
 1 file changed, 50 insertions(+), 43 deletions(-)

diff --git a/lib/main.dart b/lib/main.dart
index c88ae2164..a8b515b02 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -60,6 +60,7 @@ import 'package:stackwallet/utilities/theme/dark_colors.dart';
 import 'package:stackwallet/utilities/theme/light_colors.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:window_size/window_size.dart';
 
 final openedFromSWBFileStringStateProvider =
@@ -568,50 +569,56 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
               _buildOutlineInputBorder(colorScheme.textFieldDefaultBG),
         ),
       ),
-      home: FutureBuilder(
-        future: load(),
-        builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
-          if (snapshot.connectionState == ConnectionState.done) {
-            // FlutterNativeSplash.remove();
-            if (Util.isDesktop &&
-                (_wallets.hasWallets || _desktopHasPassword)) {
-              String? startupWalletId;
-              if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) {
-                startupWalletId =
-                    ref.read(prefsChangeNotifierProvider).startupWalletId;
-              }
-
-              return DesktopLoginView(startupWalletId: startupWalletId);
-            } else if (!Util.isDesktop &&
-                (_wallets.hasWallets || _prefs.hasPin)) {
-              // return HomeView();
-
-              String? startupWalletId;
-              if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) {
-                startupWalletId =
-                    ref.read(prefsChangeNotifierProvider).startupWalletId;
-              }
-
-              return LockscreenView(
-                isInitialAppLogin: true,
-                routeOnSuccess: HomeView.routeName,
-                routeOnSuccessArguments: startupWalletId,
-                biometricsAuthenticationTitle: "Unlock Stack",
-                biometricsLocalizedReason:
-                    "Unlock your stack wallet using biometrics",
-                biometricsCancelButtonString: "Cancel",
-              );
-            } else {
-              return const IntroView();
-            }
-          } else {
-            // CURRENTLY DISABLED as cannot be animated
-            // technically not needed as FlutterNativeSplash will overlay
-            // anything returned here until the future completes but
-            // FutureBuilder requires you to return something
-            return const LoadingView();
-          }
+      home: ConditionalParent(
+        condition: Util.isDesktop,
+        builder: (child) {
+          return child;
         },
+        child: FutureBuilder(
+          future: load(),
+          builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
+            if (snapshot.connectionState == ConnectionState.done) {
+              // FlutterNativeSplash.remove();
+              if (Util.isDesktop &&
+                  (_wallets.hasWallets || _desktopHasPassword)) {
+                String? startupWalletId;
+                if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) {
+                  startupWalletId =
+                      ref.read(prefsChangeNotifierProvider).startupWalletId;
+                }
+
+                return DesktopLoginView(startupWalletId: startupWalletId);
+              } else if (!Util.isDesktop &&
+                  (_wallets.hasWallets || _prefs.hasPin)) {
+                // return HomeView();
+
+                String? startupWalletId;
+                if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) {
+                  startupWalletId =
+                      ref.read(prefsChangeNotifierProvider).startupWalletId;
+                }
+
+                return LockscreenView(
+                  isInitialAppLogin: true,
+                  routeOnSuccess: HomeView.routeName,
+                  routeOnSuccessArguments: startupWalletId,
+                  biometricsAuthenticationTitle: "Unlock Stack",
+                  biometricsLocalizedReason:
+                      "Unlock your stack wallet using biometrics",
+                  biometricsCancelButtonString: "Cancel",
+                );
+              } else {
+                return const IntroView();
+              }
+            } else {
+              // CURRENTLY DISABLED as cannot be animated
+              // technically not needed as FlutterNativeSplash will overlay
+              // anything returned here until the future completes but
+              // FutureBuilder requires you to return something
+              return const LoadingView();
+            }
+          },
+        ),
       ),
     );
   }

From 2d9cf9146331e6dc3aa819d2d24751fb24931f5c Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 9 Nov 2022 16:57:06 -0700
Subject: [PATCH 192/426] v1.5.16 build 88

---
 pubspec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index 86f24330b..19d38ca4f 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.14+86
+version: 1.5.16+88
 
 environment:
   sdk: ">=2.17.0 <3.0.0"

From 9d7a052ca0b0241834a54a70af953463c53fd22f Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 10 Nov 2022 09:42:05 -0600
Subject: [PATCH 193/426] qr uri fix

---
 .../generate_receiving_uri_qr_code_view.dart  | 20 ++++++++-----------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
index 4c3c4c968..0f699642e 100644
--- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
+++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
@@ -11,6 +11,7 @@ import 'package:path_provider/path_provider.dart';
 import 'package:qr_flutter/qr_flutter.dart';
 import 'package:share_plus/share_plus.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/constants.dart';
@@ -101,26 +102,21 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
       return null;
     }
 
-    String query = "";
+    Map<String, String> queryParams = {};
 
     if (amountString.isNotEmpty) {
-      query += "amount=$amountString";
+      queryParams["amount"] = amountString;
     }
     if (noteString.isNotEmpty) {
-      if (query.isNotEmpty) {
-        query += "&";
-      }
-      query += "message=$noteString";
+      queryParams["message"] = noteString;
     }
 
-    final uri = Uri(
-      scheme: widget.coin.uriScheme,
-      host: widget.receivingAddress,
-      query: query.isNotEmpty ? query : null,
+    final uriString = AddressUtils.buildUriString(
+      widget.coin,
+      widget.receivingAddress,
+      queryParams,
     );
 
-    final uriString = uri.toString().replaceFirst("://", ":");
-
     Logging.instance.log("Generated receiving QR code for: $uriString",
         level: LogLevel.Info);
 

From be952d3e35bfbdb1939e7aded8dc8e983778e3c4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 10 Nov 2022 09:54:58 -0600
Subject: [PATCH 194/426] manually add bch uri fixes from
 https://github.com/cypherstack/stack_wallet/pull/214/commits/28da2b890076a1d679dccaa9970c98516d4ae2d9

---
 .../generate_receiving_uri_qr_code_view.dart  | 29 +++++++++++++++----
 lib/utilities/enums/coin_enum.dart            |  2 +-
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
index 0f699642e..ae615bd96 100644
--- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
+++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
@@ -111,9 +111,17 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
       queryParams["message"] = noteString;
     }
 
+    String receivingAddress = widget.receivingAddress;
+    if ((widget.coin == Coin.bitcoincash ||
+            widget.coin == Coin.bitcoincashTestnet) &&
+        receivingAddress.contains(":")) {
+      // remove cash addr prefix
+      receivingAddress = receivingAddress.split(":").sublist(1).join();
+    }
+
     final uriString = AddressUtils.buildUriString(
       widget.coin,
-      widget.receivingAddress,
+      receivingAddress,
       queryParams,
     );
 
@@ -225,10 +233,21 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
   @override
   void initState() {
     isDesktop = Util.isDesktop;
-    _uriString = Uri(
-      scheme: widget.coin.uriScheme,
-      host: widget.receivingAddress,
-    ).toString().replaceFirst("://", ":");
+
+    String receivingAddress = widget.receivingAddress;
+    if ((widget.coin == Coin.bitcoincash ||
+            widget.coin == Coin.bitcoincashTestnet) &&
+        receivingAddress.contains(":")) {
+      // remove cash addr prefix
+      receivingAddress = receivingAddress.split(":").sublist(1).join();
+    }
+
+    _uriString = AddressUtils.buildUriString(
+      widget.coin,
+      receivingAddress,
+      {},
+    );
+
     amountController = TextEditingController();
     noteController = TextEditingController();
     super.initState();
diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart
index 95294c8aa..48212bde8 100644
--- a/lib/utilities/enums/coin_enum.dart
+++ b/lib/utilities/enums/coin_enum.dart
@@ -132,7 +132,7 @@ extension CoinExt on Coin {
       case Coin.litecoinTestNet:
         return "litecoin";
       case Coin.bitcoincashTestnet:
-        return "bitcoincash";
+        return "bchtest";
       case Coin.firoTestNet:
         return "firo";
       case Coin.dogecoinTestNet:

From 74a04750765d26a592ed62b7e3bc408907da8122 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 10 Nov 2022 09:09:03 -0700
Subject: [PATCH 195/426] WIP: desktop restore dialog displays

---
 .../restore_from_file_view.dart               |  77 ++-
 .../stack_restore_progress_view.dart          | 556 +++++++++---------
 .../restore_backup_dialog.dart                | 171 ------
 3 files changed, 355 insertions(+), 449 deletions(-)
 delete mode 100644 lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index a237d9ea9..dbf46c729 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -20,6 +20,8 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
@@ -500,14 +502,73 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                                       return;
                                     }
 
-                                    await Navigator.of(context).push(
-                                      RouteGenerator.getRoute(
-                                        builder: (_) =>
-                                            StackRestoreProgressView(
-                                          jsonString: jsonString,
-                                        ),
-                                      ),
-                                    );
+                                    await showDialog<dynamic>(
+                                        context: context,
+                                        useSafeArea: false,
+                                        barrierDismissible: true,
+                                        builder: (context) {
+                                          return DesktopDialog(
+                                            maxHeight: 750,
+                                            maxWidth: 600,
+                                            child: LayoutBuilder(
+                                              builder: (context, constraints) {
+                                                return SingleChildScrollView(
+                                                  child: ConstrainedBox(
+                                                    constraints: BoxConstraints(
+                                                      minHeight:
+                                                          constraints.maxHeight,
+                                                    ),
+                                                    child: IntrinsicHeight(
+                                                      child: Column(
+                                                        mainAxisAlignment:
+                                                            MainAxisAlignment
+                                                                .start,
+                                                        children: [
+                                                          Row(
+                                                            mainAxisAlignment:
+                                                                MainAxisAlignment
+                                                                    .spaceBetween,
+                                                            children: [
+                                                              Padding(
+                                                                padding:
+                                                                    const EdgeInsets
+                                                                        .all(32),
+                                                                child: Text(
+                                                                  "Restoring Stack Wallet",
+                                                                  style: STextStyles
+                                                                      .desktopH3(
+                                                                          context),
+                                                                  textAlign:
+                                                                      TextAlign
+                                                                          .center,
+                                                                ),
+                                                              ),
+                                                              const DesktopDialogCloseButton(),
+                                                            ],
+                                                          ),
+                                                          const SizedBox(
+                                                            height: 30,
+                                                          ),
+                                                          Padding(
+                                                            padding: EdgeInsets
+                                                                .symmetric(
+                                                                    horizontal:
+                                                                        32),
+                                                            child:
+                                                                StackRestoreProgressView(
+                                                              jsonString:
+                                                                  jsonString,
+                                                            ),
+                                                          ),
+                                                        ],
+                                                      ),
+                                                    ),
+                                                  ),
+                                                );
+                                              },
+                                            ),
+                                          );
+                                        });
                                   }
                                 },
                         ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
index 5e5142425..7dec4e740 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
@@ -3,7 +3,6 @@ import 'dart:async';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/pages/home_view/home_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart';
@@ -17,6 +16,8 @@ import 'package:stackwallet/utilities/enums/stack_restoring_status.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
@@ -39,6 +40,8 @@ class StackRestoreProgressView extends ConsumerStatefulWidget {
 
 class _StackRestoreProgressViewState
     extends ConsumerState<StackRestoreProgressView> {
+  bool isDesktop = Util.isDesktop;
+
   Future<void> _cancel() async {
     bool shouldPop = false;
     unawaited(showDialog<void>(
@@ -79,10 +82,15 @@ class _StackRestoreProgressViewState
 
     await SWB.cancelRestore();
     shouldPop = true;
+
+    int count = 0;
+
     if (mounted) {
-      Navigator.of(context).popUntil(ModalRoute.withName(widget.fromFile
-          ? RestoreFromEncryptedStringView.routeName
-          : StackBackupView.routeName));
+      !isDesktop
+          ? Navigator.of(context).popUntil(ModalRoute.withName(widget.fromFile
+              ? RestoreFromEncryptedStringView.routeName
+              : StackBackupView.routeName))
+          : Navigator.of(context).popUntil((_) => count++ >= 2);
     }
   }
 
@@ -179,281 +187,289 @@ class _StackRestoreProgressViewState
 
   @override
   Widget build(BuildContext context) {
-    return WillPopScope(
-      onWillPop: _onWillPop,
-      child: Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          leading: AppBarBackButton(
-            onPressed: () async {
-              if (FocusScope.of(context).hasFocus) {
-                FocusScope.of(context).unfocus();
-                await Future<void>.delayed(const Duration(milliseconds: 75));
-              }
-              if (_success) {
-                _addWalletsToHomeView();
-                if (mounted) {
-                  Navigator.of(context).pop();
-                }
-              } else {
-                if (await _requestCancel()) {
-                  await _cancel();
-                }
-              }
-            },
-          ),
-          title: Text(
-            "Restoring Stack wallet",
-            style: STextStyles.navBarTitle(context),
-          ),
-        ),
-        body: Padding(
-          padding: const EdgeInsets.only(
-            left: 12,
-            top: 12,
-            right: 12,
-          ),
-          child: SingleChildScrollView(
-            child: Padding(
-              padding: const EdgeInsets.only(
-                left: 4,
-                top: 4,
-                right: 4,
-                bottom: 0,
+    bool isDesktop = Util.isDesktop;
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return WillPopScope(
+          onWillPop: _onWillPop,
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              leading: AppBarBackButton(
+                onPressed: () async {
+                  if (FocusScope.of(context).hasFocus) {
+                    FocusScope.of(context).unfocus();
+                    await Future<void>.delayed(
+                        const Duration(milliseconds: 75));
+                  }
+                  if (_success) {
+                    _addWalletsToHomeView();
+                    if (mounted) {
+                      Navigator.of(context).pop();
+                    }
+                  } else {
+                    if (await _requestCancel()) {
+                      await _cancel();
+                    }
+                  }
+                },
               ),
-              child: Column(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  Text(
-                    "Settings",
-                    style: STextStyles.itemSubtitle(context),
-                  ),
-                  const SizedBox(
-                    height: 12,
-                  ),
-                  Consumer(
-                    builder: (_, ref, __) {
-                      final state = ref.watch(stackRestoringUIStateProvider
-                          .select((value) => value.preferences));
-                      return RestoringItemCard(
-                        left: SizedBox(
-                          width: 32,
-                          height: 32,
-                          child: RoundedContainer(
-                            padding: const EdgeInsets.all(0),
+              title: Text(
+                "Restoring Stack wallet",
+                style: STextStyles.navBarTitle(context),
+              ),
+            ),
+            body: Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: child,
+            ),
+          ),
+        );
+      },
+      child: SingleChildScrollView(
+        child: Padding(
+          padding: const EdgeInsets.only(
+            left: 4,
+            top: 4,
+            right: 4,
+            bottom: 0,
+          ),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Text(
+                "Settings",
+                style: STextStyles.itemSubtitle(context),
+              ),
+              const SizedBox(
+                height: 12,
+              ),
+              Consumer(
+                builder: (_, ref, __) {
+                  final state = ref.watch(stackRestoringUIStateProvider
+                      .select((value) => value.preferences));
+                  return RestoringItemCard(
+                    left: SizedBox(
+                      width: 32,
+                      height: 32,
+                      child: RoundedContainer(
+                        padding: const EdgeInsets.all(0),
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .buttonBackSecondary,
+                        child: Center(
+                          child: SvgPicture.asset(
+                            Assets.svg.gear,
+                            width: 16,
+                            height: 16,
                             color: Theme.of(context)
                                 .extension<StackColors>()!
-                                .buttonBackSecondary,
-                            child: Center(
-                              child: SvgPicture.asset(
-                                Assets.svg.gear,
-                                width: 16,
-                                height: 16,
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorDark,
-                              ),
-                            ),
-                          ),
-                        ),
-                        right: SizedBox(
-                          width: 20,
-                          height: 20,
-                          child: _getIconForState(state),
-                        ),
-                        title: "Preferences",
-                        subTitle: state == StackRestoringStatus.failed
-                            ? Text(
-                                "Something went wrong",
-                                style: STextStyles.errorSmall(context),
-                              )
-                            : null,
-                      );
-                    },
-                  ),
-                  const SizedBox(
-                    height: 12,
-                  ),
-                  Consumer(
-                    builder: (_, ref, __) {
-                      final state = ref.watch(stackRestoringUIStateProvider
-                          .select((value) => value.addressBook));
-                      return RestoringItemCard(
-                        left: SizedBox(
-                          width: 32,
-                          height: 32,
-                          child: RoundedContainer(
-                            padding: const EdgeInsets.all(0),
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .buttonBackSecondary,
-                            child: Center(
-                              child: AddressBookIcon(
-                                width: 16,
-                                height: 16,
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorDark,
-                              ),
-                            ),
-                          ),
-                        ),
-                        right: SizedBox(
-                          width: 20,
-                          height: 20,
-                          child: _getIconForState(state),
-                        ),
-                        title: "Address book",
-                        subTitle: state == StackRestoringStatus.failed
-                            ? Text(
-                                "Something went wrong",
-                                style: STextStyles.errorSmall(context),
-                              )
-                            : null,
-                      );
-                    },
-                  ),
-                  const SizedBox(
-                    height: 12,
-                  ),
-                  Consumer(
-                    builder: (_, ref, __) {
-                      final state = ref.watch(stackRestoringUIStateProvider
-                          .select((value) => value.nodes));
-                      return RestoringItemCard(
-                        left: SizedBox(
-                          width: 32,
-                          height: 32,
-                          child: RoundedContainer(
-                            padding: const EdgeInsets.all(0),
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .buttonBackSecondary,
-                            child: Center(
-                              child: SvgPicture.asset(
-                                Assets.svg.node,
-                                width: 16,
-                                height: 16,
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorDark,
-                              ),
-                            ),
-                          ),
-                        ),
-                        right: SizedBox(
-                          width: 20,
-                          height: 20,
-                          child: _getIconForState(state),
-                        ),
-                        title: "Nodes",
-                        subTitle: state == StackRestoringStatus.failed
-                            ? Text(
-                                "Something went wrong",
-                                style: STextStyles.errorSmall(context),
-                              )
-                            : null,
-                      );
-                    },
-                  ),
-                  const SizedBox(
-                    height: 12,
-                  ),
-                  Consumer(
-                    builder: (_, ref, __) {
-                      final state = ref.watch(stackRestoringUIStateProvider
-                          .select((value) => value.trades));
-                      return RestoringItemCard(
-                        left: SizedBox(
-                          width: 32,
-                          height: 32,
-                          child: RoundedContainer(
-                            padding: const EdgeInsets.all(0),
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .buttonBackSecondary,
-                            child: Center(
-                              child: SvgPicture.asset(
-                                Assets.svg.arrowRotate2,
-                                width: 16,
-                                height: 16,
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorDark,
-                              ),
-                            ),
-                          ),
-                        ),
-                        right: SizedBox(
-                          width: 20,
-                          height: 20,
-                          child: _getIconForState(state),
-                        ),
-                        title: "Exchange history",
-                        subTitle: state == StackRestoringStatus.failed
-                            ? Text(
-                                "Something went wrong",
-                                style: STextStyles.errorSmall(context),
-                              )
-                            : null,
-                      );
-                    },
-                  ),
-                  const SizedBox(
-                    height: 16,
-                  ),
-                  Text(
-                    "Wallets",
-                    style: STextStyles.itemSubtitle(context),
-                  ),
-                  const SizedBox(
-                    height: 8,
-                  ),
-                  ...ref
-                      .watch(stackRestoringUIStateProvider
-                          .select((value) => value.walletStateProviders))
-                      .values
-                      .map(
-                        (provider) => Padding(
-                          padding: const EdgeInsets.symmetric(vertical: 4),
-                          child: RestoringWalletCard(
-                            provider: provider,
+                                .accentColorDark,
                           ),
                         ),
                       ),
-                  const SizedBox(
-                    height: 80,
+                    ),
+                    right: SizedBox(
+                      width: 20,
+                      height: 20,
+                      child: _getIconForState(state),
+                    ),
+                    title: "Preferences",
+                    subTitle: state == StackRestoringStatus.failed
+                        ? Text(
+                            "Something went wrong",
+                            style: STextStyles.errorSmall(context),
+                          )
+                        : null,
+                  );
+                },
+              ),
+              const SizedBox(
+                height: 12,
+              ),
+              Consumer(
+                builder: (_, ref, __) {
+                  final state = ref.watch(stackRestoringUIStateProvider
+                      .select((value) => value.addressBook));
+                  return RestoringItemCard(
+                    left: SizedBox(
+                      width: 32,
+                      height: 32,
+                      child: RoundedContainer(
+                        padding: const EdgeInsets.all(0),
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .buttonBackSecondary,
+                        child: Center(
+                          child: AddressBookIcon(
+                            width: 16,
+                            height: 16,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorDark,
+                          ),
+                        ),
+                      ),
+                    ),
+                    right: SizedBox(
+                      width: 20,
+                      height: 20,
+                      child: _getIconForState(state),
+                    ),
+                    title: "Address book",
+                    subTitle: state == StackRestoringStatus.failed
+                        ? Text(
+                            "Something went wrong",
+                            style: STextStyles.errorSmall(context),
+                          )
+                        : null,
+                  );
+                },
+              ),
+              const SizedBox(
+                height: 12,
+              ),
+              Consumer(
+                builder: (_, ref, __) {
+                  final state = ref.watch(stackRestoringUIStateProvider
+                      .select((value) => value.nodes));
+                  return RestoringItemCard(
+                    left: SizedBox(
+                      width: 32,
+                      height: 32,
+                      child: RoundedContainer(
+                        padding: const EdgeInsets.all(0),
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .buttonBackSecondary,
+                        child: Center(
+                          child: SvgPicture.asset(
+                            Assets.svg.node,
+                            width: 16,
+                            height: 16,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorDark,
+                          ),
+                        ),
+                      ),
+                    ),
+                    right: SizedBox(
+                      width: 20,
+                      height: 20,
+                      child: _getIconForState(state),
+                    ),
+                    title: "Nodes",
+                    subTitle: state == StackRestoringStatus.failed
+                        ? Text(
+                            "Something went wrong",
+                            style: STextStyles.errorSmall(context),
+                          )
+                        : null,
+                  );
+                },
+              ),
+              const SizedBox(
+                height: 12,
+              ),
+              Consumer(
+                builder: (_, ref, __) {
+                  final state = ref.watch(stackRestoringUIStateProvider
+                      .select((value) => value.trades));
+                  return RestoringItemCard(
+                    left: SizedBox(
+                      width: 32,
+                      height: 32,
+                      child: RoundedContainer(
+                        padding: const EdgeInsets.all(0),
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .buttonBackSecondary,
+                        child: Center(
+                          child: SvgPicture.asset(
+                            Assets.svg.arrowRotate2,
+                            width: 16,
+                            height: 16,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorDark,
+                          ),
+                        ),
+                      ),
+                    ),
+                    right: SizedBox(
+                      width: 20,
+                      height: 20,
+                      child: _getIconForState(state),
+                    ),
+                    title: "Exchange history",
+                    subTitle: state == StackRestoringStatus.failed
+                        ? Text(
+                            "Something went wrong",
+                            style: STextStyles.errorSmall(context),
+                          )
+                        : null,
+                  );
+                },
+              ),
+              const SizedBox(
+                height: 16,
+              ),
+              Text(
+                "Wallets",
+                style: STextStyles.itemSubtitle(context),
+              ),
+              const SizedBox(
+                height: 8,
+              ),
+              ...ref
+                  .watch(stackRestoringUIStateProvider
+                      .select((value) => value.walletStateProviders))
+                  .values
+                  .map(
+                    (provider) => Padding(
+                      padding: const EdgeInsets.symmetric(vertical: 4),
+                      child: RestoringWalletCard(
+                        provider: provider,
+                      ),
+                    ),
                   ),
-                ],
+              const SizedBox(
+                height: 30,
               ),
-            ),
-          ),
-        ),
-        floatingActionButton: SizedBox(
-          width: MediaQuery.of(context).size.width - 32,
-          child: TextButton(
-            onPressed: () async {
-              if (_success) {
-                _addWalletsToHomeView();
-                Navigator.of(context)
-                    .popUntil(ModalRoute.withName(HomeView.routeName));
-              } else {
-                if (await _requestCancel()) {
-                  await _cancel();
-                }
-              }
-            },
-            style: Theme.of(context)
-                .extension<StackColors>()!
-                .getPrimaryEnabledButtonColor(context),
-            child: Text(
-              _success ? "OK" : "Cancel restore process",
-              style: STextStyles.button(context).copyWith(
-                color: Theme.of(context)
-                    .extension<StackColors>()!
-                    .buttonTextPrimary,
+              SizedBox(
+                width: MediaQuery.of(context).size.width - 32,
+                child: TextButton(
+                  onPressed: () async {
+                    if (_success) {
+                      Navigator.of(context).pop();
+                    } else {
+                      if (await _requestCancel()) {
+                        await _cancel();
+                      }
+                    }
+                  },
+                  style: Theme.of(context)
+                      .extension<StackColors>()!
+                      .getPrimaryEnabledButtonColor(context),
+                  child: Text(
+                    _success ? "OK" : "Cancel restore process",
+                    style: STextStyles.button(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .buttonTextPrimary,
+                    ),
+                  ),
+                ),
               ),
-            ),
+            ],
           ),
         ),
       ),
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart
deleted file mode 100644
index 7f944847d..000000000
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart
+++ /dev/null
@@ -1,171 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
-import 'package:stackwallet/widgets/desktop/secondary_button.dart';
-import 'package:stackwallet/widgets/rounded_white_container.dart';
-
-class RestoreBackupDialog extends StatelessWidget {
-  const RestoreBackupDialog({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return DesktopDialog(
-        maxHeight: 750,
-        maxWidth: 600,
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    mainAxisAlignment: MainAxisAlignment.start,
-                    children: [
-                      Row(
-                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        children: [
-                          Padding(
-                            padding: const EdgeInsets.all(32),
-                            child: Text(
-                              "Restoring Stack Wallet",
-                              style: STextStyles.desktopH3(context),
-                              textAlign: TextAlign.center,
-                            ),
-                          ),
-                          const DesktopDialogCloseButton(),
-                        ],
-                      ),
-                      const SizedBox(
-                        height: 30,
-                      ),
-                      Padding(
-                        padding: const EdgeInsets.symmetric(horizontal: 32),
-                        child: Row(
-                          children: [
-                            Text(
-                              "Settings",
-                              style: STextStyles.desktopTextExtraSmall(context)
-                                  .copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textDark3,
-                              ),
-                              textAlign: TextAlign.left,
-                            ),
-                          ],
-                        ),
-                      ),
-                      Padding(
-                        padding: const EdgeInsets.symmetric(
-                            horizontal: 32, vertical: 12),
-                        child: RoundedWhiteContainer(
-                          borderColor: Theme.of(context)
-                              .extension<StackColors>()!
-                              .background,
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Row(
-                                children: [
-                                  SvgPicture.asset(
-                                    Assets.svg.framedAddressBook,
-                                    width: 40,
-                                    height: 40,
-                                  ),
-                                  const SizedBox(width: 12),
-                                  Text(
-                                    "Address Book",
-                                    style:
-                                        STextStyles.desktopTextSmall(context),
-                                  ),
-                                ],
-                              ),
-
-                              ///TODO: CHECKMARK ANIMATION
-                            ],
-                          ),
-                        ),
-                      ),
-                      Padding(
-                        padding: const EdgeInsets.symmetric(
-                            horizontal: 32, vertical: 12),
-                        child: RoundedWhiteContainer(
-                          borderColor: Theme.of(context)
-                              .extension<StackColors>()!
-                              .background,
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Row(
-                                children: [
-                                  SvgPicture.asset(
-                                    Assets.svg.framedGear,
-                                    width: 40,
-                                    height: 40,
-                                  ),
-                                  const SizedBox(width: 12),
-                                  Text(
-                                    "Preferences",
-                                    style:
-                                        STextStyles.desktopTextSmall(context),
-                                  ),
-                                ],
-                              ),
-
-                              ///TODO: CHECKMARK ANIMATION
-                            ],
-                          ),
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 30,
-                      ),
-                      Padding(
-                        padding: const EdgeInsets.symmetric(horizontal: 32),
-                        child: Row(
-                          children: [
-                            Text(
-                              "Wallets",
-                              style: STextStyles.desktopTextExtraSmall(context)
-                                  .copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textDark3,
-                              ),
-                              textAlign: TextAlign.left,
-                            ),
-                          ],
-                        ),
-                      ),
-                      const Spacer(),
-                      Padding(
-                        padding: const EdgeInsets.all(32),
-                        child: Row(
-                          mainAxisAlignment: MainAxisAlignment.end,
-                          children: [
-                            SecondaryButton(
-                              desktopMed: true,
-                              width: 200,
-                              label: "Cancel restore process",
-                              onPressed: () {
-                                Navigator.of(context).pop();
-                              },
-                            ),
-                          ],
-                        ),
-                      ),
-                    ],
-                  ),
-                ),
-              ),
-            );
-          },
-        ));
-  }
-}

From 07c99309ff80e5428ba6888613d2bde20aef6a07 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 10 Nov 2022 10:21:07 -0600
Subject: [PATCH 196/426] use native address validation

---
 crypto_plugins/flutter_libmonero               | 2 +-
 lib/services/coins/monero/monero_wallet.dart   | 4 +---
 lib/services/coins/wownero/wownero_wallet.dart | 4 +---
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index b9bc2dcc5..4dd55584a 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit b9bc2dcc56e13f235a6c5b0fc02c0e543eb87758
+Subproject commit 4dd55584a023bf6fd863c24ca8e1ffcedcc25162
diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index 4d29c405c..a96ecac83 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -1353,10 +1353,8 @@ class MoneroWallet extends CoinServiceAPI {
   Future<List<UtxoObject>> get unspentOutputs => throw UnimplementedError();
 
   @override
-  // TODO: implement validateAddress
   bool validateAddress(String address) {
-    bool valid = RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
-        RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
+    bool valid = walletBase!.validateAddress(address);
     return valid;
   }
 
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index e2c52c40a..4c02ec037 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -1378,10 +1378,8 @@ class WowneroWallet extends CoinServiceAPI {
   Future<List<UtxoObject>> get unspentOutputs => throw UnimplementedError();
 
   @override
-  // TODO: implement validateAddress
   bool validateAddress(String address) {
-    bool valid = RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
-        RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
+    bool valid = walletBase!.validateAddress(address);
     return valid;
   }
 

From 6e48fc4ea6ce45b82ed5204ccba5ffd8773e9777 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 10 Nov 2022 10:46:09 -0600
Subject: [PATCH 197/426] use hive_test for monero and wownero tests

---
 .../coins/monero/monero_wallet_test.dart      | 26 +++++++++++++------
 .../coins/wownero/wownero_wallet_test.dart    | 26 +++++++++++++------
 2 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index d54959ab2..2c755b484 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -81,19 +81,29 @@ void main() async {
   if (Platform.isIOS) {
     appDir = (await getLibraryDirectory());
   }
-  await Hive.close();
-  Hive.init(appDir.path);
-  Hive.registerAdapter(NodeAdapter());
-  Hive.registerAdapter(WalletInfoAdapter());
-  Hive.registerAdapter(WalletTypeAdapter());
-  Hive.registerAdapter(UnspentCoinsInfoAdapter());
 
   monero.onStartup();
-  _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-  walletService = monero.createMoneroWalletService(_walletInfoSource);
+
+  bool hiveAdaptersRegistered = false;
 
   group("Mainnet tests", () {
     setUp(() async {
+      await setUpTestHive();
+      if (!hiveAdaptersRegistered) {
+        hiveAdaptersRegistered = true;
+
+        Hive.registerAdapter(NodeAdapter());
+        Hive.registerAdapter(WalletInfoAdapter());
+        Hive.registerAdapter(WalletTypeAdapter());
+        Hive.registerAdapter(UnspentCoinsInfoAdapter());
+
+        final wallets = await Hive.openBox('wallets');
+        await wallets.put('currentWalletName', name);
+
+        _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
+        walletService = monero.createMoneroWalletService(_walletInfoSource);
+      }
+
       try {
         // if (name?.isEmpty ?? true) {
         // name = await generateName();
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 660bc1438..87229a63a 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -72,19 +72,29 @@ void main() async {
   if (Platform.isIOS) {
     appDir = (await getLibraryDirectory());
   }
-  await Hive.close();
-  Hive.init(appDir.path);
-  Hive.registerAdapter(NodeAdapter());
-  Hive.registerAdapter(WalletInfoAdapter());
-  Hive.registerAdapter(WalletTypeAdapter());
-  Hive.registerAdapter(UnspentCoinsInfoAdapter());
 
   wownero.onStartup();
-  _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-  walletService = wownero.createWowneroWalletService(_walletInfoSource);
+
+  bool hiveAdaptersRegistered = false;
 
   group("Wownero 14 word seed generation", () {
     setUp(() async {
+      await setUpTestHive();
+      if (!hiveAdaptersRegistered) {
+        hiveAdaptersRegistered = true;
+
+        Hive.registerAdapter(NodeAdapter());
+        Hive.registerAdapter(WalletInfoAdapter());
+        Hive.registerAdapter(WalletTypeAdapter());
+        Hive.registerAdapter(UnspentCoinsInfoAdapter());
+
+        final wallets = await Hive.openBox('wallets');
+        await wallets.put('currentWalletName', name);
+
+        _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
+        walletService = wownero.createWowneroWalletService(_walletInfoSource);
+      }
+
       bool hasThrown = false;
       try {
         name = 'namee${Random().nextInt(10000000)}';

From 3fb80fdc29146b1ad43e760070edf1414b69c1e0 Mon Sep 17 00:00:00 2001
From: julian-CStack <97684800+julian-CStack@users.noreply.github.com>
Date: Thu, 10 Nov 2022 11:16:22 -0600
Subject: [PATCH 198/426] Update test.yaml

attempt apt update
---
 .github/workflows/test.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index d72d33ac4..83de43779 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 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
           sudo apt install -y libc6-dev-i386

From 50f4f2ff64b28e7a9a18a2fb3a0fc6eeb1289a9f Mon Sep 17 00:00:00 2001
From: julian-CStack <97684800+julian-CStack@users.noreply.github.com>
Date: Thu, 10 Nov 2022 11:23:49 -0600
Subject: [PATCH 199/426] Update test.yaml

apt update
---
 .github/workflows/test.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index d72d33ac4..83de43779 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 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
           sudo apt install -y libc6-dev-i386

From f2bef21853639653b1be0ded1fc4355c55b8cb68 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 10 Nov 2022 11:40:33 -0600
Subject: [PATCH 200/426] temp disable erroring code

---
 .../restore_from_file_view.dart                | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index dbf46c729..ee1fcf666 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -9,7 +9,7 @@ import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
+// import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -49,14 +49,14 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
   bool hidePassword = true;
 
   Future<void> restoreBackupPopup(BuildContext context) async {
-    await showDialog<dynamic>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: true,
-      builder: (context) {
-        return const RestoreBackupDialog();
-      },
-    );
+    // await showDialog<dynamic>(
+    //   context: context,
+    //   useSafeArea: false,
+    //   barrierDismissible: true,
+    //   builder: (context) {
+    //     return const RestoreBackupDialog();
+    //   },
+    // );
   }
 
   @override

From 15dc2512dbd431ac894169731a11220f97416dad Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 10 Nov 2022 12:19:51 -0600
Subject: [PATCH 201/426] update iOs headers

---
 crypto_plugins/flutter_libmonero | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index 4dd55584a..8a8c88cda 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit 4dd55584a023bf6fd863c24ca8e1ffcedcc25162
+Subproject commit 8a8c88cdade6fe18529deea410f862b125167a3b

From a50520b37ffdf1630aca2a9bd4f5a12f50db0cf7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 10 Nov 2022 12:40:16 -0600
Subject: [PATCH 202/426] WIP: desktop password login and auth flow

---
 lib/hive/db.dart                              |  52 +++---
 lib/main.dart                                 | 153 ++++++++++--------
 .../desktop_login_view.dart                   |  52 +++---
 .../create_auto_backup.dart                   |  15 +-
 lib/utilities/desktop_password_service.dart   |   2 -
 5 files changed, 148 insertions(+), 126 deletions(-)

diff --git a/lib/hive/db.dart b/lib/hive/db.dart
index d5402752e..48e6ba154 100644
--- a/lib/hive/db.dart
+++ b/lib/hive/db.dart
@@ -43,23 +43,23 @@ class DB {
 
   static bool _initialized = false;
 
-  late final Box<dynamic> _boxAddressBook;
-  late final Box<String> _boxDebugInfo;
-  late final Box<NodeModel> _boxNodeModels;
-  late final Box<NodeModel> _boxPrimaryNodes;
-  late final Box<dynamic> _boxAllWalletsData;
-  late final Box<NotificationModel> _boxNotifications;
-  late final Box<NotificationModel> _boxWatchedTransactions;
-  late final Box<NotificationModel> _boxWatchedTrades;
-  late final Box<ExchangeTransaction> _boxTrades;
-  late final Box<Trade> _boxTradesV2;
-  late final Box<String> _boxTradeNotes;
-  late final Box<String> _boxFavoriteWallets;
-  late final Box<xmr.WalletInfo> _walletInfoSource;
-  late final Box<dynamic> _boxPrefs;
-  late final Box<TradeWalletLookup> _boxTradeLookup;
-  late final Box<dynamic> _boxDBInfo;
-  late final Box<String> _boxDesktopData;
+  Box<dynamic>? _boxAddressBook;
+  Box<String>? _boxDebugInfo;
+  Box<NodeModel>? _boxNodeModels;
+  Box<NodeModel>? _boxPrimaryNodes;
+  Box<dynamic>? _boxAllWalletsData;
+  Box<NotificationModel>? _boxNotifications;
+  Box<NotificationModel>? _boxWatchedTransactions;
+  Box<NotificationModel>? _boxWatchedTrades;
+  Box<ExchangeTransaction>? _boxTrades;
+  Box<Trade>? _boxTradesV2;
+  Box<String>? _boxTradeNotes;
+  Box<String>? _boxFavoriteWallets;
+  Box<xmr.WalletInfo>? _walletInfoSource;
+  Box<dynamic>? _boxPrefs;
+  Box<TradeWalletLookup>? _boxTradeLookup;
+  Box<dynamic>? _boxDBInfo;
+  Box<String>? _boxDesktopData;
 
   final Map<String, Box<dynamic>> _walletBoxes = {};
 
@@ -68,7 +68,7 @@ class DB {
   final Map<Coin, Box<dynamic>> _usedSerialsCacheBoxes = {};
 
   // exposed for monero
-  Box<xmr.WalletInfo> get moneroWalletInfoBox => _walletInfoSource;
+  Box<xmr.WalletInfo> get moneroWalletInfoBox => _walletInfoSource!;
 
   // mutex for stack backup
   final mutex = Mutex();
@@ -124,6 +124,12 @@ class DB {
         _boxAllWalletsData = await Hive.openBox<dynamic>(boxNameAllWalletsData);
       }
 
+      if (Hive.isBoxOpen(boxNameDesktopData)) {
+        _boxDesktopData = Hive.box<String>(boxNameDesktopData);
+      } else {
+        _boxDesktopData = await Hive.openBox<String>(boxNameDesktopData);
+      }
+
       _boxNotifications =
           await Hive.openBox<NotificationModel>(boxNameNotifications);
       _boxWatchedTransactions =
@@ -147,11 +153,11 @@ class DB {
       _initialized = true;
 
       try {
-        if (_boxPrefs.get("familiarity") == null) {
-          await _boxPrefs.put("familiarity", 0);
+        if (_boxPrefs!.get("familiarity") == null) {
+          await _boxPrefs!.put("familiarity", 0);
         }
-        int count = _boxPrefs.get("familiarity") as int;
-        await _boxPrefs.put("familiarity", count + 1);
+        int count = _boxPrefs!.get("familiarity") as int;
+        await _boxPrefs!.put("familiarity", count + 1);
         Constants.exchangeForExperiencedUsers(count + 1);
       } catch (e, s) {
         print("$e $s");
@@ -160,7 +166,7 @@ class DB {
   }
 
   Future<void> _loadWalletBoxes() async {
-    final names = _boxAllWalletsData.get("names") as Map? ?? {};
+    final names = _boxAllWalletsData!.get("names") as Map? ?? {};
     names.removeWhere((name, dyn) {
       final jsonObject = Map<String, dynamic>.from(dyn as Map);
       try {
diff --git a/lib/main.dart b/lib/main.dart
index a8b515b02..a04170bd9 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -48,19 +48,16 @@ import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/services/notifications_api.dart';
 import 'package:stackwallet/services/notifications_service.dart';
 import 'package:stackwallet/services/trade_service.dart';
-import 'package:stackwallet/services/wallets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/db_version_migration.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
-import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/theme/color_theme.dart';
 import 'package:stackwallet/utilities/theme/dark_colors.dart';
 import 'package:stackwallet/utilities/theme/light_colors.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
-import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:window_size/window_size.dart';
 
 final openedFromSWBFileStringStateProvider =
@@ -221,8 +218,8 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
   static const platform = MethodChannel("STACK_WALLET_RESTORE");
   final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
 
-  late final Wallets _wallets;
-  late final Prefs _prefs;
+  // late final Wallets _wallets;
+  // late final Prefs _prefs;
   late final NotificationsService _notificationsService;
   late final NodeService _nodeService;
   late final TradesService _tradesService;
@@ -232,6 +229,16 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
   bool didLoad = false;
   bool _desktopHasPassword = false;
 
+  Future<void> loadShared() async {
+    await DB.instance.init();
+    await ref.read(prefsChangeNotifierProvider).init();
+
+    if (Util.isDesktop) {
+      _desktopHasPassword =
+          await ref.read(storageCryptoHandlerProvider).hasPassword();
+    }
+  }
+
   Future<void> load() async {
     try {
       if (didLoad) {
@@ -239,19 +246,15 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
       }
       didLoad = true;
 
-      await DB.instance.init();
-      await _prefs.init();
-
-      if (Util.isDesktop) {
-        _desktopHasPassword =
-            await ref.read(storageCryptoHandlerProvider).hasPassword();
+      if (!Util.isDesktop) {
+        await loadShared();
       }
 
       _notificationsService = ref.read(notificationsProvider);
       _nodeService = ref.read(nodeServiceChangeNotifierProvider);
       _tradesService = ref.read(tradesServiceProvider);
 
-      NotificationApi.prefs = _prefs;
+      NotificationApi.prefs = ref.read(prefsChangeNotifierProvider);
       NotificationApi.notificationsService = _notificationsService;
 
       unawaited(ref.read(baseCurrenciesProvider).update());
@@ -260,23 +263,25 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
       await _notificationsService.init(
         nodeService: _nodeService,
         tradesService: _tradesService,
-        prefs: _prefs,
+        prefs: ref.read(prefsChangeNotifierProvider),
       );
       ref.read(priceAnd24hChangeNotifierProvider).start(true);
-      await _wallets.load(_prefs);
+      await ref
+          .read(walletsChangeNotifierProvider)
+          .load(ref.read(prefsChangeNotifierProvider));
       loadingCompleter.complete();
       // TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet
       //  unawaited(_nodeService.updateCommunityNodes());
 
       // run without awaiting
       if (Constants.enableExchange &&
-          _prefs.externalCalls &&
-          await _prefs.isExternalCallsSet()) {
+          ref.read(prefsChangeNotifierProvider).externalCalls &&
+          await ref.read(prefsChangeNotifierProvider).isExternalCallsSet()) {
         unawaited(ExchangeDataLoadingService().loadAll(ref));
       }
 
-      if (_prefs.isAutoBackupEnabled) {
-        switch (_prefs.backupFrequencyType) {
+      if (ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled) {
+        switch (ref.read(prefsChangeNotifierProvider).backupFrequencyType) {
           case BackupFrequencyType.everyTenMinutes:
             ref.read(autoSWBServiceProvider).startPeriodicBackupTimer(
                 duration: const Duration(minutes: 10));
@@ -316,9 +321,6 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
         .read(localeServiceChangeNotifierProvider.notifier)
         .loadLocale(notify: false);
 
-    _prefs = ref.read(prefsChangeNotifierProvider);
-    _wallets = ref.read(walletsChangeNotifierProvider);
-
     WidgetsBinding.instance.addPostFrameCallback((_) async {
       ref.read(colorThemeProvider.state).state =
           StackColors.fromStackColorTheme(
@@ -423,7 +425,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
   }
 
   Future<void> goToRestoreSWB(String encrypted) async {
-    if (!_prefs.hasPin) {
+    if (!ref.read(prefsChangeNotifierProvider).hasPin) {
       await Navigator.of(navigatorKey.currentContext!)
           .pushNamed(CreatePinView.routeName, arguments: true)
           .then((value) {
@@ -569,57 +571,70 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
               _buildOutlineInputBorder(colorScheme.textFieldDefaultBG),
         ),
       ),
-      home: ConditionalParent(
-        condition: Util.isDesktop,
-        builder: (child) {
-          return child;
-        },
-        child: FutureBuilder(
-          future: load(),
-          builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
-            if (snapshot.connectionState == ConnectionState.done) {
-              // FlutterNativeSplash.remove();
-              if (Util.isDesktop &&
-                  (_wallets.hasWallets || _desktopHasPassword)) {
-                String? startupWalletId;
-                if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) {
-                  startupWalletId =
-                      ref.read(prefsChangeNotifierProvider).startupWalletId;
+      home: Util.isDesktop
+          ? FutureBuilder(
+              future: loadShared(),
+              builder: (context, snapshot) {
+                if (snapshot.connectionState == ConnectionState.done) {
+                  if (_desktopHasPassword) {
+                    String? startupWalletId;
+                    if (ref
+                        .read(prefsChangeNotifierProvider)
+                        .gotoWalletOnStartup) {
+                      startupWalletId =
+                          ref.read(prefsChangeNotifierProvider).startupWalletId;
+                    }
+
+                    return DesktopLoginView(
+                      startupWalletId: startupWalletId,
+                      load: load,
+                    );
+                  } else {
+                    return const IntroView();
+                  }
+                } else {
+                  return const LoadingView();
                 }
+              },
+            )
+          : FutureBuilder(
+              future: load(),
+              builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
+                if (snapshot.connectionState == ConnectionState.done) {
+                  // FlutterNativeSplash.remove();
+                  if (ref.read(walletsChangeNotifierProvider).hasWallets ||
+                      ref.read(prefsChangeNotifierProvider).hasPin) {
+                    // return HomeView();
 
-                return DesktopLoginView(startupWalletId: startupWalletId);
-              } else if (!Util.isDesktop &&
-                  (_wallets.hasWallets || _prefs.hasPin)) {
-                // return HomeView();
+                    String? startupWalletId;
+                    if (ref
+                        .read(prefsChangeNotifierProvider)
+                        .gotoWalletOnStartup) {
+                      startupWalletId =
+                          ref.read(prefsChangeNotifierProvider).startupWalletId;
+                    }
 
-                String? startupWalletId;
-                if (ref.read(prefsChangeNotifierProvider).gotoWalletOnStartup) {
-                  startupWalletId =
-                      ref.read(prefsChangeNotifierProvider).startupWalletId;
+                    return LockscreenView(
+                      isInitialAppLogin: true,
+                      routeOnSuccess: HomeView.routeName,
+                      routeOnSuccessArguments: startupWalletId,
+                      biometricsAuthenticationTitle: "Unlock Stack",
+                      biometricsLocalizedReason:
+                          "Unlock your stack wallet using biometrics",
+                      biometricsCancelButtonString: "Cancel",
+                    );
+                  } else {
+                    return const IntroView();
+                  }
+                } else {
+                  // CURRENTLY DISABLED as cannot be animated
+                  // technically not needed as FlutterNativeSplash will overlay
+                  // anything returned here until the future completes but
+                  // FutureBuilder requires you to return something
+                  return const LoadingView();
                 }
-
-                return LockscreenView(
-                  isInitialAppLogin: true,
-                  routeOnSuccess: HomeView.routeName,
-                  routeOnSuccessArguments: startupWalletId,
-                  biometricsAuthenticationTitle: "Unlock Stack",
-                  biometricsLocalizedReason:
-                      "Unlock your stack wallet using biometrics",
-                  biometricsCancelButtonString: "Cancel",
-                );
-              } else {
-                return const IntroView();
-              }
-            } else {
-              // CURRENTLY DISABLED as cannot be animated
-              // technically not needed as FlutterNativeSplash will overlay
-              // anything returned here until the future completes but
-              // FutureBuilder requires you to return something
-              return const LoadingView();
-            }
-          },
-        ),
-      ),
+              },
+            ),
     );
   }
 }
diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index 0a47c2a96..d90e742fb 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -21,11 +21,13 @@ class DesktopLoginView extends ConsumerStatefulWidget {
   const DesktopLoginView({
     Key? key,
     this.startupWalletId,
+    this.load,
   }) : super(key: key);
 
   static const String routeName = "/desktopLogin";
 
   final String? startupWalletId;
+  final Future<void> Function()? load;
 
   @override
   ConsumerState<DesktopLoginView> createState() => _DesktopLoginViewState();
@@ -39,6 +41,32 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
   bool hidePassword = true;
   bool _continueEnabled = false;
 
+  Future<void> login() async {
+    try {
+      await ref
+          .read(storageCryptoHandlerProvider)
+          .initFromExisting(passwordController.text);
+
+      await widget.load?.call();
+
+      // if no errors passphrase is correct
+      if (mounted) {
+        unawaited(
+          Navigator.of(context).pushNamedAndRemoveUntil(
+            DesktopHomeView.routeName,
+            (route) => false,
+          ),
+        );
+      }
+    } catch (e) {
+      await showFloatingFlushBar(
+        type: FlushBarType.warning,
+        message: e.toString(),
+        context: context,
+      );
+    }
+  }
+
   @override
   void initState() {
     passwordController = TextEditingController();
@@ -159,29 +187,7 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
                 PrimaryButton(
                   label: "Continue",
                   enabled: _continueEnabled,
-                  onPressed: () async {
-                    try {
-                      await ref
-                          .read(storageCryptoHandlerProvider)
-                          .initFromExisting(passwordController.text);
-
-                      // if no errors passphrase is correct
-                      if (mounted) {
-                        unawaited(
-                          Navigator.of(context).pushNamedAndRemoveUntil(
-                            DesktopHomeView.routeName,
-                            (route) => false,
-                          ),
-                        );
-                      }
-                    } catch (e) {
-                      await showFloatingFlushBar(
-                        type: FlushBarType.warning,
-                        message: e.toString(),
-                        context: context,
-                      );
-                    }
-                  },
+                  onPressed: login,
                 ),
                 const SizedBox(
                   height: 60,
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index e804071cc..2583e16c5 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -5,13 +5,13 @@ import 'package:dropdown_button2/dropdown_button2.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stack_wallet_backup/stack_wallet_backup.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
@@ -35,13 +35,8 @@ import 'package:zxcvbn/zxcvbn.dart';
 class CreateAutoBackup extends ConsumerStatefulWidget {
   const CreateAutoBackup({
     Key? key,
-    this.secureStore = const SecureStorageWrapper(
-      FlutterSecureStorage(),
-    ),
   }) : super(key: key);
 
-  final FlutterSecureStorageInterface secureStore;
-
   @override
   ConsumerState<CreateAutoBackup> createState() => _CreateAutoBackup();
 }
@@ -51,7 +46,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
   late final TextEditingController passphraseController;
   late final TextEditingController passphraseRepeatController;
 
-  late final FlutterSecureStorageInterface secureStore;
+  late final SecureStorageInterface secureStore;
 
   late final StackFileSystem stackFileSystem;
   late final FocusNode passphraseFocusNode;
@@ -85,7 +80,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
 
   @override
   void initState() {
-    secureStore = widget.secureStore;
+    secureStore = ref.read(secureStoreProvider);
     stackFileSystem = StackFileSystem();
 
     fileLocationController = TextEditingController();
@@ -686,7 +681,9 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                             final String fileToSave =
                                 createAutoBackupFilename(pathToSave, now);
 
-                            final backup = await SWB.createStackWalletJSON();
+                            final backup = await SWB.createStackWalletJSON(
+                              secureStorage: secureStore,
+                            );
 
                             bool result = await SWB.encryptStackWalletWithADK(
                               fileToSave,
diff --git a/lib/utilities/desktop_password_service.dart b/lib/utilities/desktop_password_service.dart
index 178871e69..24299b855 100644
--- a/lib/utilities/desktop_password_service.dart
+++ b/lib/utilities/desktop_password_service.dart
@@ -89,12 +89,10 @@ class DPS {
   }
 
   Future<bool> hasPassword() async {
-    final box = await Hive.openBox<String>(DB.boxNameDesktopData);
     final keyBlob = DB.instance.get<String>(
       boxName: DB.boxNameDesktopData,
       key: _kKeyBlobKey,
     );
-    await box.close();
     return keyBlob != null;
   }
 }

From b635f1663b6a5699e0a24a73693eca1bc4cf3b34 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 10 Nov 2022 15:07:44 -0600
Subject: [PATCH 203/426] comment out broken code in swb desktop restore +
 clean up unused imports and linter errors in wow/monero tests

---
 .../restore_from_file_view.dart               | 18 +++++-----
 .../coins/monero/monero_wallet_test.dart      | 33 ++++---------------
 .../coins/wownero/wownero_wallet_test.dart    | 29 ++++------------
 3 files changed, 21 insertions(+), 59 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index dbf46c729..ee1fcf666 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -9,7 +9,7 @@ import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
+// import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -49,14 +49,14 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
   bool hidePassword = true;
 
   Future<void> restoreBackupPopup(BuildContext context) async {
-    await showDialog<dynamic>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: true,
-      builder: (context) {
-        return const RestoreBackupDialog();
-      },
-    );
+    // await showDialog<dynamic>(
+    //   context: context,
+    //   useSafeArea: false,
+    //   barrierDismissible: true,
+    //   builder: (context) {
+    //     return const RestoreBackupDialog();
+    //   },
+    // );
   }
 
   @override
diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index 2c755b484..7bbc88ed9 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -1,43 +1,27 @@
-import 'dart:async';
 import 'dart:core';
 import 'dart:core' as core;
 import 'dart:io';
 import 'dart:math';
 
-import 'package:flutter_test/flutter_test.dart';
-import 'package:hive/hive.dart';
-import 'package:hive_test/hive_test.dart';
-import 'package:mockito/annotations.dart';
-import 'package:mockito/mockito.dart';
-
-import 'package:cw_core/monero_amount_format.dart';
 import 'package:cw_core/node.dart';
-import 'package:cw_core/pending_transaction.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:cw_monero/api/wallet.dart';
-import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
-import 'package:cw_monero/pending_monero_transaction.dart';
 import 'package:cw_monero/monero_wallet.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
 import 'package:flutter_libmonero/core/key_service.dart';
 import 'package:flutter_libmonero/core/wallet_creation_service.dart';
-import 'package:flutter_libmonero/view_model/send/output.dart';
 import 'package:flutter_libmonero/monero/monero.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:flutter_test/flutter_test.dart';
 import 'package:hive/hive.dart';
+import 'package:hive_test/hive_test.dart';
+import 'package:mockito/annotations.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
-import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
-
 import 'package:stackwallet/services/wallets.dart';
-
-import 'dart:developer' as developer;
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 // TODO trim down to the minimum imports above
 
@@ -76,12 +60,6 @@ void main() async {
       dirPath: '');
   late WalletCredentials credentials;
 
-  WidgetsFlutterBinding.ensureInitialized();
-  Directory appDir = (await getApplicationDocumentsDirectory());
-  if (Platform.isIOS) {
-    appDir = (await getLibraryDirectory());
-  }
-
   monero.onStartup();
 
   bool hiveAdaptersRegistered = false;
@@ -101,7 +79,8 @@ void main() async {
         await wallets.put('currentWalletName', name);
 
         _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-        walletService = monero.createMoneroWalletService(_walletInfoSource);
+        walletService = monero
+            .createMoneroWalletService(_walletInfoSource as Box<WalletInfo>);
       }
 
       try {
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 87229a63a..c58654b4b 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -1,38 +1,26 @@
-import 'dart:async';
 import 'dart:core';
 import 'dart:core' as core;
 import 'dart:io';
 import 'dart:math';
 
-import 'package:flutter_test/flutter_test.dart';
-import 'package:hive/hive.dart';
-import 'package:hive_test/hive_test.dart';
-import 'package:mockito/annotations.dart';
-import 'package:mockito/mockito.dart';
-
-import 'package:cw_core/monero_amount_format.dart';
 import 'package:cw_core/node.dart';
-import 'package:cw_core/pending_transaction.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:cw_wownero/api/wallet.dart';
-import 'package:cw_wownero/pending_wownero_transaction.dart';
 import 'package:cw_wownero/wownero_wallet.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
 import 'package:flutter_libmonero/core/key_service.dart';
 import 'package:flutter_libmonero/core/wallet_creation_service.dart';
-import 'package:flutter_libmonero/view_model/send/output.dart';
 import 'package:flutter_libmonero/wownero/wownero.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
-import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
+import 'package:flutter_test/flutter_test.dart';
 import 'package:hive/hive.dart';
+import 'package:hive_test/hive_test.dart';
+import 'package:mockito/annotations.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 import 'wownero_wallet_test_data.dart';
 
@@ -67,12 +55,6 @@ void main() async {
       dirPath: '');
   late WalletCredentials credentials;
 
-  WidgetsFlutterBinding.ensureInitialized();
-  Directory appDir = (await getApplicationDocumentsDirectory());
-  if (Platform.isIOS) {
-    appDir = (await getLibraryDirectory());
-  }
-
   wownero.onStartup();
 
   bool hiveAdaptersRegistered = false;
@@ -92,7 +74,8 @@ void main() async {
         await wallets.put('currentWalletName', name);
 
         _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-        walletService = wownero.createWowneroWalletService(_walletInfoSource);
+        walletService = wownero
+            .createWowneroWalletService(_walletInfoSource as Box<WalletInfo>);
       }
 
       bool hasThrown = false;

From 3299f4ecd910c43e291bda713859db71d530615f Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 10 Nov 2022 15:07:44 -0600
Subject: [PATCH 204/426] comment out broken code in swb desktop restore +
 clean up unused imports and linter errors in wow/monero tests

---
 .../coins/monero/monero_wallet_test.dart      | 57 ++++++++-----------
 .../coins/wownero/wownero_wallet_test.dart    | 53 ++++++++---------
 2 files changed, 46 insertions(+), 64 deletions(-)

diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index d54959ab2..7bbc88ed9 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -1,43 +1,27 @@
-import 'dart:async';
 import 'dart:core';
 import 'dart:core' as core;
 import 'dart:io';
 import 'dart:math';
 
-import 'package:flutter_test/flutter_test.dart';
-import 'package:hive/hive.dart';
-import 'package:hive_test/hive_test.dart';
-import 'package:mockito/annotations.dart';
-import 'package:mockito/mockito.dart';
-
-import 'package:cw_core/monero_amount_format.dart';
 import 'package:cw_core/node.dart';
-import 'package:cw_core/pending_transaction.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:cw_monero/api/wallet.dart';
-import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
-import 'package:cw_monero/pending_monero_transaction.dart';
 import 'package:cw_monero/monero_wallet.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
 import 'package:flutter_libmonero/core/key_service.dart';
 import 'package:flutter_libmonero/core/wallet_creation_service.dart';
-import 'package:flutter_libmonero/view_model/send/output.dart';
 import 'package:flutter_libmonero/monero/monero.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:flutter_test/flutter_test.dart';
 import 'package:hive/hive.dart';
+import 'package:hive_test/hive_test.dart';
+import 'package:mockito/annotations.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
-import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
-
 import 'package:stackwallet/services/wallets.dart';
-
-import 'dart:developer' as developer;
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 // TODO trim down to the minimum imports above
 
@@ -76,24 +60,29 @@ void main() async {
       dirPath: '');
   late WalletCredentials credentials;
 
-  WidgetsFlutterBinding.ensureInitialized();
-  Directory appDir = (await getApplicationDocumentsDirectory());
-  if (Platform.isIOS) {
-    appDir = (await getLibraryDirectory());
-  }
-  await Hive.close();
-  Hive.init(appDir.path);
-  Hive.registerAdapter(NodeAdapter());
-  Hive.registerAdapter(WalletInfoAdapter());
-  Hive.registerAdapter(WalletTypeAdapter());
-  Hive.registerAdapter(UnspentCoinsInfoAdapter());
-
   monero.onStartup();
-  _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-  walletService = monero.createMoneroWalletService(_walletInfoSource);
+
+  bool hiveAdaptersRegistered = false;
 
   group("Mainnet tests", () {
     setUp(() async {
+      await setUpTestHive();
+      if (!hiveAdaptersRegistered) {
+        hiveAdaptersRegistered = true;
+
+        Hive.registerAdapter(NodeAdapter());
+        Hive.registerAdapter(WalletInfoAdapter());
+        Hive.registerAdapter(WalletTypeAdapter());
+        Hive.registerAdapter(UnspentCoinsInfoAdapter());
+
+        final wallets = await Hive.openBox('wallets');
+        await wallets.put('currentWalletName', name);
+
+        _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
+        walletService = monero
+            .createMoneroWalletService(_walletInfoSource as Box<WalletInfo>);
+      }
+
       try {
         // if (name?.isEmpty ?? true) {
         // name = await generateName();
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 660bc1438..c58654b4b 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -1,38 +1,26 @@
-import 'dart:async';
 import 'dart:core';
 import 'dart:core' as core;
 import 'dart:io';
 import 'dart:math';
 
-import 'package:flutter_test/flutter_test.dart';
-import 'package:hive/hive.dart';
-import 'package:hive_test/hive_test.dart';
-import 'package:mockito/annotations.dart';
-import 'package:mockito/mockito.dart';
-
-import 'package:cw_core/monero_amount_format.dart';
 import 'package:cw_core/node.dart';
-import 'package:cw_core/pending_transaction.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:cw_wownero/api/wallet.dart';
-import 'package:cw_wownero/pending_wownero_transaction.dart';
 import 'package:cw_wownero/wownero_wallet.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
 import 'package:flutter_libmonero/core/key_service.dart';
 import 'package:flutter_libmonero/core/wallet_creation_service.dart';
-import 'package:flutter_libmonero/view_model/send/output.dart';
 import 'package:flutter_libmonero/wownero/wownero.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
-import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
+import 'package:flutter_test/flutter_test.dart';
 import 'package:hive/hive.dart';
+import 'package:hive_test/hive_test.dart';
+import 'package:mockito/annotations.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 import 'wownero_wallet_test_data.dart';
 
@@ -67,24 +55,29 @@ void main() async {
       dirPath: '');
   late WalletCredentials credentials;
 
-  WidgetsFlutterBinding.ensureInitialized();
-  Directory appDir = (await getApplicationDocumentsDirectory());
-  if (Platform.isIOS) {
-    appDir = (await getLibraryDirectory());
-  }
-  await Hive.close();
-  Hive.init(appDir.path);
-  Hive.registerAdapter(NodeAdapter());
-  Hive.registerAdapter(WalletInfoAdapter());
-  Hive.registerAdapter(WalletTypeAdapter());
-  Hive.registerAdapter(UnspentCoinsInfoAdapter());
-
   wownero.onStartup();
-  _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-  walletService = wownero.createWowneroWalletService(_walletInfoSource);
+
+  bool hiveAdaptersRegistered = false;
 
   group("Wownero 14 word seed generation", () {
     setUp(() async {
+      await setUpTestHive();
+      if (!hiveAdaptersRegistered) {
+        hiveAdaptersRegistered = true;
+
+        Hive.registerAdapter(NodeAdapter());
+        Hive.registerAdapter(WalletInfoAdapter());
+        Hive.registerAdapter(WalletTypeAdapter());
+        Hive.registerAdapter(UnspentCoinsInfoAdapter());
+
+        final wallets = await Hive.openBox('wallets');
+        await wallets.put('currentWalletName', name);
+
+        _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
+        walletService = wownero
+            .createWowneroWalletService(_walletInfoSource as Box<WalletInfo>);
+      }
+
       bool hasThrown = false;
       try {
         name = 'namee${Random().nextInt(10000000)}';

From 7105deeb24b49800d98527cf403e0cca224c5eec Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 10 Nov 2022 15:40:23 -0600
Subject: [PATCH 205/426] initialize isar instance correctly for desktop secure
 wrapper

---
 .../desktop_login_view.dart                   |  4 ++++
 .../flutter_secure_storage_interface.dart     | 21 ++++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index d90e742fb..93a281bf8 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -7,9 +7,11 @@ import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages_desktop_specific/forgot_password_desktop_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.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';
@@ -47,6 +49,8 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
           .read(storageCryptoHandlerProvider)
           .initFromExisting(passwordController.text);
 
+      await (ref.read(secureStoreProvider).store as DesktopSecureStore).init();
+
       await widget.load?.call();
 
       // if no errors passphrase is correct
diff --git a/lib/utilities/flutter_secure_storage_interface.dart b/lib/utilities/flutter_secure_storage_interface.dart
index 852c13f3d..9e8aef95c 100644
--- a/lib/utilities/flutter_secure_storage_interface.dart
+++ b/lib/utilities/flutter_secure_storage_interface.dart
@@ -6,6 +6,8 @@ import 'package:stack_wallet_backup/secure_storage.dart';
 import 'package:stackwallet/models/isar/models/encrypted_string_value.dart';
 
 abstract class SecureStorageInterface {
+  dynamic get store;
+
   Future<void> write({
     required String key,
     required String? value,
@@ -54,6 +56,7 @@ class DesktopSecureStore {
       [EncryptedStringValueSchema],
       directory: appDirectory!.path,
       inspector: false,
+      name: "desktopStore",
     );
   }
 
@@ -77,7 +80,9 @@ class DesktopSecureStore {
   }) async {
     if (value == null) {
       // here we assume that a value is to be deleted
-      await isar.encryptedStringValues.deleteByKey(key);
+      await isar.writeTxn(() async {
+        await isar.encryptedStringValues.deleteByKey(key);
+      });
     } else {
       // otherwise created encrypted object value
       final object = EncryptedStringValue();
@@ -85,14 +90,18 @@ class DesktopSecureStore {
       object.value = await handler.encryptValue(key, value);
 
       // store object value
-      await isar.encryptedStringValues.put(object);
+      await isar.writeTxn(() async {
+        await isar.encryptedStringValues.put(object);
+      });
     }
   }
 
   Future<void> delete({
     required String key,
   }) async {
-    await isar.encryptedStringValues.deleteByKey(key);
+    await isar.writeTxn(() async {
+      await isar.encryptedStringValues.deleteByKey(key);
+    });
   }
 }
 
@@ -101,6 +110,9 @@ class SecureStorageWrapper implements SecureStorageInterface {
   final dynamic _store;
   final bool _isDesktop;
 
+  @override
+  dynamic get store => _store;
+
   const SecureStorageWrapper({
     required dynamic store,
     required bool isDesktop,
@@ -245,4 +257,7 @@ class FakeSecureStorage implements SecureStorageInterface {
     _deletes++;
     _store.remove(key);
   }
+
+  @override
+  dynamic get store => throw UnimplementedError();
 }

From 24bdc100fb479843132f8f6e577f69cf62341323 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 10 Nov 2022 15:49:19 -0600
Subject: [PATCH 206/426] add address validation tests

---
 crypto_plugins/flutter_libmonero              |  2 +-
 .../coins/monero/monero_wallet_test.dart      | 22 ++++++++++++++++++-
 .../coins/wownero/wownero_wallet_test.dart    | 12 ++++++++++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index 8a8c88cda..2da774385 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit 8a8c88cdade6fe18529deea410f862b125167a3b
+Subproject commit 2da77438527732dfaa5398aa391eab5253dabe19
diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index d54959ab2..4c4daa9ac 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -92,7 +92,7 @@ void main() async {
   _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
   walletService = monero.createMoneroWalletService(_walletInfoSource);
 
-  group("Mainnet tests", () {
+  group("Mnemonic recovery", () {
     setUp(() async {
       try {
         // if (name?.isEmpty ?? true) {
@@ -133,6 +133,26 @@ void main() async {
       }
     });
 
+    test("Test address validation", () async { // TODO I'd like to refactor/separate this out so I can test addresses alone, without having to first create a wallet.
+      final wallet = await _walletCreationService.restoreFromSeed(credentials);
+      walletBase = wallet as MoneroWalletBase;
+
+      expect(
+          await walletBase!.validateAddress(''), false);
+      expect(
+          await walletBase!.validateAddress('4AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), true);
+      expect(
+          await walletBase!.validateAddress('4asdfkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gpjkl'), false);
+      expect(
+          await walletBase!.validateAddress('8AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), false);
+      expect(
+          await walletBase!.validateAddress('84kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), true);
+      expect(
+          await walletBase!.validateAddress('8asdfuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenjkl'), false);
+      expect(
+          await walletBase!.validateAddress('44kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), false);
+    });
+
     test("Test mainnet address generation from seed", () async {
       final wallet = await
           // _walletCreationService.create(credentials);
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 660bc1438..8daa91755 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -122,6 +122,18 @@ void main() async {
       expect(hasThrown, false);
     });
 
+    test("Test address validation", () async { // TODO I'd like to refactor/separate this out so I can test addresses alone, without having to first create a wallet.
+      final wallet = await _walletCreationService.restoreFromSeed(credentials);
+      walletBase = wallet as WowneroWalletBase;
+
+      expect(
+          await walletBase!.validateAddress(''), false);
+      expect(
+          await walletBase!.validateAddress('Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi'), true);
+      expect(
+          await walletBase!.validateAddress('WasdfHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmjkl'), false);
+    });
+
     test("Wownero 14 word seed address generation", () async {
       final wallet = await _walletCreationService.create(credentials);
       // TODO validate mnemonic

From 5f106efa4bbd541561f2edd1e85275ff000f66f9 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 10 Nov 2022 15:11:17 -0700
Subject: [PATCH 207/426] desktop edit auto backup and enabled/disabled button

---
 assets/svg/enabled-button.svg                 |  4 ++
 .../backup_and_restore_settings.dart          | 66 ++++++++++++++-----
 .../create_auto_backup.dart                   |  4 +-
 lib/utilities/assets.dart                     |  1 +
 pubspec.yaml                                  |  1 +
 5 files changed, 59 insertions(+), 17 deletions(-)
 create mode 100644 assets/svg/enabled-button.svg

diff --git a/assets/svg/enabled-button.svg b/assets/svg/enabled-button.svg
new file mode 100644
index 000000000..a26359e81
--- /dev/null
+++ b/assets/svg/enabled-button.svg
@@ -0,0 +1,4 @@
+<svg width="87" height="38" viewBox="0 0 87 38" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect y="0.5" width="87" height="37" rx="8" fill="#B9E9D4"/>
+<path d="M17.6167 24.5V14.3182H24.0002V15.6406H19.1529V18.7429H23.6671V20.0604H19.1529V23.1776H24.0598V24.5H17.6167ZM27.4194 19.9659V24.5H25.9329V16.8636H27.3597V18.1065H27.4542C27.6299 17.7022 27.9049 17.3774 28.2795 17.1321C28.6573 16.8868 29.1329 16.7642 29.7063 16.7642C30.2267 16.7642 30.6824 16.8736 31.0735 17.0923C31.4646 17.3078 31.7679 17.6293 31.9833 18.0568C32.1987 18.4844 32.3065 19.013 32.3065 19.6428V24.5H30.82V19.8217C30.82 19.2682 30.6758 18.8357 30.3874 18.5241C30.0991 18.2093 29.703 18.0518 29.1992 18.0518C28.8545 18.0518 28.5479 18.1264 28.2795 18.2756C28.0143 18.4247 27.8039 18.6435 27.6481 18.9318C27.4956 19.2169 27.4194 19.5616 27.4194 19.9659ZM36.5224 24.669C36.0385 24.669 35.601 24.5795 35.2099 24.4006C34.8188 24.2183 34.5089 23.9548 34.2802 23.6101C34.0548 23.2654 33.9421 22.8428 33.9421 22.3423C33.9421 21.9115 34.025 21.5568 34.1907 21.2784C34.3564 21 34.5801 20.7796 34.8619 20.6172C35.1436 20.4548 35.4585 20.3321 35.8065 20.2493C36.1545 20.1664 36.5091 20.1035 36.8704 20.0604C37.3278 20.0073 37.699 19.9643 37.984 19.9311C38.2691 19.8946 38.4762 19.8366 38.6055 19.7571C38.7347 19.6776 38.7994 19.5483 38.7994 19.3693V19.3345C38.7994 18.9003 38.6767 18.5639 38.4315 18.3253C38.1895 18.0866 37.8282 17.9673 37.3477 17.9673C36.8472 17.9673 36.4528 18.0784 36.1644 18.3004C35.8794 18.5192 35.6822 18.7628 35.5728 19.0312L34.1758 18.7131C34.3415 18.2491 34.5835 17.8745 34.9016 17.5895C35.2231 17.3011 35.5927 17.0923 36.0103 16.9631C36.4279 16.8305 36.8671 16.7642 37.3278 16.7642C37.6327 16.7642 37.9558 16.8007 38.2972 16.8736C38.6419 16.9432 38.9634 17.0724 39.2617 17.2614C39.5633 17.4503 39.8103 17.7204 40.0025 18.0717C40.1947 18.4197 40.2908 18.8722 40.2908 19.429V24.5H38.8391V23.456H38.7795C38.6834 23.6482 38.5392 23.8371 38.3469 24.0227C38.1547 24.2083 37.9078 24.3625 37.6062 24.4851C37.3046 24.6077 36.9433 24.669 36.5224 24.669ZM36.8455 23.4759C37.2565 23.4759 37.6078 23.3946 37.8995 23.2322C38.1945 23.0698 38.4182 22.8577 38.5707 22.5959C38.7264 22.3307 38.8043 22.0473 38.8043 21.7457V20.7614C38.7513 20.8144 38.6486 20.8641 38.4961 20.9105C38.3469 20.9536 38.1763 20.9917 37.984 21.0249C37.7918 21.0547 37.6045 21.0829 37.4222 21.1094C37.2399 21.1326 37.0875 21.1525 36.9648 21.169C36.6765 21.2055 36.413 21.2668 36.1744 21.353C35.939 21.4392 35.7501 21.5634 35.6076 21.7259C35.4684 21.8849 35.3988 22.0971 35.3988 22.3622C35.3988 22.7301 35.5347 23.0085 35.8065 23.1974C36.0782 23.383 36.4246 23.4759 36.8455 23.4759ZM42.3901 24.5V14.3182H43.8766V18.1016H43.9661C44.0523 17.9425 44.1766 17.7585 44.339 17.5497C44.5014 17.3409 44.7267 17.1586 45.0151 17.0028C45.3034 16.8438 45.6846 16.7642 46.1586 16.7642C46.775 16.7642 47.3252 16.92 47.8091 17.2315C48.293 17.5431 48.6725 17.9922 48.9476 18.5788C49.226 19.1655 49.3652 19.8714 49.3652 20.6967C49.3652 21.522 49.2277 22.2296 48.9526 22.8196C48.6775 23.4062 48.2997 23.8587 47.8191 24.1768C47.3385 24.4917 46.79 24.6491 46.1735 24.6491C45.7095 24.6491 45.33 24.5713 45.035 24.4155C44.7433 24.2597 44.5146 24.0774 44.3489 23.8686C44.1832 23.6598 44.0556 23.4742 43.9661 23.3118H43.8418V24.5H42.3901ZM43.8468 20.6818C43.8468 21.2187 43.9247 21.6894 44.0804 22.0938C44.2362 22.4981 44.4616 22.8146 44.7566 23.0433C45.0516 23.2687 45.4128 23.3814 45.8404 23.3814C46.2845 23.3814 46.6557 23.2637 46.954 23.0284C47.2523 22.7898 47.4777 22.4666 47.6301 22.0589C47.7859 21.6513 47.8638 21.1922 47.8638 20.6818C47.8638 20.178 47.7876 19.7256 47.6351 19.3246C47.486 18.9235 47.2606 18.607 46.959 18.375C46.6607 18.143 46.2878 18.027 45.8404 18.027C45.4095 18.027 45.0449 18.138 44.7466 18.3601C44.4516 18.5821 44.2279 18.892 44.0755 19.2898C43.923 19.6875 43.8468 20.1515 43.8468 20.6818ZM52.521 14.3182V24.5H51.0344V14.3182H52.521ZM57.812 24.6541C57.0596 24.6541 56.4116 24.4934 55.8681 24.1719C55.3278 23.8471 54.9102 23.3913 54.6152 22.8047C54.3236 22.2147 54.1777 21.5237 54.1777 20.7315C54.1777 19.9493 54.3236 19.2599 54.6152 18.6634C54.9102 18.0668 55.3212 17.6011 55.8482 17.2663C56.3785 16.9316 56.9983 16.7642 57.7076 16.7642C58.1384 16.7642 58.556 16.8355 58.9604 16.978C59.3648 17.1205 59.7277 17.3442 60.0492 17.6491C60.3707 17.9541 60.6242 18.3501 60.8098 18.8374C60.9954 19.3213 61.0882 19.9096 61.0882 20.6023V21.1293H55.0179V20.0156H59.6316C59.6316 19.6245 59.552 19.2782 59.3929 18.9766C59.2338 18.6716 59.0101 18.4313 58.7218 18.2557C58.4367 18.08 58.102 17.9922 57.7175 17.9922C57.2999 17.9922 56.9353 18.0949 56.6238 18.3004C56.3155 18.5026 56.0769 18.7678 55.9078 19.0959C55.7421 19.4207 55.6593 19.7737 55.6593 20.1548V21.0249C55.6593 21.5353 55.7488 21.9695 55.9277 22.3274C56.11 22.6854 56.3636 22.9588 56.6884 23.1477C57.0132 23.3333 57.3927 23.4261 57.8269 23.4261C58.1086 23.4261 58.3655 23.3864 58.5975 23.3068C58.8295 23.224 59.03 23.1013 59.199 22.9389C59.3681 22.7765 59.4973 22.576 59.5868 22.3374L60.9938 22.5909C60.8811 23.0052 60.6789 23.3681 60.3873 23.6797C60.0989 23.9879 59.736 24.2282 59.2985 24.4006C58.8643 24.5696 58.3688 24.6541 57.812 24.6541ZM65.5962 24.6491C64.9798 24.6491 64.4296 24.4917 63.9457 24.1768C63.4651 23.8587 63.0872 23.4062 62.8121 22.8196C62.5404 22.2296 62.4045 21.522 62.4045 20.6967C62.4045 19.8714 62.542 19.1655 62.8171 18.5788C63.0955 17.9922 63.4767 17.5431 63.9606 17.2315C64.4445 16.92 64.993 16.7642 65.6062 16.7642C66.0801 16.7642 66.4613 16.8438 66.7496 17.0028C67.0413 17.1586 67.2667 17.3409 67.4258 17.5497C67.5882 17.7585 67.7141 17.9425 67.8036 18.1016H67.8931V14.3182H69.3796V24.5H67.9279V23.3118H67.8036C67.7141 23.4742 67.5849 23.6598 67.4158 23.8686C67.2501 24.0774 67.0214 24.2597 66.7298 24.4155C66.4381 24.5713 66.0603 24.6491 65.5962 24.6491ZM65.9244 23.3814C66.3519 23.3814 66.7132 23.2687 67.0082 23.0433C67.3065 22.8146 67.5318 22.4981 67.6843 22.0938C67.8401 21.6894 67.918 21.2187 67.918 20.6818C67.918 20.1515 67.8417 19.6875 67.6893 19.2898C67.5368 18.892 67.3131 18.5821 67.0181 18.3601C66.7231 18.138 66.3585 18.027 65.9244 18.027C65.4769 18.027 65.104 18.143 64.8058 18.375C64.5075 18.607 64.2821 18.9235 64.1296 19.3246C63.9805 19.7256 63.9059 20.178 63.9059 20.6818C63.9059 21.1922 63.9821 21.6513 64.1346 22.0589C64.2871 22.4666 64.5124 22.7898 64.8107 23.0284C65.1123 23.2637 65.4835 23.3814 65.9244 23.3814Z" fill="#232323"/>
+</svg>
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index a444f4b51..3ea6cea6c 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -5,6 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart';
 import 'package:intl/intl.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart';
 import 'package:stackwallet/providers/global/locale_provider.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
@@ -36,7 +37,6 @@ class BackupRestoreSettings extends ConsumerStatefulWidget {
 class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
   late bool createBackup = false;
   late bool restoreBackup = false;
-  // late bool isEnabledAutoBackup;
 
   final toggleController = DSBController();
 
@@ -91,6 +91,17 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
     );
   }
 
+  Future<void> createAutoBackup() async {
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) {
+        return CreateAutoBackup();
+      },
+    );
+  }
+
   Future<void> attemptDisable() async {
     final result = await showDialog<bool?>(
       context: context,
@@ -208,10 +219,25 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                       child: Column(
                         crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
-                          SvgPicture.asset(
-                            Assets.svg.backupAuto,
-                            width: 48,
-                            height: 48,
+                          Padding(
+                            padding: const EdgeInsets.all(8.0),
+                            child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              children: [
+                                SvgPicture.asset(
+                                  Assets.svg.backupAuto,
+                                  width: 48,
+                                  height: 48,
+                                ),
+                                isEnabledAutoBackup
+                                    ? SvgPicture.asset(
+                                        Assets.svg.enableButton,
+                                      )
+                                    : SvgPicture.asset(
+                                        Assets.svg.disableButton,
+                                      ),
+                              ],
+                            ),
                           ),
                           Center(
                             child: Row(
@@ -338,7 +364,9 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                                 desktopMed: true,
                                                 width: 190,
                                                 label: "Edit auto backup",
-                                                onPressed: () {},
+                                                onPressed: () {
+                                                  createAutoBackup();
+                                                },
                                               ),
                                             ],
                                           )
@@ -362,11 +390,14 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                       child: Column(
                         crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
-                          SvgPicture.asset(
-                            Assets.svg.backupAdd,
-                            width: 48,
-                            height: 48,
-                            alignment: Alignment.topLeft,
+                          Padding(
+                            padding: const EdgeInsets.all(8.0),
+                            child: SvgPicture.asset(
+                              Assets.svg.backupAdd,
+                              width: 48,
+                              height: 48,
+                              alignment: Alignment.topLeft,
+                            ),
                           ),
                           Center(
                             child: Row(
@@ -441,11 +472,14 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                       child: Column(
                         crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
-                          SvgPicture.asset(
-                            Assets.svg.backupRestore,
-                            width: 48,
-                            height: 48,
-                            alignment: Alignment.topLeft,
+                          Padding(
+                            padding: const EdgeInsets.all(8.0),
+                            child: SvgPicture.asset(
+                              Assets.svg.backupRestore,
+                              width: 48,
+                              height: 48,
+                              alignment: Alignment.topLeft,
+                            ),
                           ),
                           Center(
                             child: Row(
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index e804071cc..acd0e689c 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -578,7 +578,9 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                     label: "Cancel",
                     onPressed: () {
                       int count = 0;
-                      Navigator.of(context).popUntil((_) => count++ >= 2);
+                      !isEnabledAutoBackup
+                          ? Navigator.of(context).popUntil((_) => count++ >= 2)
+                          : Navigator.of(context).pop();
                     },
                   ),
                 ),
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index b0c6b3bf9..f853a00d8 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -69,6 +69,7 @@ class _SVG {
   String get circleLanguage => "assets/svg/language-circle.svg";
   String get circleDollarSign => "assets/svg/dollar-sign-circle.svg";
   String get circleLock => "assets/svg/lock-circle.svg";
+  String get enableButton => "assets/svg/enabled-button.svg";
   String get disableButton => "assets/svg/Button.svg";
   String get polygon => "assets/svg/Polygon.svg";
   String get personaIncognito => "assets/svg/persona-incognito-1.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index 19d38ca4f..8b03cd57e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -298,6 +298,7 @@ flutter:
     - assets/svg/persona-easy-1.svg
     - assets/svg/persona-incognito-1.svg
     - assets/svg/Button.svg
+    - assets/svg/enabled-button.svg
     - assets/svg/lock-circle.svg
     - assets/svg/dollar-sign-circle.svg
     - assets/svg/language-circle.svg

From a6172f90a9e5024aad844be63e8952bdf98ae07d Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 10 Nov 2022 16:21:58 -0600
Subject: [PATCH 208/426] cherrypick Julian's test changes

---
 .../coins/monero/monero_wallet_test.dart      | 57 ++++++++-----------
 .../coins/wownero/wownero_wallet_test.dart    | 53 ++++++++---------
 2 files changed, 46 insertions(+), 64 deletions(-)

diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index 4c4daa9ac..34024640f 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -1,43 +1,27 @@
-import 'dart:async';
 import 'dart:core';
 import 'dart:core' as core;
 import 'dart:io';
 import 'dart:math';
 
-import 'package:flutter_test/flutter_test.dart';
-import 'package:hive/hive.dart';
-import 'package:hive_test/hive_test.dart';
-import 'package:mockito/annotations.dart';
-import 'package:mockito/mockito.dart';
-
-import 'package:cw_core/monero_amount_format.dart';
 import 'package:cw_core/node.dart';
-import 'package:cw_core/pending_transaction.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:cw_monero/api/wallet.dart';
-import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
-import 'package:cw_monero/pending_monero_transaction.dart';
 import 'package:cw_monero/monero_wallet.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
 import 'package:flutter_libmonero/core/key_service.dart';
 import 'package:flutter_libmonero/core/wallet_creation_service.dart';
-import 'package:flutter_libmonero/view_model/send/output.dart';
 import 'package:flutter_libmonero/monero/monero.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:flutter_test/flutter_test.dart';
 import 'package:hive/hive.dart';
+import 'package:hive_test/hive_test.dart';
+import 'package:mockito/annotations.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
-import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
-
 import 'package:stackwallet/services/wallets.dart';
-
-import 'dart:developer' as developer;
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 // TODO trim down to the minimum imports above
 
@@ -76,24 +60,29 @@ void main() async {
       dirPath: '');
   late WalletCredentials credentials;
 
-  WidgetsFlutterBinding.ensureInitialized();
-  Directory appDir = (await getApplicationDocumentsDirectory());
-  if (Platform.isIOS) {
-    appDir = (await getLibraryDirectory());
-  }
-  await Hive.close();
-  Hive.init(appDir.path);
-  Hive.registerAdapter(NodeAdapter());
-  Hive.registerAdapter(WalletInfoAdapter());
-  Hive.registerAdapter(WalletTypeAdapter());
-  Hive.registerAdapter(UnspentCoinsInfoAdapter());
-
   monero.onStartup();
-  _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-  walletService = monero.createMoneroWalletService(_walletInfoSource);
+
+  bool hiveAdaptersRegistered = false;
 
   group("Mnemonic recovery", () {
     setUp(() async {
+      await setUpTestHive();
+      if (!hiveAdaptersRegistered) {
+        hiveAdaptersRegistered = true;
+
+        Hive.registerAdapter(NodeAdapter());
+        Hive.registerAdapter(WalletInfoAdapter());
+        Hive.registerAdapter(WalletTypeAdapter());
+        Hive.registerAdapter(UnspentCoinsInfoAdapter());
+
+        final wallets = await Hive.openBox('wallets');
+        await wallets.put('currentWalletName', name);
+
+        _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
+        walletService = monero
+            .createMoneroWalletService(_walletInfoSource as Box<WalletInfo>);
+      }
+
       try {
         // if (name?.isEmpty ?? true) {
         // name = await generateName();
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 8daa91755..8ad730e13 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -1,38 +1,26 @@
-import 'dart:async';
 import 'dart:core';
 import 'dart:core' as core;
 import 'dart:io';
 import 'dart:math';
 
-import 'package:flutter_test/flutter_test.dart';
-import 'package:hive/hive.dart';
-import 'package:hive_test/hive_test.dart';
-import 'package:mockito/annotations.dart';
-import 'package:mockito/mockito.dart';
-
-import 'package:cw_core/monero_amount_format.dart';
 import 'package:cw_core/node.dart';
-import 'package:cw_core/pending_transaction.dart';
 import 'package:cw_core/unspent_coins_info.dart';
 import 'package:cw_core/wallet_base.dart';
 import 'package:cw_core/wallet_credentials.dart';
 import 'package:cw_core/wallet_info.dart';
 import 'package:cw_core/wallet_service.dart';
 import 'package:cw_core/wallet_type.dart';
-import 'package:cw_wownero/api/wallet.dart';
-import 'package:cw_wownero/pending_wownero_transaction.dart';
 import 'package:cw_wownero/wownero_wallet.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
 import 'package:flutter_libmonero/core/key_service.dart';
 import 'package:flutter_libmonero/core/wallet_creation_service.dart';
-import 'package:flutter_libmonero/view_model/send/output.dart';
 import 'package:flutter_libmonero/wownero/wownero.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
-import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
+import 'package:flutter_test/flutter_test.dart';
 import 'package:hive/hive.dart';
+import 'package:hive_test/hive_test.dart';
+import 'package:mockito/annotations.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 import 'wownero_wallet_test_data.dart';
 
@@ -67,24 +55,29 @@ void main() async {
       dirPath: '');
   late WalletCredentials credentials;
 
-  WidgetsFlutterBinding.ensureInitialized();
-  Directory appDir = (await getApplicationDocumentsDirectory());
-  if (Platform.isIOS) {
-    appDir = (await getLibraryDirectory());
-  }
-  await Hive.close();
-  Hive.init(appDir.path);
-  Hive.registerAdapter(NodeAdapter());
-  Hive.registerAdapter(WalletInfoAdapter());
-  Hive.registerAdapter(WalletTypeAdapter());
-  Hive.registerAdapter(UnspentCoinsInfoAdapter());
-
   wownero.onStartup();
-  _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-  walletService = wownero.createWowneroWalletService(_walletInfoSource);
+
+  bool hiveAdaptersRegistered = false;
 
   group("Wownero 14 word seed generation", () {
     setUp(() async {
+      await setUpTestHive();
+      if (!hiveAdaptersRegistered) {
+        hiveAdaptersRegistered = true;
+
+        Hive.registerAdapter(NodeAdapter());
+        Hive.registerAdapter(WalletInfoAdapter());
+        Hive.registerAdapter(WalletTypeAdapter());
+        Hive.registerAdapter(UnspentCoinsInfoAdapter());
+
+        final wallets = await Hive.openBox('wallets');
+        await wallets.put('currentWalletName', name);
+
+        _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
+        walletService = wownero
+            .createWowneroWalletService(_walletInfoSource as Box<WalletInfo>);
+      }
+
       bool hasThrown = false;
       try {
         name = 'namee${Random().nextInt(10000000)}';

From f61b3857e6e40a45683f2233a34eb6f2087a2463 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Thu, 10 Nov 2022 17:03:01 -0600
Subject: [PATCH 209/426] add more address validation to tests

---
 .../coins/monero/monero_wallet_test.dart      | 69 ++++++++-----------
 .../coins/wownero/wownero_wallet_test.dart    | 35 ++++------
 2 files changed, 43 insertions(+), 61 deletions(-)

diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index 6b134f302..79bf98a41 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -60,19 +60,11 @@ void main() async {
       dirPath: '');
   late WalletCredentials credentials;
 
-  WidgetsFlutterBinding.ensureInitialized();
-  Directory appDir = (await getApplicationDocumentsDirectory());
-  if (Platform.isIOS) {
-    appDir = (await getLibraryDirectory());
-  }
-
   monero.onStartup();
 
   bool hiveAdaptersRegistered = false;
 
-  bool hiveAdaptersRegistered = false;
-
-  group("Mnemonic recovery", () {
+  group("Mainnet tests", () {
     setUp(() async {
       await setUpTestHive();
       if (!hiveAdaptersRegistered) {
@@ -87,7 +79,8 @@ void main() async {
         await wallets.put('currentWalletName', name);
 
         _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-        walletService = monero.createMoneroWalletService(_walletInfoSource);
+        walletService = monero
+            .createMoneroWalletService(_walletInfoSource as Box<WalletInfo>);
       }
 
       try {
@@ -97,12 +90,12 @@ void main() async {
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
         credentials =
-            // //     creating a new wallet
-            // monero.createMoneroNewWalletCredentials(
-            //     name: name, language: "English");
-            // restoring a previous wallet
-            monero.createMoneroRestoreWalletFromSeedCredentials(
-                name: name, height: 2580000, mnemonic: testMnemonic);
+        // //     creating a new wallet
+        // monero.createMoneroNewWalletCredentials(
+        //     name: name, language: "English");
+        // restoring a previous wallet
+        monero.createMoneroRestoreWalletFromSeedCredentials(
+            name: name, height: 2580000, mnemonic: testMnemonic);
 
         walletInfo = WalletInfo.external(
             id: WalletBase.idFor(name, type),
@@ -129,30 +122,10 @@ void main() async {
       }
     });
 
-    test("Test address validation", () async { // TODO I'd like to refactor/separate this out so I can test addresses alone, without having to first create a wallet.
-      final wallet = await _walletCreationService.restoreFromSeed(credentials);
-      walletBase = wallet as MoneroWalletBase;
-
-      expect(
-          await walletBase!.validateAddress(''), false);
-      expect(
-          await walletBase!.validateAddress('4AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), true);
-      expect(
-          await walletBase!.validateAddress('4asdfkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gpjkl'), false);
-      expect(
-          await walletBase!.validateAddress('8AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), false);
-      expect(
-          await walletBase!.validateAddress('84kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), true);
-      expect(
-          await walletBase!.validateAddress('8asdfuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenjkl'), false);
-      expect(
-          await walletBase!.validateAddress('44kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), false);
-    });
-
     test("Test mainnet address generation from seed", () async {
       final wallet = await
-          // _walletCreationService.create(credentials);
-          _walletCreationService.restoreFromSeed(credentials);
+      // _walletCreationService.create(credentials);
+      _walletCreationService.restoreFromSeed(credentials);
       walletInfo.address = wallet.walletAddresses.address;
       //print(walletInfo.address);
 
@@ -161,6 +134,9 @@ void main() async {
       walletBase = wallet as MoneroWalletBase;
       //print("${walletBase?.seed}");
 
+      expect(
+          await walletBase!.validateAddress(walletInfo.address ?? ''), true);
+
       // print(walletBase);
       // loggerPrint(walletBase.toString());
       // loggerPrint("name: ${walletBase!.name}  seed: ${walletBase!.seed} id: "
@@ -180,6 +156,21 @@ void main() async {
           await walletBase!.getTransactionAddress(1, 1), mainnetTestData[1][1]);
       expect(
           await walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]);
+
+      expect(
+          await walletBase!.validateAddress(''), false);
+      expect(
+          await walletBase!.validateAddress('4AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), true);
+      expect(
+          await walletBase!.validateAddress('4asdfkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gpjkl'), false);
+      expect(
+          await walletBase!.validateAddress('8AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), false);
+      expect(
+          await walletBase!.validateAddress('84kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), true);
+      expect(
+          await walletBase!.validateAddress('8asdfuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenjkl'), false);
+      expect(
+          await walletBase!.validateAddress('44kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), false);
     });
   });
   /*
@@ -238,6 +229,6 @@ Future<String> pathForWalletDir(
 }
 
 Future<String> pathForWallet(
-        {required String name, required WalletType type}) async =>
+    {required String name, required WalletType type}) async =>
     await pathForWalletDir(name: name, type: type)
         .then((path) => path + '/$name');
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 71c11677a..78a9c56c1 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -55,12 +55,6 @@ void main() async {
       dirPath: '');
   late WalletCredentials credentials;
 
-  WidgetsFlutterBinding.ensureInitialized();
-  Directory appDir = (await getApplicationDocumentsDirectory());
-  if (Platform.isIOS) {
-    appDir = (await getLibraryDirectory());
-  }
-  
   wownero.onStartup();
 
   bool hiveAdaptersRegistered = false;
@@ -80,7 +74,8 @@ void main() async {
         await wallets.put('currentWalletName', name);
 
         _walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
-        walletService = wownero.createWowneroWalletService(_walletInfoSource);
+        walletService = wownero
+            .createWowneroWalletService(_walletInfoSource as Box<WalletInfo>);
       }
 
       bool hasThrown = false;
@@ -120,18 +115,6 @@ void main() async {
       expect(hasThrown, false);
     });
 
-    test("Test address validation", () async { // TODO I'd like to refactor/separate this out so I can test addresses alone, without having to first create a wallet.
-      final wallet = await _walletCreationService.restoreFromSeed(credentials);
-      walletBase = wallet as WowneroWalletBase;
-
-      expect(
-          await walletBase!.validateAddress(''), false);
-      expect(
-          await walletBase!.validateAddress('Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi'), true);
-      expect(
-          await walletBase!.validateAddress('WasdfHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmjkl'), false);
-    });
-
     test("Wownero 14 word seed address generation", () async {
       final wallet = await _walletCreationService.create(credentials);
       // TODO validate mnemonic
@@ -143,13 +126,21 @@ void main() async {
         walletBase?.close();
         walletBase = wallet as WowneroWalletBase;
 
-        // TODO validate
-        //expect(walletInfo.address, mainnetTestData14[0][0]);
+        expect(
+            await walletBase!.validateAddress(wallet.walletAddresses.address ?? ''), true);
       } catch (_) {
         hasThrown = true;
       }
       expect(hasThrown, false);
 
+      // Address validation
+      expect(
+          await walletBase!.validateAddress(''), false);
+      expect(
+          await walletBase!.validateAddress('Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi'), true);
+      expect(
+          await walletBase!.validateAddress('WasdfHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmjkl'), false);
+
       walletBase?.close();
       walletBase = wallet as WowneroWalletBase;
     });
@@ -376,6 +367,6 @@ Future<String> pathForWalletDir(
 }
 
 Future<String> pathForWallet(
-        {required String name, required WalletType type}) async =>
+    {required String name, required WalletType type}) async =>
     await pathForWalletDir(name: name, type: type)
         .then((path) => path + '/$name');

From dac1337a712525727361c3c2bfdbf7698877a2a0 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 10 Nov 2022 17:49:49 -0700
Subject: [PATCH 210/426] WIP: added border to cards; working on cancel restore

---
 .../restore_from_file_view.dart               |  30 +-
 .../stack_restore_progress_view.dart          | 539 +++++++++++++-----
 .../sub_widgets/restoring_wallet_card.dart    | 398 +++++++++----
 3 files changed, 668 insertions(+), 299 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index ee1fcf666..e2d16db54 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -9,7 +9,6 @@ import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart';
-// import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/restore_backup_dialog.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -21,13 +20,14 @@ import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:tuple/tuple.dart';
 
+import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
+
 class RestoreFromFileView extends ConsumerStatefulWidget {
   const RestoreFromFileView({Key? key}) : super(key: key);
 
@@ -48,17 +48,6 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
 
   bool hidePassword = true;
 
-  Future<void> restoreBackupPopup(BuildContext context) async {
-    // await showDialog<dynamic>(
-    //   context: context,
-    //   useSafeArea: false,
-    //   barrierDismissible: true,
-    //   builder: (context) {
-    //     return const RestoreBackupDialog();
-    //   },
-    // );
-  }
-
   @override
   void initState() {
     stackFileSystem = StackFileSystem();
@@ -237,7 +226,7 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                   enableSuggestions: false,
                   autocorrect: false,
                   decoration: standardInputDecoration(
-                    "Enter password",
+                    "Enter passphrase",
                     passwordFocusNode,
                     context,
                   ).copyWith(
@@ -534,7 +523,7 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                                                                     const EdgeInsets
                                                                         .all(32),
                                                                 child: Text(
-                                                                  "Restoring Stack Wallet",
+                                                                  "Restore Stack Wallet",
                                                                   style: STextStyles
                                                                       .desktopH3(
                                                                           context),
@@ -546,12 +535,10 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                                                               const DesktopDialogCloseButton(),
                                                             ],
                                                           ),
-                                                          const SizedBox(
-                                                            height: 30,
-                                                          ),
                                                           Padding(
-                                                            padding: EdgeInsets
-                                                                .symmetric(
+                                                            padding:
+                                                                const EdgeInsets
+                                                                        .symmetric(
                                                                     horizontal:
                                                                         32),
                                                             child:
@@ -560,6 +547,9 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                                                                   jsonString,
                                                             ),
                                                           ),
+                                                          const SizedBox(
+                                                            height: 32,
+                                                          ),
                                                         ],
                                                       ),
                                                     ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
index 7dec4e740..e7c65346f 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
@@ -19,10 +19,13 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 
+import '../../../../../widgets/desktop/primary_button.dart';
+
 class StackRestoreProgressView extends ConsumerStatefulWidget {
   const StackRestoreProgressView({
     Key? key,
@@ -100,6 +103,30 @@ class _StackRestoreProgressViewState
       context: context,
       builder: (_) => const CancelStackRestoreDialog(),
     );
+    // : await Row(
+    //     children: [
+    //       SecondaryButton(
+    //         width: 248,
+    //         desktopMed: true,
+    //         enabled: true,
+    //         label: "Keep restoring",
+    //         onPressed: () {
+    //           false;
+    //         },
+    //       ),
+    //       const SizedBox(width: 16),
+    //       PrimaryButton(
+    //         width: 248,
+    //         desktopMed: true,
+    //         enabled: true,
+    //         label: "Cancel anyway",
+    //         onPressed: () {
+    //           true;
+    //         },
+    //       )
+    //     ],
+    //   );
+
     if (result is bool && result) {
       return true;
     }
@@ -128,6 +155,7 @@ class _StackRestoreProgressViewState
   }
 
   bool _success = false;
+  bool pendingCancel = false;
 
   Future<bool> _onWillPop() async {
     if (_success) {
@@ -239,7 +267,7 @@ class _StackRestoreProgressViewState
             left: 4,
             top: 4,
             right: 4,
-            bottom: 0,
+            bottom: 4,
           ),
           child: Column(
             crossAxisAlignment: CrossAxisAlignment.start,
@@ -255,40 +283,84 @@ class _StackRestoreProgressViewState
                 builder: (_, ref, __) {
                   final state = ref.watch(stackRestoringUIStateProvider
                       .select((value) => value.preferences));
-                  return RestoringItemCard(
-                    left: SizedBox(
-                      width: 32,
-                      height: 32,
-                      child: RoundedContainer(
-                        padding: const EdgeInsets.all(0),
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .buttonBackSecondary,
-                        child: Center(
-                          child: SvgPicture.asset(
-                            Assets.svg.gear,
-                            width: 16,
-                            height: 16,
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .accentColorDark,
+                  return !isDesktop
+                      ? RestoringItemCard(
+                          left: SizedBox(
+                            width: 32,
+                            height: 32,
+                            child: RoundedContainer(
+                              padding: const EdgeInsets.all(0),
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .buttonBackSecondary,
+                              child: Center(
+                                child: SvgPicture.asset(
+                                  Assets.svg.gear,
+                                  width: 16,
+                                  height: 16,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .accentColorDark,
+                                ),
+                              ),
+                            ),
                           ),
-                        ),
-                      ),
-                    ),
-                    right: SizedBox(
-                      width: 20,
-                      height: 20,
-                      child: _getIconForState(state),
-                    ),
-                    title: "Preferences",
-                    subTitle: state == StackRestoringStatus.failed
-                        ? Text(
-                            "Something went wrong",
-                            style: STextStyles.errorSmall(context),
-                          )
-                        : null,
-                  );
+                          right: SizedBox(
+                            width: 20,
+                            height: 20,
+                            child: _getIconForState(state),
+                          ),
+                          title: "Preferences",
+                          subTitle: state == StackRestoringStatus.failed
+                              ? Text(
+                                  "Something went wrong",
+                                  style: STextStyles.errorSmall(context),
+                                )
+                              : null,
+                        )
+                      : RoundedContainer(
+                          padding: EdgeInsets.all(0),
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .popupBG,
+                          borderColor: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                          child: RestoringItemCard(
+                            left: SizedBox(
+                              width: 32,
+                              height: 32,
+                              child: RoundedContainer(
+                                padding: const EdgeInsets.all(0),
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .buttonBackSecondary,
+                                child: Center(
+                                  child: SvgPicture.asset(
+                                    Assets.svg.gear,
+                                    width: 16,
+                                    height: 16,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark,
+                                  ),
+                                ),
+                              ),
+                            ),
+                            right: SizedBox(
+                              width: 20,
+                              height: 20,
+                              child: _getIconForState(state),
+                            ),
+                            title: "Preferences",
+                            subTitle: state == StackRestoringStatus.failed
+                                ? Text(
+                                    "Something went wrong",
+                                    style: STextStyles.errorSmall(context),
+                                  )
+                                : null,
+                          ),
+                        );
                 },
               ),
               const SizedBox(
@@ -298,39 +370,82 @@ class _StackRestoreProgressViewState
                 builder: (_, ref, __) {
                   final state = ref.watch(stackRestoringUIStateProvider
                       .select((value) => value.addressBook));
-                  return RestoringItemCard(
-                    left: SizedBox(
-                      width: 32,
-                      height: 32,
-                      child: RoundedContainer(
-                        padding: const EdgeInsets.all(0),
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .buttonBackSecondary,
-                        child: Center(
-                          child: AddressBookIcon(
-                            width: 16,
-                            height: 16,
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .accentColorDark,
+                  return !isDesktop
+                      ? RestoringItemCard(
+                          left: SizedBox(
+                            width: 32,
+                            height: 32,
+                            child: RoundedContainer(
+                              padding: const EdgeInsets.all(0),
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .buttonBackSecondary,
+                              child: Center(
+                                child: AddressBookIcon(
+                                  width: 16,
+                                  height: 16,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .accentColorDark,
+                                ),
+                              ),
+                            ),
                           ),
-                        ),
-                      ),
-                    ),
-                    right: SizedBox(
-                      width: 20,
-                      height: 20,
-                      child: _getIconForState(state),
-                    ),
-                    title: "Address book",
-                    subTitle: state == StackRestoringStatus.failed
-                        ? Text(
-                            "Something went wrong",
-                            style: STextStyles.errorSmall(context),
-                          )
-                        : null,
-                  );
+                          right: SizedBox(
+                            width: 20,
+                            height: 20,
+                            child: _getIconForState(state),
+                          ),
+                          title: "Address book",
+                          subTitle: state == StackRestoringStatus.failed
+                              ? Text(
+                                  "Something went wrong",
+                                  style: STextStyles.errorSmall(context),
+                                )
+                              : null,
+                        )
+                      : RoundedContainer(
+                          padding: EdgeInsets.all(0),
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .popupBG,
+                          borderColor: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                          child: RestoringItemCard(
+                            left: SizedBox(
+                              width: 32,
+                              height: 32,
+                              child: RoundedContainer(
+                                padding: const EdgeInsets.all(0),
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .buttonBackSecondary,
+                                child: Center(
+                                  child: AddressBookIcon(
+                                    width: 16,
+                                    height: 16,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark,
+                                  ),
+                                ),
+                              ),
+                            ),
+                            right: SizedBox(
+                              width: 20,
+                              height: 20,
+                              child: _getIconForState(state),
+                            ),
+                            title: "Address book",
+                            subTitle: state == StackRestoringStatus.failed
+                                ? Text(
+                                    "Something went wrong",
+                                    style: STextStyles.errorSmall(context),
+                                  )
+                                : null,
+                          ),
+                        );
                 },
               ),
               const SizedBox(
@@ -340,40 +455,83 @@ class _StackRestoreProgressViewState
                 builder: (_, ref, __) {
                   final state = ref.watch(stackRestoringUIStateProvider
                       .select((value) => value.nodes));
-                  return RestoringItemCard(
-                    left: SizedBox(
-                      width: 32,
-                      height: 32,
-                      child: RoundedContainer(
-                        padding: const EdgeInsets.all(0),
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .buttonBackSecondary,
-                        child: Center(
-                          child: SvgPicture.asset(
-                            Assets.svg.node,
-                            width: 16,
-                            height: 16,
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .accentColorDark,
+                  return !isDesktop
+                      ? RestoringItemCard(
+                          left: SizedBox(
+                            width: 32,
+                            height: 32,
+                            child: RoundedContainer(
+                              padding: const EdgeInsets.all(0),
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .buttonBackSecondary,
+                              child: Center(
+                                child: SvgPicture.asset(
+                                  Assets.svg.node,
+                                  width: 16,
+                                  height: 16,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .accentColorDark,
+                                ),
+                              ),
+                            ),
                           ),
-                        ),
-                      ),
-                    ),
-                    right: SizedBox(
-                      width: 20,
-                      height: 20,
-                      child: _getIconForState(state),
-                    ),
-                    title: "Nodes",
-                    subTitle: state == StackRestoringStatus.failed
-                        ? Text(
-                            "Something went wrong",
-                            style: STextStyles.errorSmall(context),
-                          )
-                        : null,
-                  );
+                          right: SizedBox(
+                            width: 20,
+                            height: 20,
+                            child: _getIconForState(state),
+                          ),
+                          title: "Nodes",
+                          subTitle: state == StackRestoringStatus.failed
+                              ? Text(
+                                  "Something went wrong",
+                                  style: STextStyles.errorSmall(context),
+                                )
+                              : null,
+                        )
+                      : RoundedContainer(
+                          padding: EdgeInsets.all(0),
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .popupBG,
+                          borderColor: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                          child: RestoringItemCard(
+                            left: SizedBox(
+                              width: 32,
+                              height: 32,
+                              child: RoundedContainer(
+                                padding: const EdgeInsets.all(0),
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .buttonBackSecondary,
+                                child: Center(
+                                  child: SvgPicture.asset(
+                                    Assets.svg.node,
+                                    width: 16,
+                                    height: 16,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark,
+                                  ),
+                                ),
+                              ),
+                            ),
+                            right: SizedBox(
+                              width: 20,
+                              height: 20,
+                              child: _getIconForState(state),
+                            ),
+                            title: "Nodes",
+                            subTitle: state == StackRestoringStatus.failed
+                                ? Text(
+                                    "Something went wrong",
+                                    style: STextStyles.errorSmall(context),
+                                  )
+                                : null,
+                          ));
                 },
               ),
               const SizedBox(
@@ -383,40 +541,86 @@ class _StackRestoreProgressViewState
                 builder: (_, ref, __) {
                   final state = ref.watch(stackRestoringUIStateProvider
                       .select((value) => value.trades));
-                  return RestoringItemCard(
-                    left: SizedBox(
-                      width: 32,
-                      height: 32,
-                      child: RoundedContainer(
-                        padding: const EdgeInsets.all(0),
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .buttonBackSecondary,
-                        child: Center(
-                          child: SvgPicture.asset(
-                            Assets.svg.arrowRotate2,
-                            width: 16,
-                            height: 16,
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .accentColorDark,
+                  return !isDesktop
+                      ? Container(
+                          child: RestoringItemCard(
+                            left: SizedBox(
+                              width: 32,
+                              height: 32,
+                              child: RoundedContainer(
+                                padding: const EdgeInsets.all(0),
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .buttonBackSecondary,
+                                child: Center(
+                                  child: SvgPicture.asset(
+                                    Assets.svg.arrowRotate2,
+                                    width: 16,
+                                    height: 16,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark,
+                                  ),
+                                ),
+                              ),
+                            ),
+                            right: SizedBox(
+                              width: 20,
+                              height: 20,
+                              child: _getIconForState(state),
+                            ),
+                            title: "Exchange history",
+                            subTitle: state == StackRestoringStatus.failed
+                                ? Text(
+                                    "Something went wrong",
+                                    style: STextStyles.errorSmall(context),
+                                  )
+                                : null,
                           ),
-                        ),
-                      ),
-                    ),
-                    right: SizedBox(
-                      width: 20,
-                      height: 20,
-                      child: _getIconForState(state),
-                    ),
-                    title: "Exchange history",
-                    subTitle: state == StackRestoringStatus.failed
-                        ? Text(
-                            "Something went wrong",
-                            style: STextStyles.errorSmall(context),
-                          )
-                        : null,
-                  );
+                        )
+                      : RoundedContainer(
+                          padding: EdgeInsets.all(0),
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .popupBG,
+                          borderColor: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                          child: RestoringItemCard(
+                            left: SizedBox(
+                              width: 32,
+                              height: 32,
+                              child: RoundedContainer(
+                                padding: const EdgeInsets.all(0),
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .buttonBackSecondary,
+                                child: Center(
+                                  child: SvgPicture.asset(
+                                    Assets.svg.arrowRotate2,
+                                    width: 16,
+                                    height: 16,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark,
+                                  ),
+                                ),
+                              ),
+                            ),
+                            right: SizedBox(
+                              width: 20,
+                              height: 20,
+                              child: _getIconForState(state),
+                            ),
+                            title: "Exchange history",
+                            subTitle: state == StackRestoringStatus.failed
+                                ? Text(
+                                    "Something went wrong",
+                                    style: STextStyles.errorSmall(context),
+                                  )
+                                : null,
+                          ),
+                        );
                 },
               ),
               const SizedBox(
@@ -446,28 +650,55 @@ class _StackRestoreProgressViewState
               ),
               SizedBox(
                 width: MediaQuery.of(context).size.width - 32,
-                child: TextButton(
-                  onPressed: () async {
-                    if (_success) {
-                      Navigator.of(context).pop();
-                    } else {
-                      if (await _requestCancel()) {
-                        await _cancel();
-                      }
-                    }
-                  },
-                  style: Theme.of(context)
-                      .extension<StackColors>()!
-                      .getPrimaryEnabledButtonColor(context),
-                  child: Text(
-                    _success ? "OK" : "Cancel restore process",
-                    style: STextStyles.button(context).copyWith(
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .buttonTextPrimary,
-                    ),
-                  ),
-                ),
+                child: !isDesktop
+                    ? TextButton(
+                        onPressed: () async {
+                          if (_success) {
+                            Navigator.of(context).pop();
+                          } else {
+                            if (await _requestCancel()) {
+                              await _cancel();
+                            }
+                          }
+                        },
+                        style: Theme.of(context)
+                            .extension<StackColors>()!
+                            .getPrimaryEnabledButtonColor(context),
+                        child: Text(
+                          _success ? "OK" : "Cancel restore process",
+                          style: STextStyles.button(context).copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .buttonTextPrimary,
+                          ),
+                        ),
+                      )
+                    : Row(
+                        mainAxisAlignment: MainAxisAlignment.end,
+                        children: [
+                          _success
+                              ? PrimaryButton(
+                                  width: 248,
+                                  desktopMed: true,
+                                  enabled: true,
+                                  label: "Done",
+                                  onPressed: () async {
+                                    Navigator.of(context).pop();
+                                  },
+                                )
+                              : SecondaryButton(
+                                  width: 248,
+                                  desktopMed: true,
+                                  enabled: true,
+                                  label: "Cancel restore process",
+                                  onPressed: () async {
+                                    if (await _requestCancel()) {
+                                      await _cancel();
+                                    }
+                                  },
+                                ),
+                        ],
+                      ),
               ),
             ],
           ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart
index 55f0588d2..2239eee71 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart
@@ -11,6 +11,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/stack_restoring_status.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/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 
@@ -68,140 +69,287 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> {
     final coin = ref.watch(provider.select((value) => value.coin));
     final restoringStatus =
         ref.watch(provider.select((value) => value.restoringState));
-    return RestoringItemCard(
-      left: SizedBox(
-        width: 32,
-        height: 32,
-        child: RoundedContainer(
-          padding: const EdgeInsets.all(0),
-          color: Theme.of(context).extension<StackColors>()!.colorForCoin(coin),
-          child: Center(
-            child: SvgPicture.asset(
-              Assets.svg.iconFor(
-                coin: coin,
-              ),
-              height: 20,
-              width: 20,
-            ),
-          ),
-        ),
-      ),
-      onRightTapped: restoringStatus == StackRestoringStatus.failed
-          ? () async {
-              final manager = ref.read(provider).manager!;
-
-              ref.read(stackRestoringUIStateProvider).update(
-                  walletId: manager.walletId,
-                  restoringStatus: StackRestoringStatus.restoring);
-
-              try {
-                final mnemonicList = await manager.mnemonic;
-                int maxUnusedAddressGap = 20;
-                if (coin == Coin.firo) {
-                  maxUnusedAddressGap = 50;
-                }
-                const maxNumberOfIndexesToCheck = 1000;
-
-                if (mnemonicList.isEmpty) {
-                  await manager.recoverFromMnemonic(
-                    mnemonic: ref.read(provider).mnemonic!,
-                    maxUnusedAddressGap: maxUnusedAddressGap,
-                    maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck,
-                    height: ref.read(provider).height ?? 0,
-                  );
-                } else {
-                  await manager.fullRescan(
-                    maxUnusedAddressGap,
-                    maxNumberOfIndexesToCheck,
-                  );
-                }
-
-                if (mounted) {
-                  final address = await manager.currentReceivingAddress;
-
-                  ref.read(stackRestoringUIStateProvider).update(
-                        walletId: manager.walletId,
-                        restoringStatus: StackRestoringStatus.success,
-                        address: address,
-                      );
-                }
-              } catch (_) {
-                if (mounted) {
-                  ref.read(stackRestoringUIStateProvider).update(
-                        walletId: manager.walletId,
-                        restoringStatus: StackRestoringStatus.failed,
-                      );
-                }
-              }
-            }
-          : null,
-      right: SizedBox(
-        width: 20,
-        height: 20,
-        child: _getIconForState(
-          ref.watch(provider.select((value) => value.restoringState)),
-        ),
-      ),
-      title:
-          "${ref.watch(provider.select((value) => value.walletName))} (${coin.ticker})",
-      subTitle: restoringStatus == StackRestoringStatus.failed
-          ? Text(
-              "Unable to restore. Tap icon to retry.",
-              style: STextStyles.errorSmall(context),
-            )
-          : ref.watch(provider.select((value) => value.address)) != null
-              ? Text(
-                  ref.watch(provider.select((value) => value.address))!,
-                  style: STextStyles.infoSmall(context),
-                )
-              : null,
-      button: restoringStatus == StackRestoringStatus.failed
-          ? Container(
-              height: 20,
-              decoration: BoxDecoration(
+    return !Util.isDesktop
+        ? RestoringItemCard(
+            left: SizedBox(
+              width: 32,
+              height: 32,
+              child: RoundedContainer(
+                padding: const EdgeInsets.all(0),
                 color: Theme.of(context)
                     .extension<StackColors>()!
-                    .buttonBackSecondary,
-                borderRadius: BorderRadius.circular(
-                  1000,
-                ),
-              ),
-              child: RawMaterialButton(
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                splashColor:
-                    Theme.of(context).extension<StackColors>()!.highlight,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    1000,
+                    .colorForCoin(coin),
+                child: Center(
+                  child: SvgPicture.asset(
+                    Assets.svg.iconFor(
+                      coin: coin,
+                    ),
+                    height: 20,
+                    width: 20,
                   ),
                 ),
-                onPressed: () async {
-                  final mnemonic = ref.read(provider).mnemonic;
+              ),
+            ),
+            onRightTapped: restoringStatus == StackRestoringStatus.failed
+                ? () async {
+                    final manager = ref.read(provider).manager!;
 
-                  if (mnemonic != null) {
-                    Navigator.of(context).push(
-                      RouteGenerator.getRoute(
-                        builder: (_) => RecoverPhraseView(
-                          walletName: ref.read(provider).walletName,
-                          mnemonic: mnemonic.split(" "),
+                    ref.read(stackRestoringUIStateProvider).update(
+                        walletId: manager.walletId,
+                        restoringStatus: StackRestoringStatus.restoring);
+
+                    try {
+                      final mnemonicList = await manager.mnemonic;
+                      int maxUnusedAddressGap = 20;
+                      if (coin == Coin.firo) {
+                        maxUnusedAddressGap = 50;
+                      }
+                      const maxNumberOfIndexesToCheck = 1000;
+
+                      if (mnemonicList.isEmpty) {
+                        await manager.recoverFromMnemonic(
+                          mnemonic: ref.read(provider).mnemonic!,
+                          maxUnusedAddressGap: maxUnusedAddressGap,
+                          maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck,
+                          height: ref.read(provider).height ?? 0,
+                        );
+                      } else {
+                        await manager.fullRescan(
+                          maxUnusedAddressGap,
+                          maxNumberOfIndexesToCheck,
+                        );
+                      }
+
+                      if (mounted) {
+                        final address = await manager.currentReceivingAddress;
+
+                        ref.read(stackRestoringUIStateProvider).update(
+                              walletId: manager.walletId,
+                              restoringStatus: StackRestoringStatus.success,
+                              address: address,
+                            );
+                      }
+                    } catch (_) {
+                      if (mounted) {
+                        ref.read(stackRestoringUIStateProvider).update(
+                              walletId: manager.walletId,
+                              restoringStatus: StackRestoringStatus.failed,
+                            );
+                      }
+                    }
+                  }
+                : null,
+            right: SizedBox(
+              width: 20,
+              height: 20,
+              child: _getIconForState(
+                ref.watch(provider.select((value) => value.restoringState)),
+              ),
+            ),
+            title:
+                "${ref.watch(provider.select((value) => value.walletName))} (${coin.ticker})",
+            subTitle: restoringStatus == StackRestoringStatus.failed
+                ? Text(
+                    "Unable to restore. Tap icon to retry.",
+                    style: STextStyles.errorSmall(context),
+                  )
+                : ref.watch(provider.select((value) => value.address)) != null
+                    ? Text(
+                        ref.watch(provider.select((value) => value.address))!,
+                        style: STextStyles.infoSmall(context),
+                      )
+                    : null,
+            button: restoringStatus == StackRestoringStatus.failed
+                ? Container(
+                    height: 20,
+                    decoration: BoxDecoration(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .buttonBackSecondary,
+                      borderRadius: BorderRadius.circular(
+                        1000,
+                      ),
+                    ),
+                    child: RawMaterialButton(
+                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                      splashColor:
+                          Theme.of(context).extension<StackColors>()!.highlight,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          1000,
                         ),
                       ),
-                    );
-                  }
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(horizontal: 8.0),
-                  child: Text(
-                    "Show recovery phrase",
-                    style: STextStyles.infoSmall(context).copyWith(
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .accentColorDark),
+                      onPressed: () async {
+                        final mnemonic = ref.read(provider).mnemonic;
+
+                        if (mnemonic != null) {
+                          Navigator.of(context).push(
+                            RouteGenerator.getRoute(
+                              builder: (_) => RecoverPhraseView(
+                                walletName: ref.read(provider).walletName,
+                                mnemonic: mnemonic.split(" "),
+                              ),
+                            ),
+                          );
+                        }
+                      },
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(horizontal: 8.0),
+                        child: Text(
+                          "Show recovery phrase",
+                          style: STextStyles.infoSmall(context).copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorDark),
+                        ),
+                      ),
+                    ),
+                  )
+                : null,
+          )
+        : RoundedContainer(
+            padding: EdgeInsets.all(0),
+            color: Theme.of(context).extension<StackColors>()!.popupBG,
+            borderColor: Theme.of(context).extension<StackColors>()!.background,
+            child: RestoringItemCard(
+              left: SizedBox(
+                width: 32,
+                height: 32,
+                child: RoundedContainer(
+                  padding: const EdgeInsets.all(0),
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .colorForCoin(coin),
+                  child: Center(
+                    child: SvgPicture.asset(
+                      Assets.svg.iconFor(
+                        coin: coin,
+                      ),
+                      height: 20,
+                      width: 20,
+                    ),
                   ),
                 ),
               ),
-            )
-          : null,
-    );
+              onRightTapped: restoringStatus == StackRestoringStatus.failed
+                  ? () async {
+                      final manager = ref.read(provider).manager!;
+
+                      ref.read(stackRestoringUIStateProvider).update(
+                          walletId: manager.walletId,
+                          restoringStatus: StackRestoringStatus.restoring);
+
+                      try {
+                        final mnemonicList = await manager.mnemonic;
+                        int maxUnusedAddressGap = 20;
+                        if (coin == Coin.firo) {
+                          maxUnusedAddressGap = 50;
+                        }
+                        const maxNumberOfIndexesToCheck = 1000;
+
+                        if (mnemonicList.isEmpty) {
+                          await manager.recoverFromMnemonic(
+                            mnemonic: ref.read(provider).mnemonic!,
+                            maxUnusedAddressGap: maxUnusedAddressGap,
+                            maxNumberOfIndexesToCheck:
+                                maxNumberOfIndexesToCheck,
+                            height: ref.read(provider).height ?? 0,
+                          );
+                        } else {
+                          await manager.fullRescan(
+                            maxUnusedAddressGap,
+                            maxNumberOfIndexesToCheck,
+                          );
+                        }
+
+                        if (mounted) {
+                          final address = await manager.currentReceivingAddress;
+
+                          ref.read(stackRestoringUIStateProvider).update(
+                                walletId: manager.walletId,
+                                restoringStatus: StackRestoringStatus.success,
+                                address: address,
+                              );
+                        }
+                      } catch (_) {
+                        if (mounted) {
+                          ref.read(stackRestoringUIStateProvider).update(
+                                walletId: manager.walletId,
+                                restoringStatus: StackRestoringStatus.failed,
+                              );
+                        }
+                      }
+                    }
+                  : null,
+              right: SizedBox(
+                width: 20,
+                height: 20,
+                child: _getIconForState(
+                  ref.watch(provider.select((value) => value.restoringState)),
+                ),
+              ),
+              title:
+                  "${ref.watch(provider.select((value) => value.walletName))} (${coin.ticker})",
+              subTitle: restoringStatus == StackRestoringStatus.failed
+                  ? Text(
+                      "Unable to restore. Tap icon to retry.",
+                      style: STextStyles.errorSmall(context),
+                    )
+                  : ref.watch(provider.select((value) => value.address)) != null
+                      ? Text(
+                          ref.watch(provider.select((value) => value.address))!,
+                          style: STextStyles.infoSmall(context),
+                        )
+                      : null,
+              button: restoringStatus == StackRestoringStatus.failed
+                  ? Container(
+                      height: 20,
+                      decoration: BoxDecoration(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .buttonBackSecondary,
+                        borderRadius: BorderRadius.circular(
+                          1000,
+                        ),
+                      ),
+                      child: RawMaterialButton(
+                        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                        splashColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .highlight,
+                        shape: RoundedRectangleBorder(
+                          borderRadius: BorderRadius.circular(
+                            1000,
+                          ),
+                        ),
+                        onPressed: () async {
+                          final mnemonic = ref.read(provider).mnemonic;
+
+                          if (mnemonic != null) {
+                            Navigator.of(context).push(
+                              RouteGenerator.getRoute(
+                                builder: (_) => RecoverPhraseView(
+                                  walletName: ref.read(provider).walletName,
+                                  mnemonic: mnemonic.split(" "),
+                                ),
+                              ),
+                            );
+                          }
+                        },
+                        child: Padding(
+                          padding: const EdgeInsets.symmetric(horizontal: 8.0),
+                          child: Text(
+                            "Show recovery phrase",
+                            style: STextStyles.infoSmall(context).copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorDark),
+                          ),
+                        ),
+                      ),
+                    )
+                  : null,
+            ),
+          );
   }
 }

From de896d30bcfa87afb74a12bd6d2afe2c9aea141d Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 10 Nov 2022 22:14:08 -0700
Subject: [PATCH 211/426] desktop dialog for disable auto backup

---
 .../backup_and_restore_settings.dart          | 135 +++++++++++++-----
 1 file changed, 99 insertions(+), 36 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 3ea6cea6c..0df7c8975 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -14,7 +14,9 @@ import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/format.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/custom_buttons/draggable_switch_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -108,42 +110,103 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
       useSafeArea: false,
       barrierDismissible: true,
       builder: (context) {
-        return StackDialog(
-          title: "Disable Auto Backup",
-          message:
-              "You are turning off Auto Backup. You can turn it back on at any time. Your previous Auto Backup file will not be deleted. Remember to backup your wallets manually so you don't lose important information.",
-          leftButton: TextButton(
-            style: Theme.of(context)
-                .extension<StackColors>()!
-                .getSecondaryEnabledButtonColor(context),
-            child: Text(
-              "Back",
-              style: STextStyles.button(context).copyWith(
-                color:
-                    Theme.of(context).extension<StackColors>()!.accentColorDark,
-              ),
-            ),
-            onPressed: () {
-              Navigator.of(context).pop();
-            },
-          ),
-          rightButton: TextButton(
-            style: Theme.of(context)
-                .extension<StackColors>()!
-                .getPrimaryEnabledButtonColor(context),
-            child: Text(
-              "Disable",
-              style: STextStyles.button(context),
-            ),
-            onPressed: () {
-              Navigator.of(context).pop();
-              setState(() {
-                ref.watch(prefsChangeNotifierProvider).isAutoBackupEnabled =
-                    false;
-              });
-            },
-          ),
-        );
+        return !Util.isDesktop
+            ? StackDialog(
+                title: "Disable Auto Backup",
+                message:
+                    "You are turning off Auto Backup. You can turn it back on at any time. Your previous Auto Backup file will not be deleted. Remember to backup your wallets manually so you don't lose important information.",
+                leftButton: TextButton(
+                  style: Theme.of(context)
+                      .extension<StackColors>()!
+                      .getSecondaryEnabledButtonColor(context),
+                  child: Text(
+                    "Back",
+                    style: STextStyles.button(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                    ),
+                  ),
+                  onPressed: () {
+                    Navigator.of(context).pop();
+                  },
+                ),
+                rightButton: TextButton(
+                  style: Theme.of(context)
+                      .extension<StackColors>()!
+                      .getPrimaryEnabledButtonColor(context),
+                  child: Text(
+                    "Disable",
+                    style: STextStyles.button(context),
+                  ),
+                  onPressed: () {
+                    Navigator.of(context).pop();
+                    setState(() {
+                      ref
+                          .watch(prefsChangeNotifierProvider)
+                          .isAutoBackupEnabled = false;
+                    });
+                  },
+                ),
+              )
+            : DesktopDialog(
+                maxHeight: 270,
+                child: Padding(
+                  padding: EdgeInsets.symmetric(vertical: 20, horizontal: 32),
+                  child: Column(
+                    children: [
+                      Text(
+                        "Disable Auto Backup",
+                        style: STextStyles.desktopH3(context),
+                      ),
+                      const SizedBox(height: 24),
+                      SizedBox(
+                        width: 600,
+                        child: Text(
+                          "You are turning off Auto Backup. You can turn it back on at any time. "
+                          "Your previous Auto Backup file will not be deleted. Remember to backup your wallets "
+                          "manually so you don't lose important information.",
+                          style: STextStyles.desktopTextSmall(context).copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark3,
+                          ),
+                        ),
+                      ),
+                      const Spacer(),
+                      Row(
+                        mainAxisAlignment: MainAxisAlignment.center,
+                        children: [
+                          SecondaryButton(
+                            width: 248,
+                            desktopMed: true,
+                            enabled: true,
+                            label: "Back",
+                            onPressed: () {
+                              Navigator.of(context).pop();
+                            },
+                          ),
+                          const SizedBox(width: 20),
+                          PrimaryButton(
+                            width: 248,
+                            desktopMed: true,
+                            enabled: true,
+                            label: "Disable",
+                            onPressed: () {
+                              Navigator.of(context).pop();
+                              setState(() {
+                                ref
+                                    .watch(prefsChangeNotifierProvider)
+                                    .isAutoBackupEnabled = false;
+                              });
+                            },
+                          )
+                        ],
+                      ),
+                    ],
+                  ),
+                ),
+              );
       },
     );
     if (mounted) {

From 7a0ef9685188231eb8814c9e983e989b22cfc1f4 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 10 Nov 2022 22:14:47 -0700
Subject: [PATCH 212/426] desktop dialog for cancel stack restore

---
 .../dialogs/cancel_stack_restore_dialog.dart  | 124 +++++++++++++-----
 1 file changed, 93 insertions(+), 31 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart
index 16e51a35d..a9f4e134d 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart
@@ -1,6 +1,11 @@
 import 'package:flutter/material.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/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
 class CancelStackRestoreDialog extends StatelessWidget {
@@ -14,38 +19,95 @@ class CancelStackRestoreDialog extends StatelessWidget {
       onWillPop: () async {
         return false;
       },
-      child: StackDialog(
-        title: "Cancel restore process",
-        message:
-            "Cancelling will revert any changes that may have been applied",
-        leftButton: TextButton(
-          style: Theme.of(context)
-              .extension<StackColors>()!
-              .getSecondaryEnabledButtonColor(context),
-          child: Text(
-            "Back",
-            style: STextStyles.itemSubtitle12(context),
-          ),
-          onPressed: () {
-            Navigator.of(context).pop(false);
-          },
-        ),
-        rightButton: TextButton(
-          style: Theme.of(context)
-              .extension<StackColors>()!
-              .getPrimaryEnabledButtonColor(context),
-          child: Text(
-            "Yes, cancel",
-            style: STextStyles.itemSubtitle12(context).copyWith(
-              color:
-                  Theme.of(context).extension<StackColors>()!.buttonTextPrimary,
+      child: !Util.isDesktop
+          ? StackDialog(
+              title: "Cancel restore process",
+              message:
+                  "Cancelling will revert any changes that may have been applied",
+              leftButton: TextButton(
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getSecondaryEnabledButtonColor(context),
+                child: Text(
+                  "Back",
+                  style: STextStyles.itemSubtitle12(context),
+                ),
+                onPressed: () {
+                  Navigator.of(context).pop(false);
+                },
+              ),
+              rightButton: TextButton(
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getPrimaryEnabledButtonColor(context),
+                child: Text(
+                  "Yes, cancel",
+                  style: STextStyles.itemSubtitle12(context).copyWith(
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .buttonTextPrimary,
+                  ),
+                ),
+                onPressed: () {
+                  Navigator.of(context).pop(true);
+                },
+              ),
+            )
+          : DesktopDialog(
+              maxHeight: 250,
+              maxWidth: 600,
+              child: Padding(
+                padding: const EdgeInsets.only(
+                    top: 20, left: 32, right: 32, bottom: 20),
+                child: Column(
+                  children: [
+                    Text(
+                      "Cancel Restore Process",
+                      style: STextStyles.desktopH3(context),
+                    ),
+                    const SizedBox(height: 24),
+                    SizedBox(
+                      width: 500,
+                      child: RoundedContainer(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .snackBarBackError,
+                        child: Text(
+                          "If you cancel, the restore will not complete, and "
+                          "the wallets will not appear in your Stack.",
+                          style: STextStyles.desktopTextMedium(context),
+                        ),
+                      ),
+                    ),
+                    const Spacer(),
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        SecondaryButton(
+                          width: 248,
+                          desktopMed: true,
+                          enabled: true,
+                          label: "Keep restoring",
+                          onPressed: () {
+                            Navigator.of(context).pop(false);
+                          },
+                        ),
+                        const SizedBox(width: 20),
+                        PrimaryButton(
+                          width: 248,
+                          desktopMed: true,
+                          enabled: true,
+                          label: "Cancel anyway",
+                          onPressed: () {
+                            Navigator.of(context).pop(true);
+                          },
+                        )
+                      ],
+                    ),
+                  ],
+                ),
+              ),
             ),
-          ),
-          onPressed: () {
-            Navigator.of(context).pop(true);
-          },
-        ),
-      ),
     );
   }
 }

From 676b26ce3793d4abc697052ac781b15c5ddb8dfb Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 11 Nov 2022 09:30:13 -0600
Subject: [PATCH 213/426] stop logging annoying monero sync non error

---
 lib/services/coins/monero/monero_wallet.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index 91bb3c4db..cf0335197 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -196,7 +196,7 @@ class MoneroWallet extends CoinServiceAPI {
     try {
       syncingHeight = (walletBase!.syncStatus as SyncingSyncStatus).height;
     } catch (e, s) {
-      Logging.instance.log("$e $s", level: LogLevel.Warning);
+      // Logging.instance.log("$e $s", level: LogLevel.Warning);
     }
     final cachedHeight =
         DB.instance.get<dynamic>(boxName: walletId, key: "storedSyncingHeight")

From ca8f63c07a28ae77cb02a15c4427fbd066e8f2f2 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 11 Nov 2022 09:31:01 -0600
Subject: [PATCH 214/426] ensure loadShared is only called once

---
 lib/main.dart | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lib/main.dart b/lib/main.dart
index a04170bd9..df9d683f5 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -227,9 +227,15 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
   late final Completer<void> loadingCompleter;
 
   bool didLoad = false;
+  bool didLoadShared = false;
   bool _desktopHasPassword = false;
 
   Future<void> loadShared() async {
+    if (didLoadShared) {
+      return;
+    }
+    didLoadShared = true;
+
     await DB.instance.init();
     await ref.read(prefsChangeNotifierProvider).init();
 

From b6613b2fd7eaeda927374ec3be4d34853dc375d4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 11 Nov 2022 09:32:55 -0600
Subject: [PATCH 215/426] stop logging monero sync non-error

---
 lib/services/coins/monero/monero_wallet.dart | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index cf0335197..d6c238df0 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -154,7 +154,7 @@ class MoneroWallet extends CoinServiceAPI {
     try {
       _height = (walletBase!.syncStatus as SyncingSyncStatus).height;
     } catch (e, s) {
-      Logging.instance.log("$e $s", level: LogLevel.Warning);
+      // Logging.instance.log("$e $s", level: LogLevel.Warning);
     }
 
     int blocksRemaining = -1;
@@ -163,7 +163,7 @@ class MoneroWallet extends CoinServiceAPI {
       blocksRemaining =
           (walletBase!.syncStatus as SyncingSyncStatus).blocksLeft;
     } catch (e, s) {
-      Logging.instance.log("$e $s", level: LogLevel.Warning);
+      // Logging.instance.log("$e $s", level: LogLevel.Warning);
     }
     int currentHeight = _height + blocksRemaining;
     if (_height == -1 || blocksRemaining == -1) {
@@ -419,7 +419,7 @@ class MoneroWallet extends CoinServiceAPI {
       try {
         progress = (walletBase!.syncStatus!).progress();
       } catch (e, s) {
-        Logging.instance.log("$e $s", level: LogLevel.Warning);
+        // Logging.instance.log("$e $s", level: LogLevel.Warning);
       }
       await _fetchTransactionData();
 

From ba853837ce3f7b3e1877d8da6a53f4bbbd01749b Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 11 Nov 2022 10:45:50 -0600
Subject: [PATCH 216/426] verify passphrase functionality added to password
 service

---
 lib/utilities/desktop_password_service.dart | 27 +++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/lib/utilities/desktop_password_service.dart b/lib/utilities/desktop_password_service.dart
index 24299b855..f20525873 100644
--- a/lib/utilities/desktop_password_service.dart
+++ b/lib/utilities/desktop_password_service.dart
@@ -88,6 +88,33 @@ class DPS {
     }
   }
 
+  Future<bool> verifyPassphrase(String passphrase) async {
+    final box = await Hive.openBox<String>(DB.boxNameDesktopData);
+    final keyBlob = DB.instance.get<String>(
+      boxName: DB.boxNameDesktopData,
+      key: _kKeyBlobKey,
+    );
+    await box.close();
+
+    if (keyBlob == null) {
+      // no passphrase key blob found so any passphrase is technically bad
+      return false;
+    }
+
+    try {
+      await StorageCryptoHandler.fromExisting(passphrase, keyBlob);
+      // existing passphrase matches key blob
+      return true;
+    } catch (e, s) {
+      Logging.instance.log(
+        "${_getMessageFromException(e)}\n$s",
+        level: LogLevel.Warning,
+      );
+      // password is wrong or some other error
+      return false;
+    }
+  }
+
   Future<bool> hasPassword() async {
     final keyBlob = DB.instance.get<String>(
       boxName: DB.boxNameDesktopData,

From 7646cbe8cb28e6902c65fe181e94ea849033b872 Mon Sep 17 00:00:00 2001
From: Dan Miller <dan@cypherstack.com>
Date: Fri, 11 Nov 2022 08:54:38 -0800
Subject: [PATCH 217/426] Handle some bash errors in build script.

---
 scripts/linux/build_secure_storage_deps.sh | 34 +++++++++++++++-------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/scripts/linux/build_secure_storage_deps.sh b/scripts/linux/build_secure_storage_deps.sh
index 5ed032b1a..378f7a604 100755
--- a/scripts/linux/build_secure_storage_deps.sh
+++ b/scripts/linux/build_secure_storage_deps.sh
@@ -1,25 +1,37 @@
 #!/bin/bash
 LINUX_DIRECTORY=$(pwd)
-mkdir build
+mkdir -p build
 
 # Build JsonCPP
-cd build
-git clone https://github.com/open-source-parsers/jsoncpp.git
-cd jsoncpp
+cd build || exit
+if ! [ -x "$(command -v git)" ]; then
+  echo 'Error: git is not installed.' >&2
+  exit 1
+fi
+git -C jsoncpp pull || git clone https://github.com/open-source-parsers/jsoncpp.git jsoncpp
+cd jsoncpp || exit
 git checkout 1.7.4
-mkdir build
-cd build
+mkdir -p build
+cd build || exit
 cmake -DCMAKE_BUILD_TYPE=release -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=ON -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ..
-make -j$(nproc)
+make -j"$(nproc)"
 
-cd $LINUX_DIRECTORY
+cd "$LINUX_DIRECTORY" || exit
 # Build libSecret
 # sudo apt install meson libgirepository1.0-dev valac xsltproc gi-docgen docbook-xsl
 # sudo apt install python3-pip
 #pip3 install --user meson --upgrade
 # pip3 install --user gi-docgen
-cd build
-git clone https://gitlab.gnome.org/GNOME/libsecret.git
-cd libsecret
+cd build || exit
+git -C libsecret pull || git clone https://gitlab.gnome.org/GNOME/libsecret.git libsecret
+cd libsecret || exit
+if ! [ -x "$(command -v meson)" ]; then
+  echo 'Error: meson is not installed.' >&2
+  exit 1
+fi
 meson _build
+if ! [ -x "$(command -v ninja)" ]; then
+  echo 'Error: ninja is not installed.' >&2
+  exit 1
+fi
 ninja -C _build

From cd1d6a5bc7af6f9103b9ddd2627a152ade2e45c1 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 11 Nov 2022 10:35:12 -0700
Subject: [PATCH 218/426] v1.5.17 build 89

---
 pubspec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index 8b03cd57e..b7947a58d 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.16+88
+version: 1.5.17+89
 
 environment:
   sdk: ">=2.17.0 <3.0.0"

From 9b09f65f4d44f3b0d8c1829eb5640c8e4eec33d4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 11 Nov 2022 12:12:01 -0600
Subject: [PATCH 219/426] remove flutter secure storage explicit instantiations
 from wow/xmr

---
 lib/main.dart                                 |  1 +
 lib/services/coins/monero/monero_wallet.dart  | 20 ++++++++-----------
 .../coins/wownero/wownero_wallet.dart         | 20 +++++++------------
 3 files changed, 16 insertions(+), 25 deletions(-)

diff --git a/lib/main.dart b/lib/main.dart
index df9d683f5..70f80e8ed 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -154,6 +154,7 @@ void main() async {
 
   await Hive.openBox<dynamic>(DB.boxNameDBInfo);
 
+  // todo: db migrate stuff for desktop needs to be handled eventually
   if (!Util.isDesktop) {
     int dbVersion = DB.instance.get<dynamic>(
             boxName: DB.boxNameDBInfo, key: "hive_data_version") as int? ??
diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index d6c238df0..9e9ffc783 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -23,7 +23,6 @@ import 'package:flutter_libmonero/core/key_service.dart';
 import 'package:flutter_libmonero/core/wallet_creation_service.dart';
 import 'package:flutter_libmonero/monero/monero.dart';
 import 'package:flutter_libmonero/view_model/send/output.dart' as monero_output;
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
 import 'package:mutex/mutex.dart';
 import 'package:path_provider/path_provider.dart';
@@ -670,11 +669,10 @@ class MoneroWallet extends CoinServiceAPI {
           "Attempted to overwrite mnemonic on generate new wallet!");
     }
 
-    storage = const FlutterSecureStorage();
     walletService =
         monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
     prefs = await SharedPreferences.getInstance();
-    keysStorage = KeyService(storage!);
+    keysStorage = KeyService(_secureStore);
     WalletInfo walletInfo;
     WalletCredentials credentials;
     try {
@@ -708,7 +706,7 @@ class MoneroWallet extends CoinServiceAPI {
       credentials.walletInfo = walletInfo;
 
       _walletCreationService = WalletCreationService(
-        secureStorage: storage,
+        secureStorage: _secureStore,
         sharedPreferences: prefs,
         walletService: walletService,
         keyService: keysStorage,
@@ -787,11 +785,11 @@ class MoneroWallet extends CoinServiceAPI {
     //   Logging.instance.log("Caught in initializeWallet(): $e\n$s");
     //   return false;
     // }
-    storage = const FlutterSecureStorage();
+
     walletService =
         monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
     prefs = await SharedPreferences.getInstance();
-    keysStorage = KeyService(storage!);
+    keysStorage = KeyService(_secureStore);
 
     await _generateNewWallet();
     // var password;
@@ -833,11 +831,10 @@ class MoneroWallet extends CoinServiceAPI {
           "Attempted to initialize an existing wallet using an unknown wallet ID!");
     }
 
-    storage = const FlutterSecureStorage();
     walletService =
         monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
     prefs = await SharedPreferences.getInstance();
-    keysStorage = KeyService(storage!);
+    keysStorage = KeyService(_secureStore);
 
     await _prefs.init();
     final data =
@@ -889,7 +886,7 @@ class MoneroWallet extends CoinServiceAPI {
   bool longMutex = false;
 
   // TODO: are these needed?
-  FlutterSecureStorage? storage;
+
   WalletService? walletService;
   SharedPreferences? prefs;
   KeyService? keysStorage;
@@ -970,11 +967,10 @@ class MoneroWallet extends CoinServiceAPI {
       await DB.instance
           .put<dynamic>(boxName: walletId, key: "restoreHeight", value: height);
 
-      storage = const FlutterSecureStorage();
       walletService =
           monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
       prefs = await SharedPreferences.getInstance();
-      keysStorage = KeyService(storage!);
+      keysStorage = KeyService(_secureStore);
       WalletInfo walletInfo;
       WalletCredentials credentials;
       String name = _walletId;
@@ -1001,7 +997,7 @@ class MoneroWallet extends CoinServiceAPI {
         credentials.walletInfo = walletInfo;
 
         _walletCreationService = WalletCreationService(
-          secureStorage: storage,
+          secureStorage: _secureStore,
           sharedPreferences: prefs,
           walletService: walletService,
           keyService: keysStorage,
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index c872c7d7e..39d3038ee 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -1,7 +1,6 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:cw_core/get_height_by_date.dart';
 import 'package:cw_core/monero_transaction_priority.dart';
 import 'package:cw_core/node.dart';
 import 'package:cw_core/pending_transaction.dart';
@@ -25,7 +24,6 @@ import 'package:flutter_libmonero/core/wallet_creation_service.dart';
 import 'package:flutter_libmonero/view_model/send/output.dart'
     as wownero_output;
 import 'package:flutter_libmonero/wownero/wownero.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:http/http.dart';
 import 'package:mutex/mutex.dart';
 import 'package:path_provider/path_provider.dart';
@@ -672,12 +670,11 @@ class WowneroWallet extends CoinServiceAPI {
           "Attempted to overwrite mnemonic on generate new wallet!");
     }
 
-    storage = const FlutterSecureStorage();
     // TODO: Wallet Service may need to be switched to Wownero
     walletService =
         wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
     prefs = await SharedPreferences.getInstance();
-    keysStorage = KeyService(storage!);
+    keysStorage = KeyService(_secureStore);
     WalletInfo walletInfo;
     WalletCredentials credentials;
     try {
@@ -702,7 +699,7 @@ class WowneroWallet extends CoinServiceAPI {
       credentials.walletInfo = walletInfo;
 
       _walletCreationService = WalletCreationService(
-        secureStorage: storage,
+        secureStorage: _secureStore,
         sharedPreferences: prefs,
         walletService: walletService,
         keyService: keysStorage,
@@ -793,11 +790,10 @@ class WowneroWallet extends CoinServiceAPI {
     //   Logging.instance.log("Caught in initializeWallet(): $e\n$s");
     //   return false;
     // }
-    storage = const FlutterSecureStorage();
     walletService =
         wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
     prefs = await SharedPreferences.getInstance();
-    keysStorage = KeyService(storage!);
+    keysStorage = KeyService(_secureStore);
 
     await _generateNewWallet(seedWordsLength: seedWordsLength);
     // var password;
@@ -839,11 +835,10 @@ class WowneroWallet extends CoinServiceAPI {
           "Attempted to initialize an existing wallet using an unknown wallet ID!");
     }
 
-    storage = const FlutterSecureStorage();
     walletService =
         wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
     prefs = await SharedPreferences.getInstance();
-    keysStorage = KeyService(storage!);
+    keysStorage = KeyService(_secureStore);
 
     await _prefs.init();
     final data =
@@ -895,7 +890,7 @@ class WowneroWallet extends CoinServiceAPI {
   bool longMutex = false;
 
   // TODO: are these needed?
-  FlutterSecureStorage? storage;
+
   WalletService? walletService;
   SharedPreferences? prefs;
   KeyService? keysStorage;
@@ -993,11 +988,10 @@ class WowneroWallet extends CoinServiceAPI {
       await DB.instance
           .put<dynamic>(boxName: walletId, key: "restoreHeight", value: height);
 
-      storage = const FlutterSecureStorage();
       walletService =
           wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
       prefs = await SharedPreferences.getInstance();
-      keysStorage = KeyService(storage!);
+      keysStorage = KeyService(_secureStore);
       WalletInfo walletInfo;
       WalletCredentials credentials;
       String name = _walletId;
@@ -1024,7 +1018,7 @@ class WowneroWallet extends CoinServiceAPI {
         credentials.walletInfo = walletInfo;
 
         _walletCreationService = WalletCreationService(
-          secureStorage: storage,
+          secureStorage: _secureStore,
           sharedPreferences: prefs,
           walletService: walletService,
           keyService: keysStorage,

From f7bf624028462d4ec4958e1edb05331f12910b65 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 11 Nov 2022 12:37:44 -0600
Subject: [PATCH 220/426] initialize store on successful password creation

---
 .../create_password/create_password_view.dart                  | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/pages_desktop_specific/create_password/create_password_view.dart b/lib/pages_desktop_specific/create_password/create_password_view.dart
index d5ce42679..c29fc3de6 100644
--- a/lib/pages_desktop_specific/create_password/create_password_view.dart
+++ b/lib/pages_desktop_specific/create_password/create_password_view.dart
@@ -6,9 +6,11 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
+import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -78,6 +80,7 @@ class _CreatePasswordViewState extends ConsumerState<CreatePasswordView> {
       }
 
       await ref.read(storageCryptoHandlerProvider).initFromNew(passphrase);
+      await (ref.read(secureStoreProvider).store as DesktopSecureStore).init();
     } catch (e) {
       unawaited(showFloatingFlushBar(
         type: FlushBarType.warning,

From 6ce899cd27348cb682e721295b00f2bc1f5c5dfa Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 11 Nov 2022 12:27:39 -0700
Subject: [PATCH 221/426] textfields for desktop change password

---
 .../home/settings_menu/security_settings.dart | 373 ++++++++++++++++--
 1 file changed, 333 insertions(+), 40 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index cdcaed49a..40928a0af 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -2,11 +2,14 @@ import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart';
 import 'package:stackwallet/utilities/assets.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/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+import 'package:zxcvbn/zxcvbn.dart';
 
 class SecuritySettings extends ConsumerStatefulWidget {
   const SecuritySettings({Key? key}) : super(key: key);
@@ -18,21 +21,55 @@ class SecuritySettings extends ConsumerStatefulWidget {
 }
 
 class _SecuritySettings extends ConsumerState<SecuritySettings> {
-  Future<void> enableAutoBackup() async {
-    // wait for keyboard to disappear
-    FocusScope.of(context).unfocus();
-    await Future<void>.delayed(
-      const Duration(milliseconds: 100),
-    );
+  late bool changePassword = false;
 
-    await showDialog<dynamic>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: true,
-      builder: (context) {
-        return EnableBackupDialog();
-      },
-    );
+  late final TextEditingController passwordCurrentController;
+  late final TextEditingController passwordController;
+  late final TextEditingController passwordRepeatController;
+
+  late final FocusNode passwordCurrentFocusNode;
+  late final FocusNode passwordFocusNode;
+  late final FocusNode passwordRepeatFocusNode;
+  final zxcvbn = Zxcvbn();
+
+  bool hidePassword = true;
+  bool shouldShowPasswordHint = true;
+
+  double passwordStrength = 0.0;
+
+  bool get shouldEnableSave {
+    return passwordCurrentController.text.isNotEmpty &&
+        passwordController.text.isNotEmpty &&
+        passwordRepeatController.text.isNotEmpty;
+  }
+
+  String passwordFeedback =
+      "Add another word or two. Uncommon words are better. Use a few words, avoid common phrases. No need for symbols, digits, or uppercase letters.";
+
+  @override
+  void initState() {
+    passwordCurrentController = TextEditingController();
+    passwordController = TextEditingController();
+    passwordRepeatController = TextEditingController();
+
+    passwordCurrentFocusNode = FocusNode();
+    passwordFocusNode = FocusNode();
+    passwordRepeatFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    passwordCurrentController.dispose();
+    passwordController.dispose();
+    passwordRepeatController.dispose();
+
+    passwordCurrentFocusNode.dispose();
+    passwordFocusNode.dispose();
+    passwordRepeatFocusNode.dispose();
+
+    super.dispose();
   }
 
   @override
@@ -78,12 +115,290 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
+                  children: [
                     Padding(
                       padding: EdgeInsets.all(
                         10,
                       ),
-                      child: NewPasswordButton(),
+                      child: changePassword
+                          ? SizedBox(
+                              width: 512,
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    "Current password",
+                                    style:
+                                        STextStyles.desktopTextExtraExtraSmall(
+                                                context)
+                                            .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark3),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                  const SizedBox(height: 10),
+                                  ClipRRect(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                    child: TextField(
+                                      key: const Key(
+                                          "desktopSecurityRestoreFromFilePasswordFieldKey"),
+                                      focusNode: passwordFocusNode,
+                                      controller: passwordController,
+                                      style: STextStyles.field(context),
+                                      obscureText: hidePassword,
+                                      enableSuggestions: false,
+                                      autocorrect: false,
+                                      decoration: standardInputDecoration(
+                                        "Enter current password",
+                                        passwordFocusNode,
+                                        context,
+                                      ).copyWith(
+                                        labelStyle:
+                                            STextStyles.fieldLabel(context),
+                                        suffixIcon: UnconstrainedBox(
+                                          child: Row(
+                                            children: [
+                                              const SizedBox(
+                                                width: 16,
+                                              ),
+                                              GestureDetector(
+                                                key: const Key(
+                                                    "desktopSecurityRestoreFromFilePasswordFieldShowPasswordButtonKey"),
+                                                onTap: () async {
+                                                  setState(() {
+                                                    hidePassword =
+                                                        !hidePassword;
+                                                  });
+                                                },
+                                                child: SvgPicture.asset(
+                                                  hidePassword
+                                                      ? Assets.svg.eye
+                                                      : Assets.svg.eyeSlash,
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark3,
+                                                  width: 16,
+                                                  height: 16,
+                                                ),
+                                              ),
+                                              const SizedBox(
+                                                width: 12,
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                      ),
+                                      onChanged: (newValue) {},
+                                    ),
+                                  ),
+                                  const SizedBox(height: 16),
+                                  Text(
+                                    "New password",
+                                    style:
+                                        STextStyles.desktopTextExtraExtraSmall(
+                                                context)
+                                            .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark3),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                  const SizedBox(height: 10),
+                                  ClipRRect(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                    child: TextField(
+                                      key: const Key(
+                                          "desktopSecurityCreateNewPasswordFieldKey1"),
+                                      focusNode: passwordCurrentFocusNode,
+                                      controller: passwordCurrentController,
+                                      style: STextStyles.field(context),
+                                      obscureText: hidePassword,
+                                      enableSuggestions: false,
+                                      autocorrect: false,
+                                      decoration: standardInputDecoration(
+                                        "Enter new password",
+                                        passwordCurrentFocusNode,
+                                        context,
+                                      ).copyWith(
+                                        labelStyle:
+                                            STextStyles.fieldLabel(context),
+                                        suffixIcon: UnconstrainedBox(
+                                          child: Row(
+                                            children: [
+                                              const SizedBox(
+                                                width: 16,
+                                              ),
+                                              GestureDetector(
+                                                key: const Key(
+                                                    "desktopSecurityCreateNewPasswordButtonKey1"),
+                                                onTap: () async {
+                                                  setState(() {
+                                                    hidePassword =
+                                                        !hidePassword;
+                                                  });
+                                                },
+                                                child: SvgPicture.asset(
+                                                  hidePassword
+                                                      ? Assets.svg.eye
+                                                      : Assets.svg.eyeSlash,
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark3,
+                                                  width: 16,
+                                                  height: 16,
+                                                ),
+                                              ),
+                                              const SizedBox(
+                                                width: 12,
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                      ),
+                                      onChanged: (newValue) {
+                                        if (newValue.isEmpty) {
+                                          setState(() {
+                                            passwordFeedback = "";
+                                          });
+                                          return;
+                                        }
+                                        final result =
+                                            zxcvbn.evaluate(newValue);
+                                        String suggestionsAndTips = "";
+                                        for (var sug in result
+                                            .feedback.suggestions!
+                                            .toSet()) {
+                                          suggestionsAndTips += "$sug\n";
+                                        }
+                                        suggestionsAndTips +=
+                                            result.feedback.warning!;
+                                        String feedback =
+                                            // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
+                                            suggestionsAndTips;
+
+                                        passwordStrength = result.score! / 4;
+
+                                        // hack fix to format back string returned from zxcvbn
+                                        if (feedback
+                                            .contains("phrasesNo need")) {
+                                          feedback = feedback.replaceFirst(
+                                              "phrasesNo need",
+                                              "phrases\nNo need");
+                                        }
+
+                                        if (feedback.endsWith("\n")) {
+                                          feedback = feedback.substring(
+                                              0, feedback.length - 2);
+                                        }
+
+                                        setState(() {
+                                          passwordFeedback = feedback;
+                                        });
+                                      },
+                                    ),
+                                  ),
+                                  const SizedBox(height: 16),
+                                  Text(
+                                    "Confirm new password",
+                                    style:
+                                        STextStyles.desktopTextExtraExtraSmall(
+                                                context)
+                                            .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark3),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                  const SizedBox(height: 10),
+                                  ClipRRect(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                    child: TextField(
+                                      key: const Key(
+                                          "desktopSecurityCreateNewPasswordFieldKey2"),
+                                      focusNode: passwordRepeatFocusNode,
+                                      controller: passwordRepeatController,
+                                      style: STextStyles.field(context),
+                                      obscureText: hidePassword,
+                                      enableSuggestions: false,
+                                      autocorrect: false,
+                                      decoration: standardInputDecoration(
+                                        "Confirm new password",
+                                        passwordRepeatFocusNode,
+                                        context,
+                                      ).copyWith(
+                                        labelStyle:
+                                            STextStyles.fieldLabel(context),
+                                        suffixIcon: UnconstrainedBox(
+                                          child: Row(
+                                            children: [
+                                              const SizedBox(
+                                                width: 16,
+                                              ),
+                                              GestureDetector(
+                                                key: const Key(
+                                                    "desktopSecurityCreateNewPasswordButtonKey2"),
+                                                onTap: () async {
+                                                  setState(() {
+                                                    hidePassword =
+                                                        !hidePassword;
+                                                  });
+                                                },
+                                                child: SvgPicture.asset(
+                                                  hidePassword
+                                                      ? Assets.svg.eye
+                                                      : Assets.svg.eyeSlash,
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark3,
+                                                  width: 16,
+                                                  height: 16,
+                                                ),
+                                              ),
+                                              const SizedBox(
+                                                width: 12,
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                      ),
+                                      onChanged: (newValue) {
+                                        setState(() {});
+                                      },
+                                    ),
+                                  ),
+                                  const SizedBox(height: 20),
+                                  PrimaryButton(
+                                    width: 142,
+                                    desktopMed: true,
+                                    enabled: shouldEnableSave,
+                                    label: "Save changes",
+                                    onPressed: () {
+                                      setState(() {
+                                        changePassword = false;
+                                      });
+                                    },
+                                  )
+                                ],
+                              ),
+                            )
+                          : PrimaryButton(
+                              width: 192,
+                              desktopMed: true,
+                              enabled: true,
+                              label: "Set up new password",
+                              onPressed: () {
+                                setState(() {
+                                  changePassword = true;
+                                });
+                              },
+                            ),
                     ),
                   ],
                 ),
@@ -110,29 +425,7 @@ class NewPasswordButton extends ConsumerWidget {
         style: Theme.of(context)
             .extension<StackColors>()!
             .getPrimaryEnabledButtonColor(context),
-        onPressed: () {
-          // Expandable(
-          //   header: Row(
-          //     mainAxisAlignment: MainAxisAlignment.start,
-          //     children: [
-          //       NewPasswordButton(),
-          //     ],
-          //   ),
-          //   body: Column(
-          //     mainAxisAlignment: MainAxisAlignment.start,
-          //     children: [
-          //       Text(
-          //         "Current Password",
-          //         style: STextStyles.desktopTextExtraSmall(context).copyWith(
-          //           color:
-          //               Theme.of(context).extension<StackColors>()!.textDark3,
-          //         ),
-          //         textAlign: TextAlign.left,
-          //       ),
-          //     ],
-          //   ),
-          // );
-        },
+        onPressed: () {},
         child: Text(
           "Set up new password",
           style: STextStyles.button(context),

From d084fac0571e7ac464bf322213c2a0f53e3c303c Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 11 Nov 2022 12:42:04 -0700
Subject: [PATCH 222/426] password progressbar fix

---
 .../home/settings_menu/security_settings.dart | 64 +++++++++++++++++--
 1 file changed, 58 insertions(+), 6 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index 40928a0af..9ee9b5bfc 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:zxcvbn/zxcvbn.dart';
@@ -145,15 +146,15 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
                                     child: TextField(
                                       key: const Key(
                                           "desktopSecurityRestoreFromFilePasswordFieldKey"),
-                                      focusNode: passwordFocusNode,
-                                      controller: passwordController,
+                                      focusNode: passwordCurrentFocusNode,
+                                      controller: passwordCurrentController,
                                       style: STextStyles.field(context),
                                       obscureText: hidePassword,
                                       enableSuggestions: false,
                                       autocorrect: false,
                                       decoration: standardInputDecoration(
                                         "Enter current password",
-                                        passwordFocusNode,
+                                        passwordCurrentFocusNode,
                                         context,
                                       ).copyWith(
                                         labelStyle:
@@ -214,15 +215,15 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
                                     child: TextField(
                                       key: const Key(
                                           "desktopSecurityCreateNewPasswordFieldKey1"),
-                                      focusNode: passwordCurrentFocusNode,
-                                      controller: passwordCurrentController,
+                                      focusNode: passwordFocusNode,
+                                      controller: passwordController,
                                       style: STextStyles.field(context),
                                       obscureText: hidePassword,
                                       enableSuggestions: false,
                                       autocorrect: false,
                                       decoration: standardInputDecoration(
                                         "Enter new password",
-                                        passwordCurrentFocusNode,
+                                        passwordFocusNode,
                                         context,
                                       ).copyWith(
                                         labelStyle:
@@ -302,6 +303,57 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
                                       },
                                     ),
                                   ),
+                                  if (passwordFocusNode.hasFocus ||
+                                      passwordRepeatFocusNode.hasFocus ||
+                                      passwordController.text.isNotEmpty)
+                                    Padding(
+                                      padding: EdgeInsets.only(
+                                        left: 12,
+                                        right: 12,
+                                        top:
+                                            passwordFeedback.isNotEmpty ? 4 : 0,
+                                      ),
+                                      child: passwordFeedback.isNotEmpty
+                                          ? Text(
+                                              passwordFeedback,
+                                              style: STextStyles.infoSmall(
+                                                  context),
+                                            )
+                                          : null,
+                                    ),
+                                  if (passwordFocusNode.hasFocus ||
+                                      passwordRepeatFocusNode.hasFocus ||
+                                      passwordController.text.isNotEmpty)
+                                    Padding(
+                                      padding: const EdgeInsets.only(
+                                        left: 12,
+                                        right: 12,
+                                        top: 10,
+                                      ),
+                                      child: ProgressBar(
+                                        key: const Key(
+                                            "desktopSecurityCreateStackBackUpProgressBar"),
+                                        width: 450,
+                                        height: 5,
+                                        fillColor: passwordStrength < 0.51
+                                            ? Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .accentColorRed
+                                            : passwordStrength < 1
+                                                ? Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .accentColorYellow
+                                                : Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .accentColorGreen,
+                                        backgroundColor: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .buttonBackSecondary,
+                                        percent: passwordStrength < 0.25
+                                            ? 0.03
+                                            : passwordStrength,
+                                      ),
+                                    ),
                                   const SizedBox(height: 16),
                                   Text(
                                     "Confirm new password",

From 7798ed39a06912425fc6c97bfbb6a6d021f1ed04 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 11 Nov 2022 15:58:47 -0700
Subject: [PATCH 223/426] desktop address book with no contacts

---
 assets/svg/plus-circle.svg                    | 12 +++
 .../desktop_address_book.dart                 | 84 ++++++++++++++++++-
 lib/utilities/assets.dart                     |  1 +
 pubspec.yaml                                  |  1 +
 4 files changed, 95 insertions(+), 3 deletions(-)
 create mode 100644 assets/svg/plus-circle.svg

diff --git a/assets/svg/plus-circle.svg b/assets/svg/plus-circle.svg
new file mode 100644
index 000000000..e673b9b0e
--- /dev/null
+++ b/assets/svg/plus-circle.svg
@@ -0,0 +1,12 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_5370_82626)">
+<path d="M9.99935 18.3337C14.6017 18.3337 18.3327 14.6027 18.3327 10.0003C18.3327 5.39795 14.6017 1.66699 9.99935 1.66699C5.39698 1.66699 1.66602 5.39795 1.66602 10.0003C1.66602 14.6027 5.39698 18.3337 9.99935 18.3337Z" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10 6.66699V13.3337" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M6.66602 10H13.3327" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_5370_82626">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index 3622fcf1e..dd38b98a8 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -1,12 +1,15 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/utilities/assets.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/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
@@ -24,6 +27,11 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
 
   late final FocusNode _searchFocusNode;
 
+  List<Contact>? _cache;
+  List<Contact>? _cacheFav;
+
+  late bool hasContacts = false;
+
   String filter = "";
 
   @override
@@ -49,6 +57,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
 
     return Column(
       mainAxisSize: MainAxisSize.min,
+      crossAxisAlignment: CrossAxisAlignment.start,
       children: [
         DesktopAppBar(
           isCompactHeight: true,
@@ -127,12 +136,81 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                   ),
                 ),
               ),
+              const SizedBox(width: 20),
+              TextButton(
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getDesktopMenuButtonColorSelected(context),
+                onPressed: () {},
+                child: SizedBox(
+                  width: 200,
+                  height: 56,
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      Padding(
+                        padding: const EdgeInsets.symmetric(horizontal: 10),
+                        child: SvgPicture.asset(Assets.svg.filter),
+                      ),
+                      Text(
+                        "Filter",
+                        style: STextStyles.desktopTextExtraExtraSmall(context)
+                            .copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark,
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              const SizedBox(width: 20),
+              TextButton(
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getPrimaryEnabledButtonColor(context),
+                onPressed: () {},
+                child: SizedBox(
+                  width: 200,
+                  height: 56,
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      Padding(
+                        padding: const EdgeInsets.symmetric(horizontal: 10),
+                        child: SvgPicture.asset(Assets.svg.circlePlus),
+                      ),
+                      Text(
+                        "Add new",
+                        style: STextStyles.desktopTextExtraExtraSmall(context)
+                            .copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .popupBG,
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+              ),
             ],
           ),
         ),
-        // Expanded(
-        //   child: hasWallets ? const MyWallets() : const EmptyWallets(),
-        // ),
+        Padding(
+          padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 26),
+          child: SizedBox(
+            width: 489,
+            child: RoundedWhiteContainer(
+              child: Center(
+                child: Text(
+                  "Your contacts will appear here",
+                  style: STextStyles.itemSubtitle(context),
+                ),
+              ),
+            ),
+          ),
+        ),
       ],
     );
   }
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index f853a00d8..e76a17c12 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -59,6 +59,7 @@ class _SVG {
   String txExchangeFailed(BuildContext context) =>
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
 
+  String get circlePlus => "assets/svg/plus-circle.svg";
   String get framedGear => "assets/svg/framed-gear.svg";
   String get framedAddressBook => "assets/svg/framed-address-book.svg";
   String get themeLight => "assets/svg/light/light-mode.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index 8b03cd57e..fd1c8a9b5 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -314,6 +314,7 @@ flutter:
     - assets/svg/exit-desktop.svg
     - assets/svg/keys.svg
     - assets/svg/arrow-down.svg
+    - assets/svg/plus-circle.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Litecoin.svg

From f08a52cd0748a2a085724b21d4f5c3aa926c27d3 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 12 Nov 2022 09:16:07 -0600
Subject: [PATCH 224/426] remove direct dependency of unused SharedPreferences

---
 lib/services/coins/monero/monero_wallet.dart  |  8 ---
 .../coins/wownero/wownero_wallet.dart         |  8 ---
 pubspec.lock                                  |  2 +-
 pubspec.yaml                                  |  2 +-
 .../coins/monero/monero_wallet_test.dart      | 53 ++++++++++---------
 .../coins/wownero/wownero_wallet_test.dart    | 24 ++++-----
 6 files changed, 42 insertions(+), 55 deletions(-)

diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index fd8f9a79e..caf1185a5 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -26,7 +26,6 @@ import 'package:flutter_libmonero/view_model/send/output.dart' as monero_output;
 import 'package:http/http.dart';
 import 'package:mutex/mutex.dart';
 import 'package:path_provider/path_provider.dart';
-import 'package:shared_preferences/shared_preferences.dart';
 import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/models/paymint/fee_object_model.dart';
@@ -671,7 +670,6 @@ class MoneroWallet extends CoinServiceAPI {
 
     walletService =
         monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
-    prefs = await SharedPreferences.getInstance();
     keysStorage = KeyService(_secureStore);
     WalletInfo walletInfo;
     WalletCredentials credentials;
@@ -707,7 +705,6 @@ class MoneroWallet extends CoinServiceAPI {
 
       _walletCreationService = WalletCreationService(
         secureStorage: _secureStore,
-        sharedPreferences: prefs,
         walletService: walletService,
         keyService: keysStorage,
       );
@@ -788,7 +785,6 @@ class MoneroWallet extends CoinServiceAPI {
 
     walletService =
         monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
-    prefs = await SharedPreferences.getInstance();
     keysStorage = KeyService(_secureStore);
 
     await _generateNewWallet();
@@ -833,7 +829,6 @@ class MoneroWallet extends CoinServiceAPI {
 
     walletService =
         monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
-    prefs = await SharedPreferences.getInstance();
     keysStorage = KeyService(_secureStore);
 
     await _prefs.init();
@@ -888,7 +883,6 @@ class MoneroWallet extends CoinServiceAPI {
   // TODO: are these needed?
 
   WalletService? walletService;
-  SharedPreferences? prefs;
   KeyService? keysStorage;
   MoneroWalletBase? walletBase;
   WalletCreationService? _walletCreationService;
@@ -969,7 +963,6 @@ class MoneroWallet extends CoinServiceAPI {
 
       walletService =
           monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
-      prefs = await SharedPreferences.getInstance();
       keysStorage = KeyService(_secureStore);
       WalletInfo walletInfo;
       WalletCredentials credentials;
@@ -998,7 +991,6 @@ class MoneroWallet extends CoinServiceAPI {
 
         _walletCreationService = WalletCreationService(
           secureStorage: _secureStore,
-          sharedPreferences: prefs,
           walletService: walletService,
           keyService: keysStorage,
         );
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index d03733edb..8f36352d0 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -27,7 +27,6 @@ import 'package:flutter_libmonero/wownero/wownero.dart';
 import 'package:http/http.dart';
 import 'package:mutex/mutex.dart';
 import 'package:path_provider/path_provider.dart';
-import 'package:shared_preferences/shared_preferences.dart';
 import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/models/paymint/fee_object_model.dart';
@@ -673,7 +672,6 @@ class WowneroWallet extends CoinServiceAPI {
     // TODO: Wallet Service may need to be switched to Wownero
     walletService =
         wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
-    prefs = await SharedPreferences.getInstance();
     keysStorage = KeyService(_secureStore);
     WalletInfo walletInfo;
     WalletCredentials credentials;
@@ -700,7 +698,6 @@ class WowneroWallet extends CoinServiceAPI {
 
       _walletCreationService = WalletCreationService(
         secureStorage: _secureStore,
-        sharedPreferences: prefs,
         walletService: walletService,
         keyService: keysStorage,
       );
@@ -792,7 +789,6 @@ class WowneroWallet extends CoinServiceAPI {
     // }
     walletService =
         wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
-    prefs = await SharedPreferences.getInstance();
     keysStorage = KeyService(_secureStore);
 
     await _generateNewWallet(seedWordsLength: seedWordsLength);
@@ -837,7 +833,6 @@ class WowneroWallet extends CoinServiceAPI {
 
     walletService =
         wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
-    prefs = await SharedPreferences.getInstance();
     keysStorage = KeyService(_secureStore);
 
     await _prefs.init();
@@ -892,7 +887,6 @@ class WowneroWallet extends CoinServiceAPI {
   // TODO: are these needed?
 
   WalletService? walletService;
-  SharedPreferences? prefs;
   KeyService? keysStorage;
   WowneroWalletBase? walletBase;
   WalletCreationService? _walletCreationService;
@@ -990,7 +984,6 @@ class WowneroWallet extends CoinServiceAPI {
 
       walletService =
           wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
-      prefs = await SharedPreferences.getInstance();
       keysStorage = KeyService(_secureStore);
       WalletInfo walletInfo;
       WalletCredentials credentials;
@@ -1019,7 +1012,6 @@ class WowneroWallet extends CoinServiceAPI {
 
         _walletCreationService = WalletCreationService(
           secureStorage: _secureStore,
-          sharedPreferences: prefs,
           walletService: walletService,
           keyService: keysStorage,
         );
diff --git a/pubspec.lock b/pubspec.lock
index 2f7770d3a..0b8f49c2c 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1244,7 +1244,7 @@ packages:
     source: hosted
     version: "3.0.1"
   shared_preferences:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: shared_preferences
       url: "https://pub.dartlang.org"
diff --git a/pubspec.yaml b/pubspec.yaml
index b7947a58d..8a41a4edd 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -126,7 +126,7 @@ dependencies:
   pointycastle: ^3.6.0
   package_info_plus: ^1.4.2
   lottie: ^1.3.0
-  shared_preferences: ^2.0.15
+#  shared_preferences: ^2.0.15
   file_picker: ^5.0.1
   connectivity_plus: 2.3.6+1
 #  document_file_save_plus: ^1.0.5
diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index 79bf98a41..789d91cb1 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -19,7 +19,6 @@ import 'package:hive/hive.dart';
 import 'package:hive_test/hive_test.dart';
 import 'package:mockito/annotations.dart';
 import 'package:path_provider/path_provider.dart';
-import 'package:shared_preferences/shared_preferences.dart';
 import 'package:stackwallet/services/wallets.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
@@ -27,10 +26,8 @@ import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 import 'monero_wallet_test_data.dart';
 
-//FlutterSecureStorage? storage;
 FakeSecureStorage? storage;
 WalletService? walletService;
-SharedPreferences? prefs;
 KeyService? keysStorage;
 MoneroWalletBase? walletBase;
 late WalletCreationService _walletCreationService;
@@ -46,7 +43,6 @@ WalletType type = WalletType.monero;
 @GenerateMocks([])
 void main() async {
   storage = FakeSecureStorage();
-  prefs = await SharedPreferences.getInstance();
   keysStorage = KeyService(storage!);
   WalletInfo walletInfo = WalletInfo.external(
       id: '',
@@ -90,12 +86,12 @@ void main() async {
         final dirPath = await pathForWalletDir(name: name, type: type);
         path = await pathForWallet(name: name, type: type);
         credentials =
-        // //     creating a new wallet
-        // monero.createMoneroNewWalletCredentials(
-        //     name: name, language: "English");
-        // restoring a previous wallet
-        monero.createMoneroRestoreWalletFromSeedCredentials(
-            name: name, height: 2580000, mnemonic: testMnemonic);
+            // //     creating a new wallet
+            // monero.createMoneroNewWalletCredentials(
+            //     name: name, language: "English");
+            // restoring a previous wallet
+            monero.createMoneroRestoreWalletFromSeedCredentials(
+                name: name, height: 2580000, mnemonic: testMnemonic);
 
         walletInfo = WalletInfo.external(
             id: WalletBase.idFor(name, type),
@@ -111,7 +107,6 @@ void main() async {
 
         _walletCreationService = WalletCreationService(
           secureStorage: storage,
-          sharedPreferences: prefs,
           walletService: walletService,
           keyService: keysStorage,
         );
@@ -124,8 +119,8 @@ void main() async {
 
     test("Test mainnet address generation from seed", () async {
       final wallet = await
-      // _walletCreationService.create(credentials);
-      _walletCreationService.restoreFromSeed(credentials);
+          // _walletCreationService.create(credentials);
+          _walletCreationService.restoreFromSeed(credentials);
       walletInfo.address = wallet.walletAddresses.address;
       //print(walletInfo.address);
 
@@ -134,8 +129,7 @@ void main() async {
       walletBase = wallet as MoneroWalletBase;
       //print("${walletBase?.seed}");
 
-      expect(
-          await walletBase!.validateAddress(walletInfo.address ?? ''), true);
+      expect(await walletBase!.validateAddress(walletInfo.address ?? ''), true);
 
       // print(walletBase);
       // loggerPrint(walletBase.toString());
@@ -157,20 +151,31 @@ void main() async {
       expect(
           await walletBase!.getTransactionAddress(1, 2), mainnetTestData[1][2]);
 
+      expect(await walletBase!.validateAddress(''), false);
       expect(
-          await walletBase!.validateAddress(''), false);
+          await walletBase!.validateAddress(
+              '4AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'),
+          true);
       expect(
-          await walletBase!.validateAddress('4AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), true);
+          await walletBase!.validateAddress(
+              '4asdfkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gpjkl'),
+          false);
       expect(
-          await walletBase!.validateAddress('4asdfkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gpjkl'), false);
+          await walletBase!.validateAddress(
+              '8AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'),
+          false);
       expect(
-          await walletBase!.validateAddress('8AeRgkWZsMJhAWKMeCZ3h4ZSPnAcW5VBtRFyLd6gBEf6GgJU2FHXDA6i1DnQTd6h8R3VU5AkbGcWSNhtSwNNPgaD48gp4nn'), false);
+          await walletBase!.validateAddress(
+              '84kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'),
+          true);
       expect(
-          await walletBase!.validateAddress('84kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), true);
+          await walletBase!.validateAddress(
+              '8asdfuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenjkl'),
+          false);
       expect(
-          await walletBase!.validateAddress('8asdfuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenjkl'), false);
-      expect(
-          await walletBase!.validateAddress('44kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'), false);
+          await walletBase!.validateAddress(
+              '44kYPuZ1eaVKGQhf26QPNWbSLQG16BywXdLYYShVrPNMLAUAWce5vcpRc78FxwRphrG6Cda7faCKdUMr8fUCH3peHPenvHy'),
+          false);
     });
   });
   /*
@@ -229,6 +234,6 @@ Future<String> pathForWalletDir(
 }
 
 Future<String> pathForWallet(
-    {required String name, required WalletType type}) async =>
+        {required String name, required WalletType type}) async =>
     await pathForWalletDir(name: name, type: type)
         .then((path) => path + '/$name');
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 78a9c56c1..8ffb590fc 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -19,14 +19,12 @@ import 'package:hive/hive.dart';
 import 'package:hive_test/hive_test.dart';
 import 'package:mockito/annotations.dart';
 import 'package:path_provider/path_provider.dart';
-import 'package:shared_preferences/shared_preferences.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 import 'wownero_wallet_test_data.dart';
 
 FakeSecureStorage? storage;
 WalletService? walletService;
-SharedPreferences? prefs;
 KeyService? keysStorage;
 WowneroWalletBase? walletBase;
 late WalletCreationService _walletCreationService;
@@ -41,7 +39,6 @@ WalletType type = WalletType.wownero;
 @GenerateMocks([])
 void main() async {
   storage = FakeSecureStorage();
-  prefs = await SharedPreferences.getInstance();
   keysStorage = KeyService(storage!);
   WalletInfo walletInfo = WalletInfo.external(
       id: '',
@@ -102,7 +99,6 @@ void main() async {
 
         _walletCreationService = WalletCreationService(
           secureStorage: storage,
-          sharedPreferences: prefs,
           walletService: walletService,
           keyService: keysStorage,
         );
@@ -127,19 +123,24 @@ void main() async {
         walletBase = wallet as WowneroWalletBase;
 
         expect(
-            await walletBase!.validateAddress(wallet.walletAddresses.address ?? ''), true);
+            await walletBase!
+                .validateAddress(wallet.walletAddresses.address ?? ''),
+            true);
       } catch (_) {
         hasThrown = true;
       }
       expect(hasThrown, false);
 
       // Address validation
+      expect(await walletBase!.validateAddress(''), false);
       expect(
-          await walletBase!.validateAddress(''), false);
+          await walletBase!.validateAddress(
+              'Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi'),
+          true);
       expect(
-          await walletBase!.validateAddress('Wo3jmHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmsEi'), true);
-      expect(
-          await walletBase!.validateAddress('WasdfHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmjkl'), false);
+          await walletBase!.validateAddress(
+              'WasdfHvTMLwE6h29fpgcb8PbJSpaKuqM7XTXVfiiu8bLCZsJvrQCbQSJR48Vo3BWNQKsMsXZ4VixndXTH25QtorC27NCjmjkl'),
+          false);
 
       walletBase?.close();
       walletBase = wallet as WowneroWalletBase;
@@ -174,7 +175,6 @@ void main() async {
 
         _walletCreationService = WalletCreationService(
           secureStorage: storage,
-          sharedPreferences: prefs,
           walletService: walletService,
           keyService: keysStorage,
         );
@@ -248,7 +248,6 @@ void main() async {
 
         _walletCreationService = WalletCreationService(
           secureStorage: storage,
-          sharedPreferences: prefs,
           walletService: walletService,
           keyService: keysStorage,
         );
@@ -312,7 +311,6 @@ void main() async {
 
         _walletCreationService = WalletCreationService(
           secureStorage: storage,
-          sharedPreferences: prefs,
           walletService: walletService,
           keyService: keysStorage,
         );
@@ -367,6 +365,6 @@ Future<String> pathForWalletDir(
 }
 
 Future<String> pathForWallet(
-    {required String name, required WalletType type}) async =>
+        {required String name, required WalletType type}) async =>
     await pathForWalletDir(name: name, type: type)
         .then((path) => path + '/$name');

From 5d8a1b030450064a92b3486f3ab00dc2e95ae710 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 12 Nov 2022 09:17:16 -0600
Subject: [PATCH 225/426] trim unused import

---
 test/services/coins/monero/monero_wallet_test.dart   | 3 ---
 test/services/coins/wownero/wownero_wallet_test.dart | 1 -
 2 files changed, 4 deletions(-)

diff --git a/test/services/coins/monero/monero_wallet_test.dart b/test/services/coins/monero/monero_wallet_test.dart
index 789d91cb1..d6d600e36 100644
--- a/test/services/coins/monero/monero_wallet_test.dart
+++ b/test/services/coins/monero/monero_wallet_test.dart
@@ -1,5 +1,4 @@
 import 'dart:core';
-import 'dart:core' as core;
 import 'dart:io';
 import 'dart:math';
 
@@ -22,8 +21,6 @@ import 'package:path_provider/path_provider.dart';
 import 'package:stackwallet/services/wallets.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
-// TODO trim down to the minimum imports above
-
 import 'monero_wallet_test_data.dart';
 
 FakeSecureStorage? storage;
diff --git a/test/services/coins/wownero/wownero_wallet_test.dart b/test/services/coins/wownero/wownero_wallet_test.dart
index 8ffb590fc..637a40b81 100644
--- a/test/services/coins/wownero/wownero_wallet_test.dart
+++ b/test/services/coins/wownero/wownero_wallet_test.dart
@@ -1,5 +1,4 @@
 import 'dart:core';
-import 'dart:core' as core;
 import 'dart:io';
 import 'dart:math';
 

From ca6578d367b7574bc0b2fd486e7d1afec32b8940 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Sat, 12 Nov 2022 11:10:46 -0700
Subject: [PATCH 226/426] desktop address book filter dialog

---
 .../subviews/address_book_filter_view.dart    | 356 ++++++++++--------
 .../desktop_address_book.dart                 |  21 +-
 2 files changed, 229 insertions(+), 148 deletions(-)

diff --git a/lib/pages/address_book_views/subviews/address_book_filter_view.dart b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
index 35968621a..df779331e 100644
--- a/lib/pages/address_book_views/subviews/address_book_filter_view.dart
+++ b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
@@ -5,7 +5,12 @@ import 'package:stackwallet/providers/ui/address_book_providers/address_book_fil
 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/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/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class AddressBookFilterView extends ConsumerStatefulWidget {
@@ -41,167 +46,224 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Filter addresses",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(12),
-        child: LayoutBuilder(builder: (builderContext, constraints) {
-          return SingleChildScrollView(
-            child: ConstrainedBox(
-              constraints: BoxConstraints(
-                minHeight: constraints.maxHeight,
+    final isDesktop = Util.isDesktop;
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            leading: AppBarBackButton(
+              onPressed: () async {
+                Navigator.of(context).pop();
+              },
+            ),
+            title: Text(
+              "Filter addresses",
+              style: STextStyles.navBarTitle(context),
+            ),
+          ),
+          body: Padding(
+            padding: const EdgeInsets.all(12),
+            child: LayoutBuilder(builder: (builderContext, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          RoundedWhiteContainer(
+                            child: Text(
+                              "Only selected cryptocurrency addresses will be displayed.",
+                              style: STextStyles.itemSubtitle(context),
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          Text(
+                            "Select cryptocurrency",
+                            style: STextStyles.smallMed12(context),
+                          ),
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          child,
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+              );
+            }),
+          ),
+        );
+      },
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) {
+          return Column(
+            children: [
+              Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Padding(
+                    padding: const EdgeInsets.all(32),
+                    child: Text(
+                      "Select cryptocurrency",
+                      style: STextStyles.desktopH3(context),
+                      textAlign: TextAlign.center,
+                    ),
+                  ),
+                  const DesktopDialogCloseButton(),
+                ],
               ),
-              child: IntrinsicHeight(
-                child: Padding(
-                  padding: const EdgeInsets.all(4),
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      RoundedWhiteContainer(
-                        child: Text(
-                          "Only selected cryptocurrency addresses will be displayed.",
-                          style: STextStyles.itemSubtitle(context),
+              Expanded(
+                child: LayoutBuilder(
+                  builder: (context, constraints) {
+                    return SingleChildScrollView(
+                      scrollDirection: Axis.vertical,
+                      child: ConstrainedBox(
+                        constraints: BoxConstraints(
+                          minHeight: constraints.maxHeight,
+                        ),
+                        child: IntrinsicHeight(
+                          child: Column(
+                            children: [
+                              Padding(
+                                padding:
+                                    const EdgeInsets.symmetric(horizontal: 32),
+                                child: child,
+                              ),
+                            ],
+                          ),
                         ),
                       ),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      Text(
-                        "Select cryptocurrency",
-                        style: STextStyles.smallMed12(context),
-                      ),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      RoundedWhiteContainer(
-                        padding: const EdgeInsets.all(0),
-                        child: Wrap(
-                          children: [
-                            ..._coins.map(
-                              (coin) => Row(
-                                children: [
-                                  GestureDetector(
-                                    onTap: () {
-                                      if (ref
-                                          .read(addressBookFilterProvider)
-                                          .coins
-                                          .contains(coin)) {
-                                        ref
-                                            .read(addressBookFilterProvider)
-                                            .remove(coin, true);
-                                      } else {
+                    );
+                  },
+                ),
+              ),
+              Padding(
+                padding:
+                    const EdgeInsets.symmetric(horizontal: 32, vertical: 32),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    SecondaryButton(
+                      width: 248,
+                      desktopMed: true,
+                      enabled: true,
+                      label: "Cancel",
+                      onPressed: () {
+                        Navigator.of(context).pop();
+                      },
+                    ),
+                    // const SizedBox(width: 16),
+                    PrimaryButton(
+                      width: 248,
+                      desktopMed: true,
+                      enabled: true,
+                      label: "Apply",
+                      onPressed: () {
+                        Navigator.of(context).pop();
+                      },
+                    ),
+                  ],
+                ),
+              ),
+            ],
+          );
+        },
+        child: RoundedWhiteContainer(
+          padding: const EdgeInsets.all(0),
+          child: Wrap(
+            children: [
+              ..._coins.map(
+                (coin) => Row(
+                  children: [
+                    GestureDetector(
+                      onTap: () {
+                        if (ref
+                            .read(addressBookFilterProvider)
+                            .coins
+                            .contains(coin)) {
+                          ref
+                              .read(addressBookFilterProvider)
+                              .remove(coin, true);
+                        } else {
+                          ref.read(addressBookFilterProvider).add(coin, true);
+                        }
+                        setState(() {});
+                      },
+                      child: Container(
+                        color: Colors.transparent,
+                        child: Padding(
+                          padding: const EdgeInsets.all(12),
+                          child: Row(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              SizedBox(
+                                height: 20,
+                                width: 20,
+                                child: Checkbox(
+                                  value: ref
+                                      .watch(addressBookFilterProvider
+                                          .select((value) => value.coins))
+                                      .contains(coin),
+                                  onChanged: (value) {
+                                    if (value is bool) {
+                                      if (value) {
                                         ref
                                             .read(addressBookFilterProvider)
                                             .add(coin, true);
+                                      } else {
+                                        ref
+                                            .read(addressBookFilterProvider)
+                                            .remove(coin, true);
                                       }
                                       setState(() {});
-                                    },
-                                    child: Container(
-                                      color: Colors.transparent,
-                                      child: Padding(
-                                        padding: const EdgeInsets.all(12),
-                                        child: Row(
-                                          crossAxisAlignment:
-                                              CrossAxisAlignment.start,
-                                          children: [
-                                            SizedBox(
-                                              height: 20,
-                                              width: 20,
-                                              child: Checkbox(
-                                                value: ref
-                                                    .watch(
-                                                        addressBookFilterProvider
-                                                            .select((value) =>
-                                                                value.coins))
-                                                    .contains(coin),
-                                                onChanged: (value) {
-                                                  if (value is bool) {
-                                                    if (value) {
-                                                      ref
-                                                          .read(
-                                                              addressBookFilterProvider)
-                                                          .add(coin, true);
-                                                    } else {
-                                                      ref
-                                                          .read(
-                                                              addressBookFilterProvider)
-                                                          .remove(coin, true);
-                                                    }
-                                                    setState(() {});
-                                                  }
-                                                },
-                                              ),
-                                            ),
-                                            const SizedBox(
-                                              width: 12,
-                                            ),
-                                            Column(
-                                              crossAxisAlignment:
-                                                  CrossAxisAlignment.start,
-                                              children: [
-                                                Text(
-                                                  coin.prettyName,
-                                                  style:
-                                                      STextStyles.largeMedium14(
-                                                          context),
-                                                ),
-                                                const SizedBox(
-                                                  height: 2,
-                                                ),
-                                                Text(
-                                                  coin.ticker,
-                                                  style:
-                                                      STextStyles.itemSubtitle(
-                                                          context),
-                                                ),
-                                              ],
-                                            )
-                                          ],
-                                        ),
-                                      ),
-                                    ),
+                                    }
+                                  },
+                                ),
+                              ),
+                              const SizedBox(
+                                width: 12,
+                              ),
+                              Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    coin.prettyName,
+                                    style: STextStyles.largeMedium14(context),
+                                  ),
+                                  const SizedBox(
+                                    height: 2,
+                                  ),
+                                  Text(
+                                    coin.ticker,
+                                    style: STextStyles.itemSubtitle(context),
                                   ),
                                 ],
-                              ),
-                            ),
-                          ],
+                              )
+                            ],
+                          ),
                         ),
                       ),
-                      const Spacer(),
-                      // Row(
-                      //   children: [
-                      //     TextButton(
-                      //       onPressed: () {},
-                      //       child: Text("Cancel"),
-                      //     ),
-                      //     SizedBox(
-                      //       width: 16,
-                      //     ),
-                      //     TextButton(
-                      //       onPressed: () {},
-                      //       child: Text("Cancel"),
-                      //     ),
-                      //   ],
-                      // )
-                    ],
-                  ),
+                    ),
+                  ],
                 ),
               ),
-            ),
-          );
-        }),
+            ],
+          ),
+        ),
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index dd38b98a8..367671a3e 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -2,12 +2,14 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/contact.dart';
+import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/utilities/assets.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/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
@@ -34,6 +36,21 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
 
   String filter = "";
 
+  Future<void> selectCryptocurrency() async {
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) {
+        return DesktopDialog(
+          maxHeight: 609,
+          maxWidth: 576,
+          child: AddressBookFilterView(),
+        );
+      },
+    );
+  }
+
   @override
   void initState() {
     _searchController = TextEditingController();
@@ -141,7 +158,9 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                 style: Theme.of(context)
                     .extension<StackColors>()!
                     .getDesktopMenuButtonColorSelected(context),
-                onPressed: () {},
+                onPressed: () {
+                  selectCryptocurrency();
+                },
                 child: SizedBox(
                   width: 200,
                   height: 56,

From 0164679cceac10602ceda50a8f93f8004fc076b1 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 12 Nov 2022 16:04:16 -0600
Subject: [PATCH 227/426] File system path clean up

---
 lib/main.dart                                 | 24 ++-----
 .../advanced_views/debug_view.dart            | 23 +++----
 .../create_auto_backup_view.dart              |  6 +-
 .../create_backup_view.dart                   |  6 +-
 .../edit_auto_backup_view.dart                |  6 +-
 ..._file_system.dart => swb_file_system.dart} |  5 +-
 .../restore_from_file_view.dart               |  9 ++-
 .../create_auto_backup.dart                   |  7 +-
 .../coins/epiccash/epiccash_wallet.dart       | 27 ++++----
 lib/services/coins/monero/monero_wallet.dart  | 12 +---
 .../coins/wownero/wownero_wallet.dart         | 11 +---
 .../flutter_secure_storage_interface.dart     | 10 +--
 lib/utilities/stack_file_system.dart          | 66 +++++++++++++++++++
 13 files changed, 119 insertions(+), 93 deletions(-)
 rename lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/{stack_file_system.dart => swb_file_system.dart} (95%)
 create mode 100644 lib/utilities/stack_file_system.dart

diff --git a/lib/main.dart b/lib/main.dart
index 70f80e8ed..21abd9df7 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -53,6 +53,7 @@ import 'package:stackwallet/utilities/db_version_migration.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/utilities/stack_file_system.dart';
 import 'package:stackwallet/utilities/theme/color_theme.dart';
 import 'package:stackwallet/utilities/theme/dark_colors.dart';
 import 'package:stackwallet/utilities/theme/light_colors.dart';
@@ -79,29 +80,11 @@ void main() async {
     setWindowMaxSize(Size.infinite);
   }
 
-  Directory appDirectory = (await getApplicationDocumentsDirectory());
-  if (Platform.isIOS) {
-    appDirectory = (await getLibraryDirectory());
-  }
-
-  if (Logging.isArmLinux) {
-    appDirectory = Directory("${appDirectory.path}/.stackwallet");
-    await appDirectory.create();
-  }
-
-  if (Platform.isLinux) {
-    appDirectory = Directory("${Platform.environment['HOME']}/.stackwallet");
-
-    if (!appDirectory.existsSync()) {
-      await appDirectory.create();
-    }
-  }
-
   // FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
   if (!(Logging.isArmLinux || Logging.isTestEnv)) {
     final isar = await Isar.open(
       [LogSchema],
-      directory: appDirectory.path,
+      directory: (await StackFileSystem.applicationIsarDirectory()).path,
       inspector: false,
     );
     await Logging.instance.init(isar);
@@ -150,7 +133,8 @@ void main() async {
   Hive.registerAdapter(WalletTypeAdapter());
 
   Hive.registerAdapter(UnspentCoinsInfoAdapter());
-  await Hive.initFlutter(appDirectory.path);
+  await Hive.initFlutter(
+      (await StackFileSystem.applicationHiveDirectory()).path);
 
   await Hive.openBox<dynamic>(DB.boxNameDBInfo);
 
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 a3aa925a0..055773ef6 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
@@ -7,19 +7,25 @@ import 'package:event_bus/event_bus.dart';
 import 'package:file_picker/file_picker.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
+import 'package:flutter_libepiccash/git_versions.dart' as EPIC_VERSIONS;
+import 'package:flutter_libmonero/git_versions.dart' as MONERO_VERSIONS;
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:lelantus/git_versions.dart' as FIRO_VERSIONS;
 import 'package:package_info_plus/package_info_plus.dart';
-import 'package:path_provider/path_provider.dart';
 import 'package:stackwallet/models/isar/models/log.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart';
 import 'package:stackwallet/providers/global/debug_service_provider.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/flush_bar_type.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/utilities/stack_file_system.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/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';
@@ -28,15 +34,6 @@ import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
-import 'package:flutter_libepiccash/git_versions.dart' as EPIC_VERSIONS;
-import 'package:flutter_libmonero/git_versions.dart' as MONERO_VERSIONS;
-import 'package:lelantus/git_versions.dart' as FIRO_VERSIONS;
-
-import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
-
-import 'package:stackwallet/utilities/clipboard_interface.dart';
-
-import 'package:stackwallet/utilities/util.dart';
 
 class DebugView extends ConsumerStatefulWidget {
   const DebugView({Key? key}) : super(key: key);
@@ -352,10 +349,10 @@ class _DebugViewState extends ConsumerState<DebugView> {
                             BlueTextButton(
                               text: "Save logs to file",
                               onTap: () async {
-                                final systemfile = StackFileSystem();
+                                final systemfile = SWBFileSystem();
                                 await systemfile.prepareStorage();
-                                Directory rootPath =
-                                    (await getApplicationDocumentsDirectory());
+                                Directory rootPath = await StackFileSystem
+                                    .applicationRootDirectory();
 
                                 if (Platform.isAndroid) {
                                   rootPath = Directory("/storage/emulated/0/");
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
index 334d50e35..bf8bd40e7 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
@@ -9,7 +9,7 @@ import 'package:stack_wallet_backup/stack_wallet_backup.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
-import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/backup_frequency_type_select_sheet.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/providers/global/secure_store_provider.dart';
@@ -49,7 +49,7 @@ class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
 
   late final FocusNode passwordFocusNode;
   late final FocusNode passwordRepeatFocusNode;
-  late final StackFileSystem stackFileSystem;
+  late final SWBFileSystem stackFileSystem;
   final zxcvbn = Zxcvbn();
 
   String passwordFeedback =
@@ -70,7 +70,7 @@ class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
   @override
   void initState() {
     secureStore = ref.read(secureStoreProvider);
-    stackFileSystem = StackFileSystem();
+    stackFileSystem = SWBFileSystem();
     fileLocationController = TextEditingController();
     passwordController = TextEditingController();
     passwordRepeatController = TextEditingController();
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index fc4719fe1..b7ee6b4be 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -7,7 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
-import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart';
 import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -41,7 +41,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
 
   late final FocusNode passwordFocusNode;
   late final FocusNode passwordRepeatFocusNode;
-  late final StackFileSystem stackFileSystem;
+  late final SWBFileSystem stackFileSystem;
   final zxcvbn = Zxcvbn();
 
   String passwordFeedback =
@@ -61,7 +61,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
 
   @override
   void initState() {
-    stackFileSystem = StackFileSystem();
+    stackFileSystem = SWBFileSystem();
     fileLocationController = TextEditingController();
     passwordController = TextEditingController();
     passwordRepeatController = TextEditingController();
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
index 0be718549..4d3c6ca99 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
@@ -9,7 +9,7 @@ import 'package:stack_wallet_backup/stack_wallet_backup.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/auto_backup_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
-import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/backup_frequency_type_select_sheet.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/providers/global/secure_store_provider.dart';
@@ -48,7 +48,7 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
 
   late final FocusNode passwordFocusNode;
   late final FocusNode passwordRepeatFocusNode;
-  late final StackFileSystem stackFileSystem;
+  late final SWBFileSystem stackFileSystem;
   final zxcvbn = Zxcvbn();
 
   String passwordFeedback =
@@ -69,7 +69,7 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
   @override
   void initState() {
     secureStore = ref.read(secureStoreProvider);
-    stackFileSystem = StackFileSystem();
+    stackFileSystem = SWBFileSystem();
     fileLocationController = TextEditingController();
     passwordController = TextEditingController();
     passwordRepeatController = TextEditingController();
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart
similarity index 95%
rename from lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart
rename to lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart
index e57c5493f..82d3fd97d 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart
@@ -4,15 +4,16 @@ import 'package:file_picker/file_picker.dart';
 import 'package:flutter/material.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:permission_handler/permission_handler.dart';
+import 'package:stackwallet/utilities/util.dart';
 
-class StackFileSystem {
+class SWBFileSystem {
   Directory? rootPath;
   Directory? startPath;
 
   String? filePath;
   String? dirPath;
 
-  final bool isDesktop = !(Platform.isAndroid || Platform.isIOS);
+  final bool isDesktop = Util.isDesktop;
 
   Future<Directory> prepareStorage() async {
     if (Platform.isAndroid) {
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index e2d16db54..c5ccfa6b3 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -7,7 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
-import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -20,14 +20,13 @@ import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:tuple/tuple.dart';
 
-import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
-
 class RestoreFromFileView extends ConsumerStatefulWidget {
   const RestoreFromFileView({Key? key}) : super(key: key);
 
@@ -44,13 +43,13 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
 
   late final FocusNode passwordFocusNode;
 
-  late final StackFileSystem stackFileSystem;
+  late final SWBFileSystem stackFileSystem;
 
   bool hidePassword = true;
 
   @override
   void initState() {
-    stackFileSystem = StackFileSystem();
+    stackFileSystem = SWBFileSystem();
     fileLocationController = TextEditingController();
     passwordController = TextEditingController();
 
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index cccb3b0b7..02d33fb95 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -9,14 +9,13 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stack_wallet_backup/stack_wallet_backup.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart';
-import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
-import 'package:stackwallet/utilities/enums/log_level_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/logger.dart';
@@ -48,7 +47,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
 
   late final SecureStorageInterface secureStore;
 
-  late final StackFileSystem stackFileSystem;
+  late final SWBFileSystem stackFileSystem;
   late final FocusNode passphraseFocusNode;
   late final FocusNode passphraseRepeatFocusNode;
   final zxcvbn = Zxcvbn();
@@ -81,7 +80,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
   @override
   void initState() {
     secureStore = ref.read(secureStoreProvider);
-    stackFileSystem = StackFileSystem();
+    stackFileSystem = SWBFileSystem();
 
     fileLocationController = TextEditingController();
     passphraseController = TextEditingController();
diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart
index 683e26544..1a5b2961f 100644
--- a/lib/services/coins/epiccash/epiccash_wallet.dart
+++ b/lib/services/coins/epiccash/epiccash_wallet.dart
@@ -9,7 +9,6 @@ import 'package:flutter_libepiccash/epic_cash.dart';
 import 'package:hive/hive.dart';
 import 'package:http/http.dart';
 import 'package:mutex/mutex.dart';
-import 'package:path_provider/path_provider.dart';
 import 'package:stack_wallet_backup/generate_password.dart';
 import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/models/node_model.dart';
@@ -31,6 +30,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/utilities/stack_file_system.dart';
 import 'package:stackwallet/utilities/test_epic_box_connection.dart';
 import 'package:tuple/tuple.dart';
 
@@ -253,14 +253,16 @@ Future<String> deleteEpicWallet({
   required SecureStorageInterface secureStore,
 }) async {
   String? config = await secureStore.read(key: '${walletId}_config');
+  // TODO: why double check for iOS?
   if (Platform.isIOS) {
-    Directory appDir = (await getApplicationDocumentsDirectory());
-    if (Platform.isIOS) {
-      appDir = (await getLibraryDirectory());
-    }
-    if (Platform.isLinux) {
-      appDir = Directory("${appDir.path}/.stackwallet");
-    }
+    Directory appDir = await StackFileSystem.applicationRootDirectory();
+    // todo why double check for ios?
+    // if (Platform.isIOS) {
+    //   appDir = (await getLibraryDirectory());
+    // }
+    // if (Platform.isLinux) {
+    //   appDir = Directory("${appDir.path}/.stackwallet");
+    // }
     final path = "${appDir.path}/epiccash";
     final String name = walletId;
 
@@ -1237,13 +1239,8 @@ class EpicCashWallet extends CoinServiceAPI {
   }
 
   Future<String> currentWalletDirPath() async {
-    Directory appDir = (await getApplicationDocumentsDirectory());
-    if (Platform.isIOS) {
-      appDir = (await getLibraryDirectory());
-    }
-    if (Platform.isLinux) {
-      appDir = Directory("${appDir.path}/.stackwallet");
-    }
+    Directory appDir = await StackFileSystem.applicationRootDirectory();
+
     final path = "${appDir.path}/epiccash";
     final String name = _walletId.trim();
     return '$path/$name';
diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index caf1185a5..c35323d53 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -25,7 +25,6 @@ import 'package:flutter_libmonero/monero/monero.dart';
 import 'package:flutter_libmonero/view_model/send/output.dart' as monero_output;
 import 'package:http/http.dart';
 import 'package:mutex/mutex.dart';
-import 'package:path_provider/path_provider.dart';
 import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/models/paymint/fee_object_model.dart';
@@ -47,6 +46,7 @@ import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/utilities/stack_file_system.dart';
 
 const int MINIMUM_CONFIRMATIONS = 10;
 
@@ -897,14 +897,8 @@ class MoneroWallet extends CoinServiceAPI {
     required String name,
     required WalletType type,
   }) async {
-    Directory root = (await getApplicationDocumentsDirectory());
-    if (Platform.isIOS) {
-      root = (await getLibraryDirectory());
-    }
-    //
-    if (Platform.isLinux) {
-      root = Directory("${root.path}/.stackwallet");
-    }
+    Directory root = await StackFileSystem.applicationRootDirectory();
+
     final prefix = walletTypeToString(type).toLowerCase();
     final walletsDir = Directory('${root.path}/wallets');
     final walletDire = Directory('${walletsDir.path}/$prefix/$name');
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 8f36352d0..e39d13005 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -26,7 +26,6 @@ import 'package:flutter_libmonero/view_model/send/output.dart'
 import 'package:flutter_libmonero/wownero/wownero.dart';
 import 'package:http/http.dart';
 import 'package:mutex/mutex.dart';
-import 'package:path_provider/path_provider.dart';
 import 'package:stackwallet/hive/db.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/models/paymint/fee_object_model.dart';
@@ -48,6 +47,7 @@ import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/utilities/stack_file_system.dart';
 
 const int MINIMUM_CONFIRMATIONS = 10;
 
@@ -901,13 +901,8 @@ class WowneroWallet extends CoinServiceAPI {
     required String name,
     required WalletType type,
   }) async {
-    Directory root = (await getApplicationDocumentsDirectory());
-    if (Platform.isIOS) {
-      root = (await getLibraryDirectory());
-    }
-    if (Platform.isLinux) {
-      root = Directory("${root.path}/.stackwallet");
-    }
+    Directory root = await StackFileSystem.applicationRootDirectory();
+
     final prefix = walletTypeToString(type).toLowerCase();
     final walletsDir = Directory('${root.path}/wallets');
     final walletDire = Directory('${walletsDir.path}/$prefix/$name');
diff --git a/lib/utilities/flutter_secure_storage_interface.dart b/lib/utilities/flutter_secure_storage_interface.dart
index 9e8aef95c..2d9b19050 100644
--- a/lib/utilities/flutter_secure_storage_interface.dart
+++ b/lib/utilities/flutter_secure_storage_interface.dart
@@ -1,9 +1,8 @@
-import 'dart:io';
-
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:isar/isar.dart';
 import 'package:stack_wallet_backup/secure_storage.dart';
 import 'package:stackwallet/models/isar/models/encrypted_string_value.dart';
+import 'package:stackwallet/utilities/stack_file_system.dart';
 
 abstract class SecureStorageInterface {
   dynamic get store;
@@ -47,14 +46,9 @@ class DesktopSecureStore {
   DesktopSecureStore(this.handler);
 
   Future<void> init() async {
-    Directory? appDirectory;
-    if (Platform.isLinux) {
-      appDirectory = Directory("${Platform.environment['HOME']}/.stackwallet");
-      await appDirectory.create();
-    }
     isar = await Isar.open(
       [EncryptedStringValueSchema],
-      directory: appDirectory!.path,
+      directory: (await StackFileSystem.applicationIsarDirectory()).path,
       inspector: false,
       name: "desktopStore",
     );
diff --git a/lib/utilities/stack_file_system.dart b/lib/utilities/stack_file_system.dart
new file mode 100644
index 000000000..5177f1973
--- /dev/null
+++ b/lib/utilities/stack_file_system.dart
@@ -0,0 +1,66 @@
+import 'dart:io';
+
+import 'package:path_provider/path_provider.dart';
+import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/utilities/util.dart';
+
+abstract class StackFileSystem {
+  static Future<Directory> applicationRootDirectory() async {
+    Directory appDirectory;
+
+    // todo: can merge and do same as regular linux home dir?
+    if (Logging.isArmLinux) {
+      appDirectory = await getApplicationDocumentsDirectory();
+      appDirectory = Directory("${appDirectory.path}/.stackwallet");
+    } else if (Platform.isLinux) {
+      appDirectory = Directory("${Platform.environment['HOME']}/.stackwallet");
+    } else if (Platform.isWindows) {
+      // TODO: windows root .stackwallet dir location
+      throw Exception("Unsupported platform");
+    } else if (Platform.isMacOS) {
+      // currently run in ipad mode??
+      throw Exception("Unsupported platform");
+    } else if (Platform.isIOS) {
+      // todo: check if we need different behaviour here
+      if (Util.isDesktop) {
+        appDirectory = await getLibraryDirectory();
+      } else {
+        appDirectory = await getLibraryDirectory();
+      }
+    } else if (Platform.isAndroid) {
+      appDirectory = await getApplicationDocumentsDirectory();
+    } else {
+      throw Exception("Unsupported platform");
+    }
+    if (!appDirectory.existsSync()) {
+      await appDirectory.create(recursive: true);
+    }
+    return appDirectory;
+  }
+
+  static Future<Directory> applicationIsarDirectory() async {
+    final root = await applicationRootDirectory();
+    if (Util.isDesktop) {
+      final dir = Directory("${root.path}/isar");
+      if (!dir.existsSync()) {
+        await dir.create();
+      }
+      return dir;
+    } else {
+      return root;
+    }
+  }
+
+  static Future<Directory> applicationHiveDirectory() async {
+    final root = await applicationRootDirectory();
+    if (Util.isDesktop) {
+      final dir = Directory("${root.path}/hive");
+      if (!dir.existsSync()) {
+        await dir.create();
+      }
+      return dir;
+    } else {
+      return root;
+    }
+  }
+}

From 357fd5e6fe23f2f31e3572efd27ad201df83affa Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 12 Nov 2022 16:34:34 -0600
Subject: [PATCH 228/426] update libmonero submodule dep

---
 crypto_plugins/flutter_libmonero | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index 2da774385..e5e3f6ee8 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit 2da77438527732dfaa5398aa391eab5253dabe19
+Subproject commit e5e3f6ee866a04f71534d71d62a7e371205b80d4

From 316a34914fd9849efa42a94ed7acf88a5ec8865e Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 12 Nov 2022 16:46:08 -0600
Subject: [PATCH 229/426] libmonero fix

---
 crypto_plugins/flutter_libmonero | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero
index e5e3f6ee8..de29931da 160000
--- a/crypto_plugins/flutter_libmonero
+++ b/crypto_plugins/flutter_libmonero
@@ -1 +1 @@
-Subproject commit e5e3f6ee866a04f71534d71d62a7e371205b80d4
+Subproject commit de29931dacc9aefaf42a9ca139a8754a42adc40d

From 94709623c4270a082277ad1f095e809d51be21e5 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 07:37:24 -0600
Subject: [PATCH 230/426] temp firo balance dropdown

---
 .../wallet_view/sub_widgets/desktop_send.dart | 157 ++++++++++--------
 1 file changed, 89 insertions(+), 68 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index 710bc8685..6f35a8570 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -1,6 +1,7 @@
 import 'dart:async';
 
 import 'package:decimal/decimal.dart';
+import 'package:dropdown_button2/dropdown_button2.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -9,7 +10,6 @@ import 'package:stackwallet/models/contact_address_entry.dart';
 import 'package:stackwallet/models/send_view_auto_fill_data.dart';
 import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart';
-import 'package:stackwallet/pages/send_view/sub_widgets/firo_balance_selection_sheet.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
 import 'package:stackwallet/providers/providers.dart';
@@ -550,13 +550,13 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
   Future<String?> _firoBalanceFuture(
     ChangeNotifierProvider<Manager> provider,
     String locale,
+    bool private,
   ) async {
     final wallet = ref.read(provider).wallet as FiroWallet?;
 
     if (wallet != null) {
       Decimal? balance;
-      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
-          "Private") {
+      if (private) {
         balance = await wallet.availablePrivateBalance();
       } else {
         balance = await wallet.availablePublicBalance();
@@ -572,24 +572,21 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
   Widget firoBalanceFutureBuilder(
     BuildContext context,
     AsyncSnapshot<String?> snapshot,
+    bool private,
   ) {
     if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
-      if (ref.read(publicPrivateBalanceStateProvider.state).state ==
-          "Private") {
+      if (private) {
         _privateBalanceString = snapshot.data!;
       } else {
         _publicBalanceString = snapshot.data!;
       }
     }
-    if (ref.read(publicPrivateBalanceStateProvider.state).state == "Private" &&
-        _privateBalanceString != null) {
+    if (private && _privateBalanceString != null) {
       return Text(
         "$_privateBalanceString ${coin.ticker}",
         style: STextStyles.itemSubtitle(context),
       );
-    } else if (ref.read(publicPrivateBalanceStateProvider.state).state ==
-            "Public" &&
-        _publicBalanceString != null) {
+    } else if (!private && _publicBalanceString != null) {
       return Text(
         "$_publicBalanceString ${coin.ticker}",
         style: STextStyles.itemSubtitle(context),
@@ -889,71 +886,95 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             height: 10,
           ),
         if (coin == Coin.firo)
-          Stack(
-            children: [
-              TextField(
-                autocorrect: Util.isDesktop ? false : true,
-                enableSuggestions: Util.isDesktop ? false : true,
-                readOnly: true,
-                textInputAction: TextInputAction.none,
-              ),
-              Padding(
-                padding: const EdgeInsets.symmetric(
-                  horizontal: 12,
-                ),
-                child: RawMaterialButton(
-                  splashColor:
-                      Theme.of(context).extension<StackColors>()!.highlight,
-                  shape: RoundedRectangleBorder(
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
-                    ),
-                  ),
-                  onPressed: () {
-                    showModalBottomSheet<dynamic>(
-                      backgroundColor: Colors.transparent,
-                      context: context,
-                      shape: const RoundedRectangleBorder(
-                        borderRadius: BorderRadius.vertical(
-                          top: Radius.circular(20),
-                        ),
-                      ),
-                      builder: (_) => FiroBalanceSelectionSheet(
-                        walletId: walletId,
-                      ),
-                    );
-                  },
+          DropdownButtonHideUnderline(
+            child: DropdownButton2(
+              offset: const Offset(0, -10),
+              isExpanded: true,
+              dropdownElevation: 0,
+              value: ref.watch(publicPrivateBalanceStateProvider.state).state,
+              items: [
+                DropdownMenuItem(
+                  value: "Private",
                   child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                     children: [
-                      Row(
-                        children: [
-                          Text(
-                            "${ref.watch(publicPrivateBalanceStateProvider.state).state} balance",
-                            style: STextStyles.itemSubtitle12(context),
-                          ),
-                          const SizedBox(
-                            width: 10,
-                          ),
-                          FutureBuilder(
-                            future: _firoBalanceFuture(provider, locale),
-                            builder: firoBalanceFutureBuilder,
-                          ),
-                        ],
+                      Text(
+                        "Private balance",
+                        style: STextStyles.itemSubtitle12(context),
                       ),
-                      SvgPicture.asset(
-                        Assets.svg.chevronDown,
-                        width: 8,
-                        height: 4,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textSubtitle2,
+                      const SizedBox(
+                        width: 10,
+                      ),
+                      FutureBuilder(
+                        future: _firoBalanceFuture(provider, locale, true),
+                        builder: (context, AsyncSnapshot<String?> snapshot) =>
+                            firoBalanceFutureBuilder(
+                          context,
+                          snapshot,
+                          true,
+                        ),
                       ),
                     ],
                   ),
                 ),
-              )
-            ],
+                DropdownMenuItem(
+                  value: "Public",
+                  child: Row(
+                    children: [
+                      Text(
+                        "Public balance",
+                        style: STextStyles.itemSubtitle12(context),
+                      ),
+                      const SizedBox(
+                        width: 10,
+                      ),
+                      FutureBuilder(
+                        future: _firoBalanceFuture(provider, locale, false),
+                        builder: (context, AsyncSnapshot<String?> snapshot) =>
+                            firoBalanceFutureBuilder(
+                          context,
+                          snapshot,
+                          false,
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+              ],
+              onChanged: (value) {
+                if (value is String) {
+                  setState(() {
+                    ref.watch(publicPrivateBalanceStateProvider.state).state =
+                        value;
+                  });
+                }
+              },
+              icon: SvgPicture.asset(
+                Assets.svg.chevronDown,
+                width: 12,
+                height: 6,
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
+              ),
+              buttonPadding: const EdgeInsets.symmetric(
+                horizontal: 16,
+                vertical: 8,
+              ),
+              buttonDecoration: BoxDecoration(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultBG,
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
+              ),
+              dropdownDecoration: BoxDecoration(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultBG,
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
+              ),
+            ),
           ),
         if (coin == Coin.firo)
           const SizedBox(

From 9a9b10b1b3c244a5b0e0486187a85af8be055688 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 07:56:07 -0600
Subject: [PATCH 231/426] WIP: fee selection ui

---
 .../send_view/confirm_transaction_view.dart   | 128 +++++++++++++-----
 1 file changed, 95 insertions(+), 33 deletions(-)

diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index 26d1231f0..eef0f84e6 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -54,13 +54,6 @@ class _ConfirmTransactionViewState
   late final String routeOnSuccessName;
   late final bool isDesktop;
 
-  int _fee = 12;
-  final List<int> _dropDownItems = [
-    12,
-    22,
-    234,
-  ];
-
   Future<void> _attemptSend(BuildContext context) async {
     unawaited(showDialog<dynamic>(
       context: context,
@@ -568,32 +561,101 @@ class _ConfirmTransactionViewState
               ),
             if (isDesktop)
               Padding(
-                padding: const EdgeInsets.only(
-                  top: 10,
-                  left: 32,
-                  right: 32,
-                ),
-                child: DropdownButtonFormField(
-                  value: _fee,
-                  items: _dropDownItems
-                      .map(
-                        (e) => DropdownMenuItem(
-                          value: e,
-                          child: Text(
-                            e.toString(),
-                          ),
-                        ),
-                      )
-                      .toList(),
-                  onChanged: (value) {
-                    if (value is int) {
-                      setState(() {
-                        _fee = value;
-                      });
-                    }
-                  },
-                ),
-              ),
+                  padding: const EdgeInsets.only(
+                    top: 10,
+                    left: 32,
+                    right: 32,
+                  ),
+                  child: RoundedContainer(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 16,
+                      vertical: 18,
+                    ),
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .textFieldDefaultBG,
+                    child: Builder(builder: (context) {
+                      final coin = ref
+                          .watch(walletsChangeNotifierProvider
+                              .select((value) => value.getManager(walletId)))
+                          .coin;
+
+                      final fee = Format.satoshisToAmount(
+                        transactionInfo["fee"] as int,
+                        coin: coin,
+                      );
+
+                      return Text(
+                        "${Format.localizedStringAsFixed(
+                          value: fee,
+                          locale: ref.watch(localeServiceChangeNotifierProvider
+                              .select((value) => value.locale)),
+                          decimalPlaces: coin == Coin.monero
+                              ? Constants.decimalPlacesMonero
+                              : coin == Coin.wownero
+                                  ? Constants.decimalPlacesWownero
+                                  : Constants.decimalPlaces,
+                        )} ${coin.ticker}",
+                        style: STextStyles.itemSubtitle(context),
+                      );
+                    }),
+                  )
+                  // DropdownButtonHideUnderline(
+                  //   child: DropdownButton2(
+                  //     offset: const Offset(0, -10),
+                  //     isExpanded: true,
+                  //
+                  //     dropdownElevation: 0,
+                  //     value: _fee,
+                  //     items: [
+                  //       ..._dropDownItems.map(
+                  //         (e) {
+                  //           String message = _fee.toString();
+                  //
+                  //           return DropdownMenuItem(
+                  //             value: e,
+                  //             child: Text(message),
+                  //           );
+                  //         },
+                  //       ),
+                  //     ],
+                  //     onChanged: (value) {
+                  //       if (value is int) {
+                  //         setState(() {
+                  //           _fee = value;
+                  //         });
+                  //       }
+                  //     },
+                  //     icon: SvgPicture.asset(
+                  //       Assets.svg.chevronDown,
+                  //       width: 12,
+                  //       height: 6,
+                  //       color:
+                  //           Theme.of(context).extension<StackColors>()!.textDark3,
+                  //     ),
+                  //     buttonPadding: const EdgeInsets.symmetric(
+                  //       horizontal: 16,
+                  //       vertical: 8,
+                  //     ),
+                  //     buttonDecoration: BoxDecoration(
+                  //       color: Theme.of(context)
+                  //           .extension<StackColors>()!
+                  //           .textFieldDefaultBG,
+                  //       borderRadius: BorderRadius.circular(
+                  //         Constants.size.circularBorderRadius,
+                  //       ),
+                  //     ),
+                  //     dropdownDecoration: BoxDecoration(
+                  //       color: Theme.of(context)
+                  //           .extension<StackColors>()!
+                  //           .textFieldDefaultBG,
+                  //       borderRadius: BorderRadius.circular(
+                  //         Constants.size.circularBorderRadius,
+                  //       ),
+                  //     ),
+                  //   ),
+                  // ),
+                  ),
             if (!isDesktop) const Spacer(),
             SizedBox(
               height: isDesktop ? 23 : 12,

From 4238ce338ac8cf9f46ff402f7f5cff3186f59a3a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 09:05:45 -0600
Subject: [PATCH 232/426] desktop password protected send flow

---
 .../send_view/confirm_transaction_view.dart   | 165 ++++++++++++-----
 .../sending_transaction_dialog.dart           |  69 +++++--
 .../sub_widgets/desktop_auth_send.dart        | 173 ++++++++++++++++++
 .../wallet_view/sub_widgets/desktop_send.dart |   2 +
 4 files changed, 348 insertions(+), 61 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart

diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index eef0f84e6..0f1692c08 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -8,6 +8,7 @@ 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';
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
 import 'package:stackwallet/route_generator.dart';
@@ -23,6 +24,8 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -55,14 +58,16 @@ class _ConfirmTransactionViewState
   late final bool isDesktop;
 
   Future<void> _attemptSend(BuildContext context) async {
-    unawaited(showDialog<dynamic>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: false,
-      builder: (context) {
-        return const SendingTransactionDialog();
-      },
-    ));
+    unawaited(
+      showDialog<dynamic>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: false,
+        builder: (context) {
+          return const SendingTransactionDialog();
+        },
+      ),
+    );
 
     final note = transactionInfo["note"] as String? ?? "";
     final manager =
@@ -115,25 +120,66 @@ class _ConfirmTransactionViewState
         useSafeArea: false,
         barrierDismissible: true,
         builder: (context) {
-          return StackDialog(
-            title: "Broadcast transaction failed",
-            message: e.toString(),
-            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),
+          if (isDesktop) {
+            return DesktopDialog(
+              maxWidth: 450,
+              child: Padding(
+                padding: const EdgeInsets.all(32),
+                child: Column(
+                  mainAxisSize: MainAxisSize.min,
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Text(
+                      "Broadcast transaction failed",
+                      style: STextStyles.desktopH3(context),
+                    ),
+                    const SizedBox(
+                      height: 24,
+                    ),
+                    Text(
+                      e.toString(),
+                      style: STextStyles.smallMed14(context),
+                    ),
+                    const SizedBox(
+                      height: 56,
+                    ),
+                    Row(
+                      children: [
+                        const Spacer(),
+                        Expanded(
+                          child: PrimaryButton(
+                            desktopMed: true,
+                            label: "Ok",
+                            onPressed: Navigator.of(context).pop,
+                          ),
+                        ),
+                      ],
+                    )
+                  ],
+                ),
               ),
-              onPressed: () {
-                Navigator.of(context).pop();
-              },
-            ),
-          );
+            );
+          } else {
+            return StackDialog(
+              title: "Broadcast transaction failed",
+              message: e.toString(),
+              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();
+                },
+              ),
+            );
+          }
         },
       );
     }
@@ -736,25 +782,56 @@ class _ConfirmTransactionViewState
                 label: "Send",
                 desktopMed: true,
                 onPressed: () async {
-                  final unlocked = await Navigator.push(
-                    context,
-                    RouteGenerator.getRoute(
-                      shouldUseMaterialRoute:
-                          RouteGenerator.useMaterialPageRoute,
-                      builder: (_) => const LockscreenView(
-                        showBackButton: true,
-                        popOnSuccess: true,
-                        routeOnSuccessArguments: true,
-                        routeOnSuccess: "",
-                        biometricsCancelButtonString: "CANCEL",
-                        biometricsLocalizedReason:
-                            "Authenticate to send transaction",
-                        biometricsAuthenticationTitle: "Confirm Transaction",
+                  final dynamic unlocked;
+
+                  if (isDesktop) {
+                    unlocked = await showDialog<bool?>(
+                      context: context,
+                      builder: (context) => DesktopDialog(
+                        maxWidth: 580,
+                        maxHeight: double.infinity,
+                        child: Column(
+                          mainAxisSize: MainAxisSize.min,
+                          children: [
+                            Row(
+                              mainAxisAlignment: MainAxisAlignment.end,
+                              children: const [
+                                DesktopDialogCloseButton(),
+                              ],
+                            ),
+                            const Padding(
+                              padding: EdgeInsets.only(
+                                left: 32,
+                                right: 32,
+                                bottom: 32,
+                              ),
+                              child: DesktopAuthSend(),
+                            ),
+                          ],
+                        ),
                       ),
-                      settings:
-                          const RouteSettings(name: "/confirmsendlockscreen"),
-                    ),
-                  );
+                    );
+                  } else {
+                    unlocked = await Navigator.push(
+                      context,
+                      RouteGenerator.getRoute(
+                        shouldUseMaterialRoute:
+                            RouteGenerator.useMaterialPageRoute,
+                        builder: (_) => const LockscreenView(
+                          showBackButton: true,
+                          popOnSuccess: true,
+                          routeOnSuccessArguments: true,
+                          routeOnSuccess: "",
+                          biometricsCancelButtonString: "CANCEL",
+                          biometricsLocalizedReason:
+                              "Authenticate to send transaction",
+                          biometricsAuthenticationTitle: "Confirm Transaction",
+                        ),
+                        settings:
+                            const RouteSettings(name: "/confirmsendlockscreen"),
+                      ),
+                    );
+                  }
 
                   if (unlocked is bool && unlocked && mounted) {
                     unawaited(_attemptSend(context));
diff --git a/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart b/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart
index 1eb106b53..e5c86fe2e 100644
--- a/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart
+++ b/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart
@@ -1,7 +1,10 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/utilities/assets.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/desktop_dialog.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
 class SendingTransactionDialog extends StatefulWidget {
@@ -43,24 +46,56 @@ class _RestoringDialogState extends State<SendingTransactionDialog>
 
   @override
   Widget build(BuildContext context) {
-    return WillPopScope(
-      onWillPop: () async {
-        return false;
-      },
-      child: StackDialog(
-        title: "Sending transaction",
-        // // TODO get message from design team
-        // message: "<PLACEHOLDER>",
-        icon: RotationTransition(
-          turns: _spinAnimation,
-          child: SvgPicture.asset(
-            Assets.svg.arrowRotate,
-            color: Theme.of(context).extension<StackColors>()!.accentColorDark,
-            width: 24,
-            height: 24,
+    if (Util.isDesktop) {
+      return DesktopDialog(
+        child: Padding(
+          padding: const EdgeInsets.all(40),
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              Text(
+                "Sending transaction",
+                style: STextStyles.desktopH3(context),
+              ),
+              const SizedBox(
+                height: 40,
+              ),
+              RotationTransition(
+                turns: _spinAnimation,
+                child: SvgPicture.asset(
+                  Assets.svg.arrowRotate,
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .accentColorDark,
+                  width: 24,
+                  height: 24,
+                ),
+              ),
+            ],
           ),
         ),
-      ),
-    );
+      );
+    } else {
+      return WillPopScope(
+        onWillPop: () async {
+          return false;
+        },
+        child: StackDialog(
+          title: "Sending transaction",
+          // // TODO get message from design team
+          // message: "<PLACEHOLDER>",
+          icon: RotationTransition(
+            turns: _spinAnimation,
+            child: SvgPicture.asset(
+              Assets.svg.arrowRotate,
+              color:
+                  Theme.of(context).extension<StackColors>()!.accentColorDark,
+              width: 24,
+              height: 24,
+            ),
+          ),
+        ),
+      );
+    }
   }
 }
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
new file mode 100644
index 000000000..566a82b35
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
@@ -0,0 +1,173 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
+import 'package:stackwallet/utilities/assets.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/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+
+class DesktopAuthSend extends ConsumerStatefulWidget {
+  const DesktopAuthSend({Key? key}) : super(key: key);
+
+  @override
+  ConsumerState<DesktopAuthSend> createState() => _DesktopAuthSendState();
+}
+
+class _DesktopAuthSendState extends ConsumerState<DesktopAuthSend> {
+  late final TextEditingController passwordController;
+  late final FocusNode passwordFocusNode;
+
+  bool hidePassword = true;
+
+  bool _confirmEnabled = false;
+
+  Future<bool> verifyPassphrase() async {
+    return await ref
+        .read(storageCryptoHandlerProvider)
+        .verifyPassphrase(passwordController.text);
+  }
+
+  @override
+  void initState() {
+    passwordController = TextEditingController();
+    passwordFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    passwordController.dispose();
+    passwordFocusNode.dispose();
+
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      mainAxisSize: MainAxisSize.min,
+      children: [
+        SvgPicture.asset(
+          Assets.svg.keys,
+          width: 100,
+        ),
+        const SizedBox(
+          height: 56,
+        ),
+        Text(
+          "Confirm transaction",
+          style: STextStyles.desktopH3(context),
+        ),
+        const SizedBox(
+          height: 16,
+        ),
+        Text(
+          "Enter your wallet password to send BTC",
+          style: STextStyles.desktopTextMedium(context).copyWith(
+            color: Theme.of(context).extension<StackColors>()!.textDark3,
+          ),
+        ),
+        const SizedBox(
+          height: 24,
+        ),
+        ClipRRect(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
+          ),
+          child: TextField(
+            key: const Key("desktopLoginPasswordFieldKey"),
+            focusNode: passwordFocusNode,
+            controller: passwordController,
+            style: STextStyles.desktopTextMedium(context).copyWith(
+              height: 2,
+            ),
+            obscureText: hidePassword,
+            enableSuggestions: false,
+            autocorrect: false,
+            decoration: standardInputDecoration(
+              "Enter password",
+              passwordFocusNode,
+              context,
+            ).copyWith(
+              suffixIcon: UnconstrainedBox(
+                child: SizedBox(
+                  height: 70,
+                  child: Row(
+                    children: [
+                      const SizedBox(
+                        width: 24,
+                      ),
+                      GestureDetector(
+                        key: const Key(
+                            "restoreFromFilePasswordFieldShowPasswordButtonKey"),
+                        onTap: () async {
+                          setState(() {
+                            hidePassword = !hidePassword;
+                          });
+                        },
+                        child: SvgPicture.asset(
+                          hidePassword ? Assets.svg.eye : Assets.svg.eyeSlash,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark3,
+                          width: 24,
+                          height: 24,
+                        ),
+                      ),
+                      const SizedBox(
+                        width: 12,
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+            ),
+            onChanged: (newValue) {
+              setState(() {
+                _confirmEnabled = passwordController.text.isNotEmpty;
+              });
+            },
+          ),
+        ),
+        const SizedBox(
+          height: 48,
+        ),
+        Row(
+          children: [
+            Expanded(
+              child: SecondaryButton(
+                label: "Cancel",
+                desktopMed: true,
+                onPressed: Navigator.of(context).pop,
+              ),
+            ),
+            const SizedBox(
+              width: 16,
+            ),
+            Expanded(
+              child: PrimaryButton(
+                enabled: _confirmEnabled,
+                label: "Confirm",
+                desktopMed: true,
+                onPressed: () async {
+                  // TODO show spinner while verifying passphrase
+
+                  final passwordIsValid = await verifyPassphrase();
+
+                  if (mounted) {
+                    Navigator.of(context).pop(passwordIsValid);
+                  }
+                },
+              ),
+            ),
+          ],
+        )
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index 6f35a8570..071122def 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -11,6 +11,7 @@ import 'package:stackwallet/models/send_view_auto_fill_data.dart';
 import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart';
+import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/ui/fee_rate_type_state_provider.dart';
@@ -332,6 +333,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
               child: ConfirmTransactionView(
                 transactionInfo: txData,
                 walletId: walletId,
+                routeOnSuccessName: DesktopHomeView.routeName,
               ),
             ),
           ),

From daa7708ad0196e16145a551b9f5574c0972ff8e0 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 09:20:35 -0600
Subject: [PATCH 233/426] temp disable exchange option for desktop

---
 .../home/desktop_home_view.dart               |  7 +--
 .../home/desktop_menu.dart                    | 46 +++++++++----------
 2 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index cb8aba255..76645442d 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -26,9 +26,10 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: MyStackView.routeName,
     ),
-    Container(
-      color: Colors.green,
-    ),
+    // Container(
+    //   // todo: exchange
+    //   color: Colors.green,
+    // ),
     Container(
       color: Colors.red,
     ),
diff --git a/lib/pages_desktop_specific/home/desktop_menu.dart b/lib/pages_desktop_specific/home/desktop_menu.dart
index 7409a4156..800a8416e 100644
--- a/lib/pages_desktop_specific/home/desktop_menu.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu.dart
@@ -103,29 +103,29 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                     const SizedBox(
                       height: 2,
                     ),
-                    DesktopMenuItem(
-                      icon: SvgPicture.asset(
-                        Assets.svg.exchangeDesktop,
-                        width: 20,
-                        height: 20,
-                        color: 1 == selectedMenuItem
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark
-                                .withOpacity(0.8),
-                      ),
-                      label: "Exchange",
-                      value: 1,
-                      group: selectedMenuItem,
-                      onChanged: updateSelectedMenuItem,
-                      iconOnly: _width == minimizedWidth,
-                    ),
-                    const SizedBox(
-                      height: 2,
-                    ),
+                    // DesktopMenuItem(
+                    //   icon: SvgPicture.asset(
+                    //     Assets.svg.exchangeDesktop,
+                    //     width: 20,
+                    //     height: 20,
+                    //     color: 1 == selectedMenuItem
+                    //         ? Theme.of(context)
+                    //             .extension<StackColors>()!
+                    //             .textDark
+                    //         : Theme.of(context)
+                    //             .extension<StackColors>()!
+                    //             .textDark
+                    //             .withOpacity(0.8),
+                    //   ),
+                    //   label: "Exchange",
+                    //   value: 1,
+                    //   group: selectedMenuItem,
+                    //   onChanged: updateSelectedMenuItem,
+                    //   iconOnly: _width == minimizedWidth,
+                    // ),
+                    // const SizedBox(
+                    //   height: 2,
+                    // ),
                     DesktopMenuItem(
                       icon: SvgPicture.asset(
                         Assets.svg.bell,

From 5b47d5806d97f1206d336312d87e3a0a703974ef Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 09:25:06 -0600
Subject: [PATCH 234/426] disable seemingly pointless code

---
 .../coins/epiccash/epiccash_wallet.dart       | 41 ++++++++++---------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart
index 1a5b2961f..fcf728fb8 100644
--- a/lib/services/coins/epiccash/epiccash_wallet.dart
+++ b/lib/services/coins/epiccash/epiccash_wallet.dart
@@ -252,26 +252,27 @@ Future<String> deleteEpicWallet({
   required String walletId,
   required SecureStorageInterface secureStore,
 }) async {
-  String? config = await secureStore.read(key: '${walletId}_config');
-  // TODO: why double check for iOS?
-  if (Platform.isIOS) {
-    Directory appDir = await StackFileSystem.applicationRootDirectory();
-    // todo why double check for ios?
-    // if (Platform.isIOS) {
-    //   appDir = (await getLibraryDirectory());
-    // }
-    // if (Platform.isLinux) {
-    //   appDir = Directory("${appDir.path}/.stackwallet");
-    // }
-    final path = "${appDir.path}/epiccash";
-    final String name = walletId;
-
-    final walletDir = '$path/$name';
-    var editConfig = jsonDecode(config as String);
-
-    editConfig["wallet_dir"] = walletDir;
-    config = jsonEncode(editConfig);
-  }
+  // is this even needed for anything?
+  // String? config = await secureStore.read(key: '${walletId}_config');
+  // // TODO: why double check for iOS?
+  // if (Platform.isIOS) {
+  //   Directory appDir = await StackFileSystem.applicationRootDirectory();
+  //   // todo why double check for ios?
+  //   // if (Platform.isIOS) {
+  //   //   appDir = (await getLibraryDirectory());
+  //   // }
+  //   // if (Platform.isLinux) {
+  //   //   appDir = Directory("${appDir.path}/.stackwallet");
+  //   // }
+  //   final path = "${appDir.path}/epiccash";
+  //   final String name = walletId;
+  //
+  //   final walletDir = '$path/$name';
+  //   var editConfig = jsonDecode(config as String);
+  //
+  //   editConfig["wallet_dir"] = walletDir;
+  //   config = jsonEncode(editConfig);
+  // }
 
   final wallet = await secureStore.read(key: '${walletId}_wallet');
 

From 7cf3a8efba9a2968644c0df6e7b56257416db7c6 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 09:50:58 -0600
Subject: [PATCH 235/426] refactor desktop main menu and add WIP notifications
 view

---
 .../home/desktop_home_view.dart               | 29 +++++----
 .../home/desktop_menu.dart                    | 63 +++++++++++--------
 .../desktop_notifications_view.dart           | 59 +++++++++++++++++
 lib/route_generator.dart                      |  7 +++
 4 files changed, 119 insertions(+), 39 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart

diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index 76645442d..c0b0145f7 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -4,6 +4,7 @@ import 'package:stackwallet/pages_desktop_specific/home/address_book_view/deskto
 import 'package:stackwallet/pages_desktop_specific/home/desktop_menu.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/notifications/desktop_notifications_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart';
 import 'package:stackwallet/route_generator.dart';
@@ -19,9 +20,9 @@ class DesktopHomeView extends ConsumerStatefulWidget {
 }
 
 class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
-  int currentViewIndex = 0;
-  final List<Widget> contentViews = [
-    const Navigator(
+  DesktopMenuItemId currentViewKey = DesktopMenuItemId.myStack;
+  final Map<DesktopMenuItemId, Widget> contentViews = {
+    DesktopMenuItemId.myStack: const Navigator(
       key: Key("desktopStackHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: MyStackView.routeName,
@@ -30,34 +31,36 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
     //   // todo: exchange
     //   color: Colors.green,
     // ),
-    Container(
-      color: Colors.red,
+    DesktopMenuItemId.notifications: const Navigator(
+      key: Key("desktopNotificationsHomeKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: DesktopNotificationsView.routeName,
     ),
-    const Navigator(
+    DesktopMenuItemId.addressBook: const Navigator(
       key: Key("desktopAddressBookHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: DesktopAddressBook.routeName,
     ),
-    const Navigator(
+    DesktopMenuItemId.settings: const Navigator(
       key: Key("desktopSettingHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: DesktopSettingsView.routeName,
     ),
-    const Navigator(
+    DesktopMenuItemId.support: const Navigator(
       key: Key("desktopSupportHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: DesktopSupportView.routeName,
     ),
-    const Navigator(
+    DesktopMenuItemId.about: const Navigator(
       key: Key("desktopAboutHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: DesktopAboutView.routeName,
     ),
-  ];
+  };
 
-  void onMenuSelectionChanged(int newIndex) {
+  void onMenuSelectionChanged(DesktopMenuItemId newKey) {
     setState(() {
-      currentViewIndex = newIndex;
+      currentViewKey = newKey;
     });
   }
 
@@ -75,7 +78,7 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
             color: Theme.of(context).extension<StackColors>()!.background,
           ),
           Expanded(
-            child: contentViews[currentViewIndex],
+            child: contentViews[currentViewKey]!,
           ),
         ],
       ),
diff --git a/lib/pages_desktop_specific/home/desktop_menu.dart b/lib/pages_desktop_specific/home/desktop_menu.dart
index 800a8416e..cfa1a0ff0 100644
--- a/lib/pages_desktop_specific/home/desktop_menu.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu.dart
@@ -8,13 +8,23 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
+enum DesktopMenuItemId {
+  myStack,
+  exchange,
+  notifications,
+  addressBook,
+  settings,
+  support,
+  about,
+}
+
 class DesktopMenu extends ConsumerStatefulWidget {
   const DesktopMenu({
     Key? key,
     required this.onSelectionChanged,
   }) : super(key: key);
 
-  final void Function(int)? onSelectionChanged;
+  final void Function(DesktopMenuItemId)? onSelectionChanged;
 
   @override
   ConsumerState<DesktopMenu> createState() => _DesktopMenuState();
@@ -25,13 +35,13 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
   static const minimizedWidth = 72.0;
 
   double _width = expandedWidth;
-  int selectedMenuItem = 0;
+  DesktopMenuItemId selectedMenuItem = DesktopMenuItemId.myStack;
 
-  void updateSelectedMenuItem(int index) {
+  void updateSelectedMenuItem(DesktopMenuItemId idKey) {
     setState(() {
-      selectedMenuItem = index;
+      selectedMenuItem = idKey;
     });
-    widget.onSelectionChanged?.call(index);
+    widget.onSelectionChanged?.call(idKey);
   }
 
   void toggleMinimize() {
@@ -85,7 +95,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.walletDesktop,
                         width: 20,
                         height: 20,
-                        color: 0 == selectedMenuItem
+                        color: DesktopMenuItemId.myStack == selectedMenuItem
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -95,7 +105,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                 .withOpacity(0.8),
                       ),
                       label: "My Stack",
-                      value: 0,
+                      value: DesktopMenuItemId.myStack,
                       group: selectedMenuItem,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
@@ -108,7 +118,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                     //     Assets.svg.exchangeDesktop,
                     //     width: 20,
                     //     height: 20,
-                    //     color: 1 == selectedMenuItem
+                    //     color: DesktopMenuItemId.exchange == selectedMenuItem
                     //         ? Theme.of(context)
                     //             .extension<StackColors>()!
                     //             .textDark
@@ -118,7 +128,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                     //             .withOpacity(0.8),
                     //   ),
                     //   label: "Exchange",
-                    //   value: 1,
+                    //   value: DesktopMenuItemId.exchange,
                     //   group: selectedMenuItem,
                     //   onChanged: updateSelectedMenuItem,
                     //   iconOnly: _width == minimizedWidth,
@@ -131,17 +141,18 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.bell,
                         width: 20,
                         height: 20,
-                        color: 2 == selectedMenuItem
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark
-                                .withOpacity(0.8),
+                        color:
+                            DesktopMenuItemId.notifications == selectedMenuItem
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark
+                                    .withOpacity(0.8),
                       ),
                       label: "Notifications",
-                      value: 2,
+                      value: DesktopMenuItemId.notifications,
                       group: selectedMenuItem,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
@@ -154,7 +165,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.addressBookDesktop,
                         width: 20,
                         height: 20,
-                        color: 3 == selectedMenuItem
+                        color: DesktopMenuItemId.addressBook == selectedMenuItem
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -164,7 +175,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                 .withOpacity(0.8),
                       ),
                       label: "Address Book",
-                      value: 3,
+                      value: DesktopMenuItemId.addressBook,
                       group: selectedMenuItem,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
@@ -177,7 +188,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.gear,
                         width: 20,
                         height: 20,
-                        color: 4 == selectedMenuItem
+                        color: DesktopMenuItemId.settings == selectedMenuItem
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -187,7 +198,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                 .withOpacity(0.8),
                       ),
                       label: "Settings",
-                      value: 4,
+                      value: DesktopMenuItemId.settings,
                       group: selectedMenuItem,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
@@ -200,7 +211,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.messageQuestion,
                         width: 20,
                         height: 20,
-                        color: 5 == selectedMenuItem
+                        color: DesktopMenuItemId.support == selectedMenuItem
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -210,7 +221,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                 .withOpacity(0.8),
                       ),
                       label: "Support",
-                      value: 5,
+                      value: DesktopMenuItemId.support,
                       group: selectedMenuItem,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
@@ -223,7 +234,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.aboutDesktop,
                         width: 20,
                         height: 20,
-                        color: 6 == selectedMenuItem
+                        color: DesktopMenuItemId.about == selectedMenuItem
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -233,7 +244,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                 .withOpacity(0.8),
                       ),
                       label: "About",
-                      value: 6,
+                      value: DesktopMenuItemId.about,
                       group: selectedMenuItem,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
diff --git a/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart b/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart
new file mode 100644
index 000000000..c8e688aa6
--- /dev/null
+++ b/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart
@@ -0,0 +1,59 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/notifications/notification_card.dart';
+import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class DesktopNotificationsView extends ConsumerStatefulWidget {
+  const DesktopNotificationsView({Key? key}) : super(key: key);
+
+  static const String routeName = "/desktopNotifications";
+
+  @override
+  ConsumerState<DesktopNotificationsView> createState() =>
+      _DesktopNotificationsViewState();
+}
+
+class _DesktopNotificationsViewState
+    extends ConsumerState<DesktopNotificationsView> {
+  @override
+  Widget build(BuildContext context) {
+    final notifications =
+        ref.watch(notificationsProvider.select((value) => value.notifications));
+
+    return DesktopScaffold(
+      background: Theme.of(context).extension<StackColors>()!.background,
+      appBar: DesktopAppBar(
+        isCompactHeight: true,
+        leading: Padding(
+          padding: const EdgeInsets.only(left: 24),
+          child: Text(
+            "Notifications",
+            style: STextStyles.desktopH3(context),
+          ),
+        ),
+      ),
+      body: notifications.isEmpty
+          ? RoundedWhiteContainer(
+              child: Center(
+                child: Text(
+                  "Notifications will appear here",
+                  style: STextStyles.desktopTextExtraExtraSmall(context),
+                ),
+              ),
+            )
+          : ListView.builder(
+              itemCount: notifications.length,
+              itemBuilder: (context, index) {
+                return NotificationCard(
+                  notification: notifications[index],
+                );
+              },
+            ),
+    );
+  }
+}
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index f3e37e383..d7865d013 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -93,6 +93,7 @@ import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_v
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
+import 'package:stackwallet/pages_desktop_specific/home/notifications/desktop_notifications_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
@@ -1012,6 +1013,12 @@ class RouteGenerator {
             builder: (_) => const DesktopHomeView(),
             settings: RouteSettings(name: settings.name));
 
+      case DesktopNotificationsView.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const DesktopNotificationsView(),
+            settings: RouteSettings(name: settings.name));
+
       case DesktopSettingsView.routeName:
         return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,

From 60bdc6151bbffc8183cf0b0e539ee8e3b48005ad Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 10:40:31 -0600
Subject: [PATCH 236/426] desktop notifications view

---
 lib/notifications/notification_card.dart      | 75 ++++++++++++++---
 .../home/desktop_home_view.dart               | 44 ++++++++--
 .../home/desktop_menu.dart                    | 83 ++++++++++++-------
 .../desktop_notifications_view.dart           | 20 ++++-
 .../desktop/current_desktop_menu_item.dart    |  5 ++
 5 files changed, 179 insertions(+), 48 deletions(-)
 create mode 100644 lib/providers/desktop/current_desktop_menu_item.dart

diff --git a/lib/notifications/notification_card.dart b/lib/notifications/notification_card.dart
index 67be236f0..2a181499c 100644
--- a/lib/notifications/notification_card.dart
+++ b/lib/notifications/notification_card.dart
@@ -4,6 +4,8 @@ import 'package:stackwallet/models/notification_model.dart';
 import 'package:stackwallet/utilities/format.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';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
@@ -20,22 +22,33 @@ class NotificationCard extends StatelessWidget {
     return Format.extractDateFrom(date.millisecondsSinceEpoch ~/ 1000);
   }
 
+  static const double mobileIconSize = 24;
+  static const double desktopIconSize = 30;
+
   @override
   Widget build(BuildContext context) {
+    final isDesktop = Util.isDesktop;
+
     return Stack(
       children: [
         RoundedWhiteContainer(
+          padding: isDesktop
+              ? const EdgeInsets.symmetric(
+                  horizontal: 20,
+                  vertical: 10,
+                )
+              : const EdgeInsets.all(12),
           child: Row(
             children: [
               notification.changeNowId == null
                   ? SvgPicture.asset(
                       notification.iconAssetName,
-                      width: 24,
-                      height: 24,
+                      width: isDesktop ? desktopIconSize : mobileIconSize,
+                      height: isDesktop ? desktopIconSize : mobileIconSize,
                     )
                   : Container(
-                      width: 24,
-                      height: 24,
+                      width: isDesktop ? desktopIconSize : mobileIconSize,
+                      height: isDesktop ? desktopIconSize : mobileIconSize,
                       decoration: BoxDecoration(
                         color: Colors.transparent,
                         borderRadius: BorderRadius.circular(24),
@@ -45,8 +58,8 @@ class NotificationCard extends StatelessWidget {
                         color: Theme.of(context)
                             .extension<StackColors>()!
                             .accentColorDark,
-                        width: 24,
-                        height: 24,
+                        width: isDesktop ? desktopIconSize : mobileIconSize,
+                        height: isDesktop ? desktopIconSize : mobileIconSize,
                       ),
                     ),
               const SizedBox(
@@ -56,9 +69,35 @@ class NotificationCard extends StatelessWidget {
                 child: Column(
                   crossAxisAlignment: CrossAxisAlignment.stretch,
                   children: [
-                    Text(
-                      notification.title,
-                      style: STextStyles.titleBold12(context),
+                    ConditionalParent(
+                      condition: isDesktop && !notification.read,
+                      builder: (child) => Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          child,
+                          Text(
+                            "New",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context)
+                                    .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorGreen,
+                            ),
+                          )
+                        ],
+                      ),
+                      child: Text(
+                        notification.title,
+                        style: isDesktop
+                            ? STextStyles.desktopTextExtraExtraSmall(context)
+                                .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              )
+                            : STextStyles.titleBold12(context),
+                      ),
                     ),
                     const SizedBox(
                       height: 2,
@@ -68,11 +107,25 @@ class NotificationCard extends StatelessWidget {
                       children: [
                         Text(
                           notification.description,
-                          style: STextStyles.label(context),
+                          style: isDesktop
+                              ? STextStyles.desktopTextExtraExtraSmall(context)
+                                  .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textSubtitle1,
+                                )
+                              : STextStyles.label(context),
                         ),
                         Text(
                           extractPrettyDateString(notification.date),
-                          style: STextStyles.label(context),
+                          style: isDesktop
+                              ? STextStyles.desktopTextExtraExtraSmall(context)
+                                  .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textSubtitle1,
+                                )
+                              : STextStyles.label(context),
                         ),
                       ],
                     ),
diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index c0b0145f7..b1c35f00b 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -7,6 +7,9 @@ import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_v
 import 'package:stackwallet/pages_desktop_specific/home/notifications/desktop_notifications_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart';
+import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart';
+import 'package:stackwallet/providers/global/notifications_provider.dart';
+import 'package:stackwallet/providers/ui/unread_notifications_provider.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
@@ -20,7 +23,6 @@ class DesktopHomeView extends ConsumerStatefulWidget {
 }
 
 class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
-  DesktopMenuItemId currentViewKey = DesktopMenuItemId.myStack;
   final Map<DesktopMenuItemId, Widget> contentViews = {
     DesktopMenuItemId.myStack: const Navigator(
       key: Key("desktopStackHomeKey"),
@@ -58,10 +60,36 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
     ),
   };
 
-  void onMenuSelectionChanged(DesktopMenuItemId newKey) {
-    setState(() {
-      currentViewKey = newKey;
-    });
+  void onMenuSelectionWillChange(DesktopMenuItemId newKey) {
+    // check for unread notifications and refresh provider before
+    // showing notifications view
+    if (newKey == DesktopMenuItemId.notifications) {
+      ref.refresh(unreadNotificationsStateProvider);
+    }
+    // mark notifications as read if leaving notifications view
+    if (ref.read(currentDesktopMenuItemProvider.state).state ==
+            DesktopMenuItemId.notifications &&
+        newKey != DesktopMenuItemId.notifications) {
+      final Set<int> unreadNotificationIds =
+          ref.read(unreadNotificationsStateProvider.state).state;
+
+      if (unreadNotificationIds.isNotEmpty) {
+        List<Future<void>> futures = [];
+        for (int i = 0; i < unreadNotificationIds.length - 1; i++) {
+          futures.add(ref
+              .read(notificationsProvider)
+              .markAsRead(unreadNotificationIds.elementAt(i), false));
+        }
+
+        // wait for multiple to update if any
+        Future.wait(futures).then((_) {
+          // only notify listeners once
+          ref
+              .read(notificationsProvider)
+              .markAsRead(unreadNotificationIds.last, true);
+        });
+      }
+    }
   }
 
   @override
@@ -71,14 +99,16 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
       child: Row(
         children: [
           DesktopMenu(
-            onSelectionChanged: onMenuSelectionChanged,
+            // onSelectionChanged: onMenuSelectionChanged,
+            onSelectionWillChange: onMenuSelectionWillChange,
           ),
           Container(
             width: 1,
             color: Theme.of(context).extension<StackColors>()!.background,
           ),
           Expanded(
-            child: contentViews[currentViewKey]!,
+            child: contentViews[
+                ref.watch(currentDesktopMenuItemProvider.state).state]!,
           ),
         ],
       ),
diff --git a/lib/pages_desktop_specific/home/desktop_menu.dart b/lib/pages_desktop_specific/home/desktop_menu.dart
index cfa1a0ff0..bdaa1d6ce 100644
--- a/lib/pages_desktop_specific/home/desktop_menu.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu.dart
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_menu_item.dart';
+import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -21,10 +22,12 @@ enum DesktopMenuItemId {
 class DesktopMenu extends ConsumerStatefulWidget {
   const DesktopMenu({
     Key? key,
-    required this.onSelectionChanged,
+    this.onSelectionChanged,
+    this.onSelectionWillChange,
   }) : super(key: key);
 
   final void Function(DesktopMenuItemId)? onSelectionChanged;
+  final void Function(DesktopMenuItemId)? onSelectionWillChange;
 
   @override
   ConsumerState<DesktopMenu> createState() => _DesktopMenuState();
@@ -35,12 +38,12 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
   static const minimizedWidth = 72.0;
 
   double _width = expandedWidth;
-  DesktopMenuItemId selectedMenuItem = DesktopMenuItemId.myStack;
 
   void updateSelectedMenuItem(DesktopMenuItemId idKey) {
-    setState(() {
-      selectedMenuItem = idKey;
-    });
+    widget.onSelectionWillChange?.call(idKey);
+
+    ref.read(currentDesktopMenuItemProvider.state).state = idKey;
+
     widget.onSelectionChanged?.call(idKey);
   }
 
@@ -95,7 +98,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.walletDesktop,
                         width: 20,
                         height: 20,
-                        color: DesktopMenuItemId.myStack == selectedMenuItem
+                        color: DesktopMenuItemId.myStack ==
+                                ref
+                                    .watch(currentDesktopMenuItemProvider.state)
+                                    .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -106,7 +112,8 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "My Stack",
                       value: DesktopMenuItemId.myStack,
-                      group: selectedMenuItem,
+                      group:
+                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
                     ),
@@ -118,7 +125,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                     //     Assets.svg.exchangeDesktop,
                     //     width: 20,
                     //     height: 20,
-                    //     color: DesktopMenuItemId.exchange == selectedMenuItem
+                    //     color: DesktopMenuItemId.exchange == ref.watch(currentDesktopMenuItemProvider.state).state
                     //         ? Theme.of(context)
                     //             .extension<StackColors>()!
                     //             .textDark
@@ -129,7 +136,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                     //   ),
                     //   label: "Exchange",
                     //   value: DesktopMenuItemId.exchange,
-                    //   group: selectedMenuItem,
+                    //   group: ref.watch(currentDesktopMenuItemProvider.state).state,
                     //   onChanged: updateSelectedMenuItem,
                     //   iconOnly: _width == minimizedWidth,
                     // ),
@@ -141,19 +148,22 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.bell,
                         width: 20,
                         height: 20,
-                        color:
-                            DesktopMenuItemId.notifications == selectedMenuItem
-                                ? Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textDark
-                                : Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textDark
-                                    .withOpacity(0.8),
+                        color: DesktopMenuItemId.notifications ==
+                                ref
+                                    .watch(currentDesktopMenuItemProvider.state)
+                                    .state
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark
+                                .withOpacity(0.8),
                       ),
                       label: "Notifications",
                       value: DesktopMenuItemId.notifications,
-                      group: selectedMenuItem,
+                      group:
+                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
                     ),
@@ -165,7 +175,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.addressBookDesktop,
                         width: 20,
                         height: 20,
-                        color: DesktopMenuItemId.addressBook == selectedMenuItem
+                        color: DesktopMenuItemId.addressBook ==
+                                ref
+                                    .watch(currentDesktopMenuItemProvider.state)
+                                    .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -176,7 +189,8 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Address Book",
                       value: DesktopMenuItemId.addressBook,
-                      group: selectedMenuItem,
+                      group:
+                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
                     ),
@@ -188,7 +202,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.gear,
                         width: 20,
                         height: 20,
-                        color: DesktopMenuItemId.settings == selectedMenuItem
+                        color: DesktopMenuItemId.settings ==
+                                ref
+                                    .watch(currentDesktopMenuItemProvider.state)
+                                    .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -199,7 +216,8 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Settings",
                       value: DesktopMenuItemId.settings,
-                      group: selectedMenuItem,
+                      group:
+                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
                     ),
@@ -211,7 +229,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.messageQuestion,
                         width: 20,
                         height: 20,
-                        color: DesktopMenuItemId.support == selectedMenuItem
+                        color: DesktopMenuItemId.support ==
+                                ref
+                                    .watch(currentDesktopMenuItemProvider.state)
+                                    .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -222,7 +243,8 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Support",
                       value: DesktopMenuItemId.support,
-                      group: selectedMenuItem,
+                      group:
+                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
                     ),
@@ -234,7 +256,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         Assets.svg.aboutDesktop,
                         width: 20,
                         height: 20,
-                        color: DesktopMenuItemId.about == selectedMenuItem
+                        color: DesktopMenuItemId.about ==
+                                ref
+                                    .watch(currentDesktopMenuItemProvider.state)
+                                    .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
                                 .textDark
@@ -245,7 +270,8 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "About",
                       value: DesktopMenuItemId.about,
-                      group: selectedMenuItem,
+                      group:
+                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       iconOnly: _width == minimizedWidth,
                     ),
@@ -262,7 +288,8 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Exit",
                       value: 7,
-                      group: selectedMenuItem,
+                      group:
+                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: (_) {
                         // todo: save stuff/ notify before exit?
                         exit(0);
diff --git a/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart b/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart
index c8e688aa6..0c51f899d 100644
--- a/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart
+++ b/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/notifications/notification_card.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/providers/ui/unread_notifications_provider.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
@@ -47,10 +48,25 @@ class _DesktopNotificationsViewState
               ),
             )
           : ListView.builder(
+              primary: false,
               itemCount: notifications.length,
               itemBuilder: (context, index) {
-                return NotificationCard(
-                  notification: notifications[index],
+                final notification = notifications[index];
+                if (notification.read == false) {
+                  ref
+                      .read(unreadNotificationsStateProvider.state)
+                      .state
+                      .add(notification.id);
+                }
+
+                return Padding(
+                  padding: const EdgeInsets.symmetric(
+                    horizontal: 24,
+                    vertical: 5,
+                  ),
+                  child: NotificationCard(
+                    notification: notification,
+                  ),
                 );
               },
             ),
diff --git a/lib/providers/desktop/current_desktop_menu_item.dart b/lib/providers/desktop/current_desktop_menu_item.dart
new file mode 100644
index 000000000..6a58db6a0
--- /dev/null
+++ b/lib/providers/desktop/current_desktop_menu_item.dart
@@ -0,0 +1,5 @@
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages_desktop_specific/home/desktop_menu.dart';
+
+final currentDesktopMenuItemProvider =
+    StateProvider<DesktopMenuItemId>((ref) => DesktopMenuItemId.myStack);

From 48bfabf74e67331383bb2e5e3b635d9c1316da72 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 10:49:45 -0600
Subject: [PATCH 237/426] update desktop directory paths for swb

---
 .../stack_backup_views/helpers/swb_file_system.dart | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart
index 82d3fd97d..e88e11dfe 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/swb_file_system.dart
@@ -26,11 +26,20 @@ class SWBFileSystem {
     }
     debugPrint(rootPath!.absolute.toString());
 
-    Directory sampleFolder =
-        Directory('${rootPath!.path}Documents/Stack_backups');
+    late Directory sampleFolder;
+
     if (Platform.isIOS) {
       sampleFolder = Directory(rootPath!.path);
+    } else if (Platform.isAndroid) {
+      sampleFolder = Directory('${rootPath!.path}Documents/Stack_backups');
+    } else if (Platform.isLinux) {
+      sampleFolder = Directory('${rootPath!.path}/Stack_backups');
+    } else if (Platform.isWindows) {
+      sampleFolder = Directory('${rootPath!.path}/Stack_backups');
+    } else if (Platform.isMacOS) {
+      sampleFolder = Directory('${rootPath!.path}/Stack_backups');
     }
+
     try {
       if (!sampleFolder.existsSync()) {
         sampleFolder.createSync(recursive: true);

From ceaaa0a4f065f6543c48dada95d5c8e4edc10230 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 11:25:34 -0600
Subject: [PATCH 238/426] linter warning clean up and update process dialog
 popups

---
 .../backup_and_restore_settings.dart          |   8 +-
 .../create_auto_backup.dart                   | 228 ++++++++++++------
 .../enable_backup_dialog.dart                 |   5 +-
 3 files changed, 162 insertions(+), 79 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 0df7c8975..47d1ffdc1 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart';
+import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
 import 'package:stackwallet/providers/global/locale_provider.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -15,6 +16,7 @@ import 'package:stackwallet/utilities/format.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/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
@@ -23,9 +25,6 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:url_launcher/url_launcher.dart';
 
-import '../../../../providers/global/auto_swb_service_provider.dart';
-import '../../../../widgets/custom_buttons/blue_text_button.dart';
-
 class BackupRestoreSettings extends ConsumerStatefulWidget {
   const BackupRestoreSettings({Key? key}) : super(key: key);
 
@@ -99,7 +98,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
       useSafeArea: false,
       barrierDismissible: true,
       builder: (context) {
-        return CreateAutoBackup();
+        return const CreateAutoBackup();
       },
     );
   }
@@ -428,6 +427,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                                 width: 190,
                                                 label: "Edit auto backup",
                                                 onPressed: () {
+                                                  Navigator.of(context).pop();
                                                   createAutoBackup();
                                                 },
                                               ),
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 02d33fb95..e383d6fe9 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -1,3 +1,4 @@
+import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
 
@@ -22,8 +23,8 @@ 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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
@@ -119,10 +120,9 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType ");
 
-    bool isEnabledAutoBackup = ref.watch(prefsChangeNotifierProvider
-        .select((value) => value.isAutoBackupEnabled));
+    // bool isEnabledAutoBackup = ref.watch(prefsChangeNotifierProvider
+    //     .select((value) => value.isAutoBackupEnabled));
 
-    String? selectedItem = "Every 10 minutes";
     final isDesktop = Util.isDesktop;
     return DesktopDialog(
       maxHeight: 680,
@@ -140,25 +140,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                   textAlign: TextAlign.center,
                 ),
               ),
-              Padding(
-                padding: const EdgeInsets.all(20.0),
-                child: AppBarIconButton(
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .textFieldDefaultBG,
-                  size: 40,
-                  icon: SvgPicture.asset(
-                    Assets.svg.x,
-                    color: Theme.of(context).extension<StackColors>()!.textDark,
-                    width: 22,
-                    height: 22,
-                  ),
-                  onPressed: () {
-                    int count = 0;
-                    Navigator.of(context).popUntil((_) => count++ >= 2);
-                  },
-                ),
-              ),
+              const DesktopDialogCloseButton(),
             ],
           ),
           const SizedBox(
@@ -487,7 +469,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
             child: isDesktop
                 ? DropdownButtonHideUnderline(
                     child: DropdownButton2(
-                      offset: Offset(0, -10),
+                      offset: const Offset(0, -10),
                       isExpanded: true,
                       dropdownElevation: 0,
                       value: _currentDropDownValue,
@@ -570,12 +552,8 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                 Expanded(
                   child: SecondaryButton(
                     label: "Cancel",
-                    onPressed: () {
-                      int count = 0;
-                      !isEnabledAutoBackup
-                          ? Navigator.of(context).popUntil((_) => count++ >= 2)
-                          : Navigator.of(context).pop();
-                    },
+                    desktopMed: true,
+                    onPressed: Navigator.of(context).pop,
                   ),
                 ),
                 const SizedBox(
@@ -583,6 +561,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                 ),
                 Expanded(
                   child: PrimaryButton(
+                    desktopMed: true,
                     label: "Enable Auto Backup",
                     enabled: shouldEnableCreate,
                     onPressed: !shouldEnableCreate
@@ -595,44 +574,89 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                                 passphraseRepeatController.text;
 
                             if (pathToSave.isEmpty) {
-                              showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "Directory not chosen",
-                                context: context,
+                              unawaited(
+                                showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "Directory not chosen",
+                                  context: context,
+                                ),
                               );
                               return;
                             }
                             if (!(await Directory(pathToSave).exists())) {
-                              showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "Directory does not exist",
-                                context: context,
+                              unawaited(
+                                showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "Directory does not exist",
+                                  context: context,
+                                ),
                               );
                               return;
                             }
                             if (passphrase.isEmpty) {
-                              showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "A passphrase is required",
-                                context: context,
+                              unawaited(
+                                showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "A passphrase is required",
+                                  context: context,
+                                ),
                               );
                               return;
                             }
                             if (passphrase != repeatPassphrase) {
-                              showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "Passphrase does not match",
-                                context: context,
+                              unawaited(
+                                showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "Passphrase does not match",
+                                  context: context,
+                                ),
                               );
                               return;
                             }
 
-                            showDialog<dynamic>(
-                              context: context,
-                              barrierDismissible: false,
-                              builder: (_) => const StackDialog(
-                                title: "Encrypting initial backup",
-                                message: "This shouldn't take long",
+                            unawaited(
+                              showDialog<dynamic>(
+                                context: context,
+                                barrierDismissible: false,
+                                builder: (_) {
+                                  if (Util.isDesktop) {
+                                    return DesktopDialog(
+                                      maxHeight: double.infinity,
+                                      maxWidth: 450,
+                                      child: Padding(
+                                        padding: const EdgeInsets.all(
+                                          32,
+                                        ),
+                                        child: Column(
+                                          mainAxisSize: MainAxisSize.min,
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            Text(
+                                              "Encrypting initial backup",
+                                              style: STextStyles.desktopH3(
+                                                  context),
+                                            ),
+                                            const SizedBox(
+                                              height: 40,
+                                            ),
+                                            Text(
+                                              "This shouldn't take long",
+                                              style: STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context),
+                                            ),
+                                          ],
+                                        ),
+                                      ),
+                                    );
+                                  } else {
+                                    return const StackDialog(
+                                      title: "Encrypting initial backup",
+                                      message: "This shouldn't take long",
+                                    );
+                                  }
+                                },
                               ),
                             );
 
@@ -653,10 +677,12 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                                   .log("$err\n$s", level: LogLevel.Error);
                               // pop encryption progress dialog
                               Navigator.of(context).pop();
-                              showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: err,
-                                context: context,
+                              unawaited(
+                                showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: err,
+                                  context: context,
+                                ),
                               );
                               return;
                             } catch (e, s) {
@@ -664,10 +690,12 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                                   .log("$e\n$s", level: LogLevel.Error);
                               // pop encryption progress dialog
                               Navigator.of(context).pop();
-                              showFloatingFlushBar(
-                                type: FlushBarType.warning,
-                                message: "$e",
-                                context: context,
+                              unawaited(
+                                showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "$e",
+                                  context: context,
+                                ),
                               );
                               return;
                             }
@@ -698,9 +726,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
 
                             if (mounted) {
                               // pop encryption progress dialog
-                              int count = 0;
-                              Navigator.of(context)
-                                  .popUntil((_) => count++ >= 2);
+                              Navigator.of(context).pop();
 
                               if (result) {
                                 ref
@@ -717,22 +743,76 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                                 await showDialog<dynamic>(
                                   context: context,
                                   barrierDismissible: false,
-                                  builder: (_) => Platform.isAndroid
-                                      ? StackOkDialog(
-                                          title:
-                                              "Stack Auto Backup enabled and saved to:",
-                                          message: fileToSave,
-                                        )
-                                      : const StackOkDialog(
-                                          title: "Stack Auto Backup enabled!"),
+                                  builder: (context) {
+                                    if (Platform.isAndroid) {
+                                      return StackOkDialog(
+                                        title:
+                                            "Stack Auto Backup enabled and saved to:",
+                                        message: fileToSave,
+                                      );
+                                    } else if (Util.isDesktop) {
+                                      return DesktopDialog(
+                                        maxHeight: double.infinity,
+                                        maxWidth: 500,
+                                        child: Padding(
+                                          padding: const EdgeInsets.only(
+                                            left: 32,
+                                            right: 32,
+                                            bottom: 32,
+                                          ),
+                                          child: Column(
+                                            mainAxisSize: MainAxisSize.min,
+                                            crossAxisAlignment:
+                                                CrossAxisAlignment.start,
+                                            children: [
+                                              Row(
+                                                mainAxisAlignment:
+                                                    MainAxisAlignment
+                                                        .spaceBetween,
+                                                children: [
+                                                  Text(
+                                                    "Stack Auto Backup enabled!",
+                                                    style:
+                                                        STextStyles.desktopH3(
+                                                            context),
+                                                  ),
+                                                  const DesktopDialogCloseButton(),
+                                                ],
+                                              ),
+                                              const SizedBox(
+                                                height: 40,
+                                              ),
+                                              Row(
+                                                children: [
+                                                  const Spacer(),
+                                                  Expanded(
+                                                    child: PrimaryButton(
+                                                      label: "Ok",
+                                                      desktopMed: true,
+                                                      onPressed: () {
+                                                        Navigator.of(context)
+                                                            .pop();
+                                                      },
+                                                    ),
+                                                  ),
+                                                ],
+                                              )
+                                            ],
+                                          ),
+                                        ),
+                                      );
+                                    } else {
+                                      return const StackOkDialog(
+                                        title: "Stack Auto Backup enabled!",
+                                      );
+                                    }
+                                  },
                                 );
                                 if (mounted) {
                                   passphraseController.text = "";
                                   passphraseRepeatController.text = "";
 
-                                  int count = 0;
-                                  Navigator.of(context)
-                                      .popUntil((_) => count++ >= 2);
+                                  Navigator.of(context).pop();
                                 }
                               } else {
                                 await showDialog<dynamic>(
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
index 963fb4441..6496253d5 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
@@ -18,7 +18,7 @@ class EnableBackupDialog extends StatelessWidget {
         useSafeArea: false,
         barrierDismissible: true,
         builder: (context) {
-          return CreateAutoBackup();
+          return const CreateAutoBackup();
         },
       );
     }
@@ -59,6 +59,7 @@ class EnableBackupDialog extends StatelessWidget {
               children: [
                 Expanded(
                   child: SecondaryButton(
+                    desktopMed: true,
                     label: "Cancel",
                     onPressed: () {
                       Navigator.of(context).pop();
@@ -70,8 +71,10 @@ class EnableBackupDialog extends StatelessWidget {
                 ),
                 Expanded(
                   child: PrimaryButton(
+                    desktopMed: true,
                     label: "Continue",
                     onPressed: () {
+                      Navigator.of(context).pop();
                       createAutoBackup();
                     },
                   ),

From f46c0dacf9f22c8ec62acd6bd46933791b5bd7c3 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 14 Nov 2022 08:26:36 -0700
Subject: [PATCH 239/426] fixed desktop sizing error

---
 .../desktop_address_book.dart                 | 245 ++++++++++--------
 1 file changed, 134 insertions(+), 111 deletions(-)

diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index 367671a3e..e375bbcc7 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/contact.dart';
+import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -11,6 +12,7 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
@@ -42,7 +44,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
       useSafeArea: false,
       barrierDismissible: true,
       builder: (context) {
-        return DesktopDialog(
+        return const DesktopDialog(
           maxHeight: 609,
           maxWidth: 576,
           child: AddressBookFilterView(),
@@ -51,6 +53,21 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
     );
   }
 
+  Future<void> newContact() async {
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) {
+        return const DesktopDialog(
+          maxHeight: 609,
+          maxWidth: 576,
+          child: AddAddressBookEntryView(),
+        );
+      },
+    );
+  }
+
   @override
   void initState() {
     _searchController = TextEditingController();
@@ -71,6 +88,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
     final hasWallets = ref.watch(walletsChangeNotifierProvider).hasWallets;
+    final size = MediaQuery.of(context).size;
 
     return Column(
       mainAxisSize: MainAxisSize.min,
@@ -93,127 +111,132 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
         const SizedBox(height: 53),
         Padding(
           padding: const EdgeInsets.symmetric(horizontal: 24),
-          child: Row(
-            children: [
-              SizedBox(
-                height: 60,
-                width: 489,
-                child: ClipRRect(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
-                  child: TextField(
-                    autocorrect: false,
-                    enableSuggestions: false,
-                    controller: _searchController,
-                    focusNode: _searchFocusNode,
-                    onChanged: (newString) {
-                      setState(() => filter = newString);
-                    },
-                    style: STextStyles.field(context),
-                    decoration: standardInputDecoration(
-                      "Search...",
-                      _searchFocusNode,
-                      context,
-                    ).copyWith(
-                      labelStyle: STextStyles.fieldLabel(context)
-                          .copyWith(fontSize: 16),
-                      prefixIcon: Padding(
-                        padding: const EdgeInsets.symmetric(
-                          horizontal: 10,
-                          vertical: 16,
+          child: RoundedContainer(
+            color: Theme.of(context).extension<StackColors>()!.background,
+            child: Row(
+              children: [
+                SizedBox(
+                  height: 60,
+                  width: size.width - 800,
+                  child: ClipRRect(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
+                    child: TextField(
+                      autocorrect: false,
+                      enableSuggestions: false,
+                      controller: _searchController,
+                      focusNode: _searchFocusNode,
+                      onChanged: (newString) {
+                        setState(() => filter = newString);
+                      },
+                      style: STextStyles.field(context),
+                      decoration: standardInputDecoration(
+                        "Search...",
+                        _searchFocusNode,
+                        context,
+                      ).copyWith(
+                        labelStyle: STextStyles.fieldLabel(context)
+                            .copyWith(fontSize: 16),
+                        prefixIcon: Padding(
+                          padding: const EdgeInsets.symmetric(
+                            horizontal: 10,
+                            vertical: 16,
+                          ),
+                          child: SvgPicture.asset(
+                            Assets.svg.search,
+                            width: 16,
+                            height: 16,
+                          ),
                         ),
-                        child: SvgPicture.asset(
-                          Assets.svg.search,
-                          width: 16,
-                          height: 16,
-                        ),
-                      ),
-                      suffixIcon: _searchController.text.isNotEmpty
-                          ? Padding(
-                              padding: const EdgeInsets.only(right: 0),
-                              child: UnconstrainedBox(
-                                child: Row(
-                                  children: [
-                                    TextFieldIconButton(
-                                      child: const XIcon(),
-                                      onTap: () async {
-                                        setState(() {
-                                          _searchController.text = "";
-                                          filter = "";
-                                        });
-                                      },
-                                    ),
-                                  ],
+                        suffixIcon: _searchController.text.isNotEmpty
+                            ? Padding(
+                                padding: const EdgeInsets.only(right: 0),
+                                child: UnconstrainedBox(
+                                  child: Row(
+                                    children: [
+                                      TextFieldIconButton(
+                                        child: const XIcon(),
+                                        onTap: () async {
+                                          setState(() {
+                                            _searchController.text = "";
+                                            filter = "";
+                                          });
+                                        },
+                                      ),
+                                    ],
+                                  ),
                                 ),
-                              ),
-                            )
-                          : null,
+                              )
+                            : null,
+                      ),
                     ),
                   ),
                 ),
-              ),
-              const SizedBox(width: 20),
-              TextButton(
-                style: Theme.of(context)
-                    .extension<StackColors>()!
-                    .getDesktopMenuButtonColorSelected(context),
-                onPressed: () {
-                  selectCryptocurrency();
-                },
-                child: SizedBox(
-                  width: 200,
-                  height: 56,
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.center,
-                    children: [
-                      Padding(
-                        padding: const EdgeInsets.symmetric(horizontal: 10),
-                        child: SvgPicture.asset(Assets.svg.filter),
-                      ),
-                      Text(
-                        "Filter",
-                        style: STextStyles.desktopTextExtraExtraSmall(context)
-                            .copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .textDark,
+                const SizedBox(width: 20),
+                TextButton(
+                  style: Theme.of(context)
+                      .extension<StackColors>()!
+                      .getDesktopMenuButtonColorSelected(context),
+                  onPressed: () {
+                    selectCryptocurrency();
+                  },
+                  child: SizedBox(
+                    width: 200,
+                    height: 56,
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        Padding(
+                          padding: const EdgeInsets.symmetric(horizontal: 10),
+                          child: SvgPicture.asset(Assets.svg.filter),
                         ),
-                      ),
-                    ],
+                        Text(
+                          "Filter",
+                          style: STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark,
+                          ),
+                        ),
+                      ],
+                    ),
                   ),
                 ),
-              ),
-              const SizedBox(width: 20),
-              TextButton(
-                style: Theme.of(context)
-                    .extension<StackColors>()!
-                    .getPrimaryEnabledButtonColor(context),
-                onPressed: () {},
-                child: SizedBox(
-                  width: 200,
-                  height: 56,
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.center,
-                    children: [
-                      Padding(
-                        padding: const EdgeInsets.symmetric(horizontal: 10),
-                        child: SvgPicture.asset(Assets.svg.circlePlus),
-                      ),
-                      Text(
-                        "Add new",
-                        style: STextStyles.desktopTextExtraExtraSmall(context)
-                            .copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .popupBG,
+                const SizedBox(width: 20),
+                TextButton(
+                  style: Theme.of(context)
+                      .extension<StackColors>()!
+                      .getPrimaryEnabledButtonColor(context),
+                  onPressed: () {
+                    newContact();
+                  },
+                  child: SizedBox(
+                    width: 200,
+                    height: 56,
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        Padding(
+                          padding: const EdgeInsets.symmetric(horizontal: 10),
+                          child: SvgPicture.asset(Assets.svg.circlePlus),
                         ),
-                      ),
-                    ],
+                        Text(
+                          "Add new",
+                          style: STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .popupBG,
+                          ),
+                        ),
+                      ],
+                    ),
                   ),
                 ),
-              ),
-            ],
+              ],
+            ),
           ),
         ),
         Padding(

From e91c99883b24f8171db4c296845742f7712f552b Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 14 Nov 2022 11:43:00 -0700
Subject: [PATCH 240/426] edit auto backup navigation route error

---
 .../backup_and_restore/backup_and_restore_settings.dart         | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 47d1ffdc1..7d86999ac 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -427,7 +427,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                                 width: 190,
                                                 label: "Edit auto backup",
                                                 onPressed: () {
-                                                  Navigator.of(context).pop();
+                                                  // Navigator.of(context).pop();
                                                   createAutoBackup();
                                                 },
                                               ),

From 27b6293072b8287769d3c72f2171008ee7bd5d9b Mon Sep 17 00:00:00 2001
From: Dan Miller <dan@cypherstack.com>
Date: Mon, 14 Nov 2022 11:09:25 -0800
Subject: [PATCH 241/426] Add markdown python lib dependency to linux build
 script comments.

---
 scripts/linux/build_secure_storage_deps.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/linux/build_secure_storage_deps.sh b/scripts/linux/build_secure_storage_deps.sh
index 378f7a604..7a725d65c 100755
--- a/scripts/linux/build_secure_storage_deps.sh
+++ b/scripts/linux/build_secure_storage_deps.sh
@@ -20,7 +20,7 @@ cd "$LINUX_DIRECTORY" || exit
 # Build libSecret
 # sudo apt install meson libgirepository1.0-dev valac xsltproc gi-docgen docbook-xsl
 # sudo apt install python3-pip
-#pip3 install --user meson --upgrade
+#pip3 install --user meson markdown --upgrade
 # pip3 install --user gi-docgen
 cd build || exit
 git -C libsecret pull || git clone https://gitlab.gnome.org/GNOME/libsecret.git libsecret

From 29ec03fb87572538f67b6d7832cca8896e8d4706 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 11:40:12 -0600
Subject: [PATCH 242/426] disable swb auto backup desktop popup

---
 .../backup_and_restore_settings.dart          | 169 ++++++++++--------
 1 file changed, 91 insertions(+), 78 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 7d86999ac..53ce55424 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -19,8 +19,10 @@ import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:url_launcher/url_launcher.dart';
@@ -149,61 +151,80 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                 ),
               )
             : DesktopDialog(
-                maxHeight: 270,
-                child: Padding(
-                  padding: EdgeInsets.symmetric(vertical: 20, horizontal: 32),
-                  child: Column(
-                    children: [
-                      Text(
-                        "Disable Auto Backup",
-                        style: STextStyles.desktopH3(context),
-                      ),
-                      const SizedBox(height: 24),
-                      SizedBox(
-                        width: 600,
-                        child: Text(
-                          "You are turning off Auto Backup. You can turn it back on at any time. "
-                          "Your previous Auto Backup file will not be deleted. Remember to backup your wallets "
-                          "manually so you don't lose important information.",
-                          style: STextStyles.desktopTextSmall(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark3,
+                maxHeight: double.infinity,
+                maxWidth: 580,
+                child: Column(
+                  mainAxisSize: MainAxisSize.min,
+                  children: [
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Padding(
+                          padding: const EdgeInsets.only(
+                            left: 32,
+                          ),
+                          child: Text(
+                            "Disable Auto Backup",
+                            style: STextStyles.desktopH3(context),
                           ),
                         ),
+                        const DesktopDialogCloseButton(),
+                      ],
+                    ),
+                    Padding(
+                      padding: const EdgeInsets.only(
+                        left: 32,
+                        right: 32,
+                        bottom: 32,
                       ),
-                      const Spacer(),
-                      Row(
-                        mainAxisAlignment: MainAxisAlignment.center,
+                      child: Column(
+                        mainAxisSize: MainAxisSize.min,
+                        crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
-                          SecondaryButton(
-                            width: 248,
-                            desktopMed: true,
-                            enabled: true,
-                            label: "Back",
-                            onPressed: () {
-                              Navigator.of(context).pop();
-                            },
+                          SizedBox(
+                            width: 600,
+                            child: Text(
+                              "You are turning off Auto Backup. You can turn it back on at any time. Your previous Auto Backup file will not be deleted. Remember to backup your wallets manually so you don't lose important information.",
+                              style: STextStyles.desktopTextSmall(context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark3,
+                              ),
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 48,
+                          ),
+                          Row(
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            children: [
+                              Expanded(
+                                child: SecondaryButton(
+                                  desktopMed: true,
+                                  label: "Cancel",
+                                  onPressed: Navigator.of(context).pop,
+                                ),
+                              ),
+                              const SizedBox(width: 16),
+                              Expanded(
+                                child: PrimaryButton(
+                                  desktopMed: true,
+                                  label: "Disable",
+                                  onPressed: () {
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .isAutoBackupEnabled = false;
+                                    Navigator.of(context).pop();
+                                  },
+                                ),
+                              ),
+                            ],
                           ),
-                          const SizedBox(width: 20),
-                          PrimaryButton(
-                            width: 248,
-                            desktopMed: true,
-                            enabled: true,
-                            label: "Disable",
-                            onPressed: () {
-                              Navigator.of(context).pop();
-                              setState(() {
-                                ref
-                                    .watch(prefsChangeNotifierProvider)
-                                    .isAutoBackupEnabled = false;
-                              });
-                            },
-                          )
                         ],
                       ),
-                    ],
-                  ),
+                    ),
+                  ],
                 ),
               );
       },
@@ -372,40 +393,32 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                         crossAxisAlignment:
                                             CrossAxisAlignment.start,
                                         children: [
-                                          Container(
+                                          RoundedContainer(
                                             width: 403,
                                             color: Theme.of(context)
                                                 .extension<StackColors>()!
                                                 .background,
-                                            child: Padding(
-                                              padding:
-                                                  const EdgeInsets.all(8.0),
-                                              child: Column(
-                                                children: [
-                                                  Row(
-                                                    mainAxisAlignment:
-                                                        MainAxisAlignment
-                                                            .spaceBetween,
-                                                    children: [
-                                                      Text(
-                                                        "Backed up ${prettySinceLastBackupString(ref.watch(prefsChangeNotifierProvider.select((value) => value.lastAutoBackup)))}",
-                                                        style: STextStyles
-                                                            .itemSubtitle(
-                                                                context),
-                                                      ),
-                                                      BlueTextButton(
-                                                        text: "Back up now",
-                                                        onTap: () {
-                                                          ref
-                                                              .read(
-                                                                  autoSWBServiceProvider)
-                                                              .doBackup();
-                                                        },
-                                                      ),
-                                                    ],
-                                                  ),
-                                                ],
-                                              ),
+                                            child: Row(
+                                              mainAxisAlignment:
+                                                  MainAxisAlignment
+                                                      .spaceBetween,
+                                              children: [
+                                                Text(
+                                                  "Backed up ${prettySinceLastBackupString(ref.watch(prefsChangeNotifierProvider.select((value) => value.lastAutoBackup)))}",
+                                                  style:
+                                                      STextStyles.itemSubtitle(
+                                                          context),
+                                                ),
+                                                BlueTextButton(
+                                                  text: "Back up now",
+                                                  onTap: () {
+                                                    ref
+                                                        .read(
+                                                            autoSWBServiceProvider)
+                                                        .doBackup();
+                                                  },
+                                                ),
+                                              ],
                                             ),
                                           ),
                                           const SizedBox(

From bdf100842437628e60f50994cdbd33406c6108c7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 12:19:26 -0600
Subject: [PATCH 243/426] desktop edit auto swb functionality

---
 .../edit_auto_backup_view.dart                | 1170 +++++++++--------
 .../backup_and_restore_settings.dart          |   42 +-
 .../create_auto_backup.dart                   |    2 +-
 3 files changed, 691 insertions(+), 523 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
index 4d3c6ca99..3b6d87b52 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
@@ -1,6 +1,8 @@
+import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:dropdown_button2/dropdown_button2.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -15,6 +17,7 @@ import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/format.dart';
@@ -22,7 +25,10 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
@@ -51,6 +57,14 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
   late final SWBFileSystem stackFileSystem;
   final zxcvbn = Zxcvbn();
 
+  late BackupFrequencyType _currentDropDownValue;
+
+  final List<BackupFrequencyType> _dropDownItems = [
+    BackupFrequencyType.everyTenMinutes,
+    BackupFrequencyType.everyAppStart,
+    BackupFrequencyType.afterClosingAWallet,
+  ];
+
   String passwordFeedback =
       "Add another word or two. Uncommon words are better. Use a few words, avoid common phrases. No need for symbols, digits, or uppercase letters.";
 
@@ -66,6 +80,157 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
         passwordRepeatController.text.isNotEmpty;
   }
 
+  void onSavePressed() async {
+    final String pathToSave = fileLocationController.text;
+    final String passphrase = passwordController.text;
+    final String repeatPassphrase = passwordRepeatController.text;
+
+    if (pathToSave.isEmpty) {
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "Directory not chosen",
+          context: context,
+        ),
+      );
+      return;
+    }
+    if (!(await Directory(pathToSave).exists())) {
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "Directory does not exist",
+          context: context,
+        ),
+      );
+      return;
+    }
+    if (passphrase.isEmpty) {
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "A passphrase is required",
+          context: context,
+        ),
+      );
+      return;
+    }
+    if (passphrase != repeatPassphrase) {
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "Passphrase does not match",
+          context: context,
+        ),
+      );
+      return;
+    }
+
+    unawaited(
+      showDialog<dynamic>(
+        context: context,
+        barrierDismissible: false,
+        builder: (_) => const StackDialog(
+          title: "Updating Auto Backup",
+          message: "This shouldn't take long",
+        ),
+      ),
+    );
+    // make sure the dialog is able to be displayed for at least 1 second
+    final fut = Future<void>.delayed(const Duration(seconds: 1));
+
+    String adkString;
+    int adkVersion;
+    try {
+      final adk = await compute(generateAdk, passphrase);
+      adkString = Format.uint8listToString(adk.item2);
+      adkVersion = adk.item1;
+    } on Exception catch (e, s) {
+      String err = getErrorMessageFromSWBException(e);
+      Logging.instance.log("$err\n$s", level: LogLevel.Error);
+      // pop encryption progress dialog
+      Navigator.of(context).pop();
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: err,
+          context: context,
+        ),
+      );
+      return;
+    } catch (e, s) {
+      Logging.instance.log("$e\n$s", level: LogLevel.Error);
+      // pop encryption progress dialog
+      Navigator.of(context).pop();
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "$e",
+          context: context,
+        ),
+      );
+      return;
+    }
+
+    await secureStore.write(key: "auto_adk_string", value: adkString);
+    await secureStore.write(
+        key: "auto_adk_version_string", value: adkVersion.toString());
+
+    final DateTime now = DateTime.now();
+    final String fileToSave = createAutoBackupFilename(pathToSave, now);
+
+    final backup = await SWB.createStackWalletJSON(
+      secureStorage: ref.read(secureStoreProvider),
+    );
+
+    bool result = await SWB.encryptStackWalletWithADK(
+      fileToSave,
+      adkString,
+      jsonEncode(backup),
+      adkVersion: adkVersion,
+    );
+
+    // this future should already be complete unless there was an error encrypting
+    await Future.wait([fut]);
+
+    if (mounted) {
+      // pop encryption progress dialog
+      Navigator.of(context).pop();
+
+      if (result) {
+        ref.read(prefsChangeNotifierProvider).autoBackupLocation = pathToSave;
+        ref.read(prefsChangeNotifierProvider).lastAutoBackup = now;
+
+        ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled = true;
+
+        await showDialog<dynamic>(
+          context: context,
+          barrierDismissible: false,
+          builder: (_) => Platform.isAndroid
+              ? StackOkDialog(
+                  title: "Stack Auto Backup saved to:",
+                  message: fileToSave,
+                )
+              : const StackOkDialog(title: "Stack Auto Backup saved"),
+        );
+        if (mounted) {
+          passwordController.text = "";
+          passwordRepeatController.text = "";
+
+          Navigator.of(context)
+              .popUntil(ModalRoute.withName(AutoBackupView.routeName));
+        }
+      } else {
+        await showDialog<dynamic>(
+          context: context,
+          barrierDismissible: false,
+          builder: (_) =>
+              const StackOkDialog(title: "Failed to update Auto Backup"),
+        );
+      }
+    }
+  }
+
   @override
   void initState() {
     secureStore = ref.read(secureStoreProvider);
@@ -77,6 +242,9 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
     fileLocationController.text =
         ref.read(prefsChangeNotifierProvider).autoBackupLocation ?? "";
 
+    _currentDropDownValue =
+        ref.read(prefsChangeNotifierProvider).backupFrequencyType;
+
     passwordFocusNode = FocusNode();
     passwordRepeatFocusNode = FocusNode();
 
@@ -110,547 +278,509 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    final isDesktop = Util.isDesktop;
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Edit Auto Backup",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Edit Auto Backup",
-          style: STextStyles.navBarTitle(context),
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: LayoutBuilder(builder: (context, constraints) {
+            return SingleChildScrollView(
+              child: ConstrainedBox(
+                constraints: BoxConstraints(
+                  minHeight: constraints.maxHeight,
+                ),
+                child: IntrinsicHeight(
+                  child: child,
+                ),
+              ),
+            );
+          }),
         ),
       ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(builder: (context, constraints) {
-          return SingleChildScrollView(
-            child: ConstrainedBox(
-              constraints: BoxConstraints(
-                minHeight: constraints.maxHeight,
+      child: Column(
+        crossAxisAlignment:
+            isDesktop ? CrossAxisAlignment.start : CrossAxisAlignment.stretch,
+        children: [
+          if (!isDesktop)
+            Text(
+              "Create your backup",
+              style: STextStyles.smallMed12(context),
+            ),
+          if (isDesktop)
+            Text(
+              "Choose file location",
+              style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
               ),
-              child: IntrinsicHeight(
-                child: Column(
-                  crossAxisAlignment: CrossAxisAlignment.stretch,
-                  children: [
-                    Text(
-                      "Create your backup",
-                      style: STextStyles.smallMed12(context),
-                    ),
-                    const SizedBox(
-                      height: 10,
-                    ),
-                    if (!Platform.isAndroid)
-                      TextField(
-                        autocorrect: Util.isDesktop ? false : true,
-                        enableSuggestions: Util.isDesktop ? false : true,
-                        onTap: Platform.isAndroid
-                            ? null
-                            : () async {
-                                try {
-                                  await stackFileSystem.prepareStorage();
+              textAlign: TextAlign.left,
+            ),
+          const SizedBox(
+            height: 10,
+          ),
+          if (!Platform.isAndroid)
+            TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
+              onTap: Platform.isAndroid
+                  ? null
+                  : () async {
+                      try {
+                        await stackFileSystem.prepareStorage();
 
-                                  if (mounted) {
-                                    await stackFileSystem.pickDir(context);
-                                  }
-
-                                  if (mounted) {
-                                    setState(() {
-                                      fileLocationController.text =
-                                          stackFileSystem.dirPath ?? "";
-                                    });
-                                  }
-                                } catch (e, s) {
-                                  Logging.instance
-                                      .log("$e\n$s", level: LogLevel.Error);
-                                }
-                              },
-                        controller: fileLocationController,
-                        style: STextStyles.field(context),
-                        decoration: InputDecoration(
-                          hintText: "Save to...",
-                          hintStyle: STextStyles.fieldLabel(context),
-                          suffixIcon: UnconstrainedBox(
-                            child: Row(
-                              children: [
-                                const SizedBox(
-                                  width: 16,
-                                ),
-                                SvgPicture.asset(
-                                  Assets.svg.folder,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark3,
-                                  width: 16,
-                                  height: 16,
-                                ),
-                                const SizedBox(
-                                  width: 12,
-                                ),
-                              ],
-                            ),
-                          ),
-                        ),
-                        key: const Key(
-                            "createBackupSaveToFileLocationTextFieldKey"),
-                        readOnly: true,
-                        toolbarOptions: const ToolbarOptions(
-                          copy: true,
-                          cut: false,
-                          paste: false,
-                          selectAll: false,
-                        ),
-                        onChanged: (newValue) {},
-                      ),
-                    if (!Platform.isAndroid)
-                      const SizedBox(
-                        height: 10,
-                      ),
-                    ClipRRect(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
-                      ),
-                      child: TextField(
-                        key: const Key("createBackupPasswordFieldKey1"),
-                        focusNode: passwordFocusNode,
-                        controller: passwordController,
-                        style: STextStyles.field(context),
-                        obscureText: hidePassword,
-                        enableSuggestions: false,
-                        autocorrect: false,
-                        decoration: standardInputDecoration(
-                          "Create passphrase",
-                          passwordFocusNode,
-                          context,
-                        ).copyWith(
-                          suffixIcon: UnconstrainedBox(
-                            child: Row(
-                              children: [
-                                const SizedBox(
-                                  width: 16,
-                                ),
-                                GestureDetector(
-                                  key: const Key(
-                                      "createBackupPasswordFieldShowPasswordButtonKey"),
-                                  onTap: () async {
-                                    setState(() {
-                                      hidePassword = !hidePassword;
-                                    });
-                                  },
-                                  child: SvgPicture.asset(
-                                    hidePassword
-                                        ? Assets.svg.eye
-                                        : Assets.svg.eyeSlash,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textDark3,
-                                    width: 16,
-                                    height: 16,
-                                  ),
-                                ),
-                                const SizedBox(
-                                  width: 12,
-                                ),
-                              ],
-                            ),
-                          ),
-                        ),
-                        onChanged: (newValue) {
-                          if (newValue.isEmpty) {
-                            setState(() {
-                              passwordFeedback = "";
-                            });
-                            return;
-                          }
-                          final result = zxcvbn.evaluate(newValue);
-                          String suggestionsAndTips = "";
-                          for (var sug
-                              in result.feedback.suggestions!.toSet()) {
-                            suggestionsAndTips += "$sug\n";
-                          }
-                          suggestionsAndTips += result.feedback.warning!;
-                          String feedback =
-                              // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
-                              suggestionsAndTips;
-
-                          passwordStrength = result.score! / 4;
-
-                          // hack fix to format back string returned from zxcvbn
-                          if (feedback.contains("phrasesNo need")) {
-                            feedback = feedback.replaceFirst(
-                                "phrasesNo need", "phrases\nNo need");
-                          }
-
-                          if (feedback.endsWith("\n")) {
-                            feedback =
-                                feedback.substring(0, feedback.length - 2);
-                          }
+                        if (mounted) {
+                          await stackFileSystem.pickDir(context);
+                        }
 
+                        if (mounted) {
                           setState(() {
-                            passwordFeedback = feedback;
+                            fileLocationController.text =
+                                stackFileSystem.dirPath ?? "";
+                          });
+                        }
+                      } catch (e, s) {
+                        Logging.instance.log("$e\n$s", level: LogLevel.Error);
+                      }
+                    },
+              controller: fileLocationController,
+              style: STextStyles.field(context),
+              decoration: InputDecoration(
+                hintText: "Save to...",
+                hintStyle: STextStyles.fieldLabel(context),
+                suffixIcon: UnconstrainedBox(
+                  child: Row(
+                    children: [
+                      const SizedBox(
+                        width: 16,
+                      ),
+                      SvgPicture.asset(
+                        Assets.svg.folder,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark3,
+                        width: 16,
+                        height: 16,
+                      ),
+                      const SizedBox(
+                        width: 12,
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              key: const Key("createBackupSaveToFileLocationTextFieldKey"),
+              readOnly: true,
+              toolbarOptions: const ToolbarOptions(
+                copy: true,
+                cut: false,
+                paste: false,
+                selectAll: false,
+              ),
+              onChanged: (newValue) {},
+            ),
+          if (isDesktop)
+            const SizedBox(
+              height: 24,
+            ),
+          if (isDesktop)
+            Text(
+              "Create a passphrase",
+              style: STextStyles.desktopTextExtraSmall(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
+              ),
+              textAlign: TextAlign.left,
+            ),
+          if (!Platform.isAndroid)
+            const SizedBox(
+              height: 10,
+            ),
+          ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              key: const Key("createBackupPasswordFieldKey1"),
+              focusNode: passwordFocusNode,
+              controller: passwordController,
+              style: STextStyles.field(context),
+              obscureText: hidePassword,
+              enableSuggestions: false,
+              autocorrect: false,
+              decoration: standardInputDecoration(
+                "Create passphrase",
+                passwordFocusNode,
+                context,
+              ).copyWith(
+                suffixIcon: UnconstrainedBox(
+                  child: Row(
+                    children: [
+                      const SizedBox(
+                        width: 16,
+                      ),
+                      GestureDetector(
+                        key: const Key(
+                            "createBackupPasswordFieldShowPasswordButtonKey"),
+                        onTap: () async {
+                          setState(() {
+                            hidePassword = !hidePassword;
                           });
                         },
-                      ),
-                    ),
-                    if (passwordFocusNode.hasFocus ||
-                        passwordRepeatFocusNode.hasFocus ||
-                        passwordController.text.isNotEmpty)
-                      Padding(
-                        padding: EdgeInsets.only(
-                          left: 12,
-                          right: 12,
-                          top: passwordFeedback.isNotEmpty ? 4 : 0,
-                        ),
-                        child: passwordFeedback.isNotEmpty
-                            ? Text(
-                                passwordFeedback,
-                                style: STextStyles.infoSmall(context),
-                              )
-                            : null,
-                      ),
-                    if (passwordFocusNode.hasFocus ||
-                        passwordRepeatFocusNode.hasFocus ||
-                        passwordController.text.isNotEmpty)
-                      Padding(
-                        padding: const EdgeInsets.only(
-                          left: 12,
-                          right: 12,
-                          top: 10,
-                        ),
-                        child: ProgressBar(
-                          key: const Key("createStackBackUpProgressBar"),
-                          width: MediaQuery.of(context).size.width - 32 - 24,
-                          height: 5,
-                          fillColor: passwordStrength < 0.51
-                              ? Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .accentColorRed
-                              : passwordStrength < 1
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .accentColorYellow
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .accentColorGreen,
-                          backgroundColor: Theme.of(context)
+                        child: SvgPicture.asset(
+                          hidePassword ? Assets.svg.eye : Assets.svg.eyeSlash,
+                          color: Theme.of(context)
                               .extension<StackColors>()!
-                              .buttonBackSecondary,
-                          percent:
-                              passwordStrength < 0.25 ? 0.03 : passwordStrength,
+                              .textDark3,
+                          width: 16,
+                          height: 16,
                         ),
                       ),
-                    const SizedBox(
-                      height: 10,
-                    ),
-                    ClipRRect(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
+                      const SizedBox(
+                        width: 12,
                       ),
-                      child: TextField(
-                        key: const Key("createBackupPasswordFieldKey2"),
-                        focusNode: passwordRepeatFocusNode,
-                        controller: passwordRepeatController,
-                        style: STextStyles.field(context),
-                        obscureText: hidePassword,
-                        enableSuggestions: false,
-                        autocorrect: false,
-                        decoration: standardInputDecoration(
-                          "Confirm passphrase",
-                          passwordRepeatFocusNode,
-                          context,
-                        ).copyWith(
-                          suffixIcon: UnconstrainedBox(
-                            child: Row(
-                              children: [
-                                const SizedBox(
-                                  width: 16,
-                                ),
-                                GestureDetector(
-                                  key: const Key(
-                                      "createBackupPasswordFieldShowPasswordButtonKey"),
-                                  onTap: () async {
-                                    setState(() {
-                                      hidePassword = !hidePassword;
-                                    });
-                                  },
-                                  child: SvgPicture.asset(
-                                    hidePassword
-                                        ? Assets.svg.eye
-                                        : Assets.svg.eyeSlash,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textDark3,
-                                    width: 16,
-                                    height: 16,
-                                  ),
-                                ),
-                                const SizedBox(
-                                  width: 12,
-                                ),
-                              ],
-                            ),
-                          ),
-                        ),
-                        onChanged: (newValue) {
-                          setState(() {});
-                          // TODO: ? check if passwords match?
-                        },
-                      ),
-                    ),
-                    const SizedBox(
-                      height: 32,
-                    ),
-                    Text(
-                      "Auto Backup frequency",
-                      style: STextStyles.smallMed12(context),
-                    ),
-                    const SizedBox(
-                      height: 10,
-                    ),
-                    Stack(
-                      children: [
-                        TextField(
-                          autocorrect: Util.isDesktop ? false : true,
-                          enableSuggestions: Util.isDesktop ? false : true,
-                          readOnly: true,
-                          textInputAction: TextInputAction.none,
-                        ),
-                        Positioned.fill(
-                          child: RawMaterialButton(
-                            splashColor: Theme.of(context)
-                                .extension<StackColors>()!
-                                .highlight,
-                            shape: RoundedRectangleBorder(
-                              borderRadius: BorderRadius.circular(
-                                Constants.size.circularBorderRadius,
-                              ),
-                            ),
-                            onPressed: () {
-                              showModalBottomSheet<dynamic>(
-                                backgroundColor: Colors.transparent,
-                                context: context,
-                                shape: const RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.vertical(
-                                    top: Radius.circular(20),
-                                  ),
-                                ),
-                                builder: (_) =>
-                                    const BackupFrequencyTypeSelectSheet(),
-                              );
-                            },
-                            child: Padding(
-                              padding:
-                                  const EdgeInsets.symmetric(horizontal: 12.0),
-                              child: Row(
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
-                                children: [
-                                  Text(
-                                    Format.prettyFrequencyType(ref.watch(
-                                        prefsChangeNotifierProvider.select(
-                                            (value) =>
-                                                value.backupFrequencyType))),
-                                    style: STextStyles.itemSubtitle12(context),
-                                  ),
-                                  Padding(
-                                    padding: const EdgeInsets.only(right: 4.0),
-                                    child: SvgPicture.asset(
-                                      Assets.svg.chevronDown,
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textSubtitle2,
-                                      width: 12,
-                                      height: 6,
-                                    ),
-                                  ),
-                                ],
-                              ),
-                            ),
-                          ),
-                        )
-                      ],
-                    ),
-                    const Spacer(),
-                    const SizedBox(
-                      height: 10,
-                    ),
-                    TextButton(
-                      style: shouldEnableCreate
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context)
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryDisabledButtonColor(context),
-                      onPressed: !shouldEnableCreate
-                          ? null
-                          : () async {
-                              final String pathToSave =
-                                  fileLocationController.text;
-                              final String passphrase = passwordController.text;
-                              final String repeatPassphrase =
-                                  passwordRepeatController.text;
+                    ],
+                  ),
+                ),
+              ),
+              onChanged: (newValue) {
+                if (newValue.isEmpty) {
+                  setState(() {
+                    passwordFeedback = "";
+                  });
+                  return;
+                }
+                final result = zxcvbn.evaluate(newValue);
+                String suggestionsAndTips = "";
+                for (var sug in result.feedback.suggestions!.toSet()) {
+                  suggestionsAndTips += "$sug\n";
+                }
+                suggestionsAndTips += result.feedback.warning!;
+                String feedback =
+                    // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
+                    suggestionsAndTips;
 
-                              if (pathToSave.isEmpty) {
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "Directory not chosen",
-                                  context: context,
-                                );
-                                return;
-                              }
-                              if (!(await Directory(pathToSave).exists())) {
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "Directory does not exist",
-                                  context: context,
-                                );
-                                return;
-                              }
-                              if (passphrase.isEmpty) {
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "A passphrase is required",
-                                  context: context,
-                                );
-                                return;
-                              }
-                              if (passphrase != repeatPassphrase) {
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "Passphrase does not match",
-                                  context: context,
-                                );
-                                return;
-                              }
+                passwordStrength = result.score! / 4;
 
-                              showDialog<dynamic>(
-                                context: context,
-                                barrierDismissible: false,
-                                builder: (_) => const StackDialog(
-                                  title: "Updating Auto Backup",
-                                  message: "This shouldn't take long",
-                                ),
-                              );
-                              // make sure the dialog is able to be displayed for at least 1 second
-                              final fut = Future<void>.delayed(
-                                  const Duration(seconds: 1));
+                // hack fix to format back string returned from zxcvbn
+                if (feedback.contains("phrasesNo need")) {
+                  feedback = feedback.replaceFirst(
+                      "phrasesNo need", "phrases\nNo need");
+                }
 
-                              String adkString;
-                              int adkVersion;
-                              try {
-                                final adk =
-                                    await compute(generateAdk, passphrase);
-                                adkString = Format.uint8listToString(adk.item2);
-                                adkVersion = adk.item1;
-                              } on Exception catch (e, s) {
-                                String err = getErrorMessageFromSWBException(e);
-                                Logging.instance
-                                    .log("$err\n$s", level: LogLevel.Error);
-                                // pop encryption progress dialog
-                                Navigator.of(context).pop();
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: err,
-                                  context: context,
-                                );
-                                return;
-                              } catch (e, s) {
-                                Logging.instance
-                                    .log("$e\n$s", level: LogLevel.Error);
-                                // pop encryption progress dialog
-                                Navigator.of(context).pop();
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "$e",
-                                  context: context,
-                                );
-                                return;
-                              }
+                if (feedback.endsWith("\n")) {
+                  feedback = feedback.substring(0, feedback.length - 2);
+                }
 
-                              await secureStore.write(
-                                  key: "auto_adk_string", value: adkString);
-                              await secureStore.write(
-                                  key: "auto_adk_version_string",
-                                  value: adkVersion.toString());
-
-                              final DateTime now = DateTime.now();
-                              final String fileToSave =
-                                  createAutoBackupFilename(pathToSave, now);
-
-                              final backup = await SWB.createStackWalletJSON(
-                                secureStorage: ref.read(secureStoreProvider),
-                              );
-
-                              bool result = await SWB.encryptStackWalletWithADK(
-                                fileToSave,
-                                adkString,
-                                jsonEncode(backup),
-                                adkVersion: adkVersion,
-                              );
-
-                              // this future should already be complete unless there was an error encrypting
-                              await Future.wait([fut]);
-
-                              if (mounted) {
-                                // pop encryption progress dialog
-                                Navigator.of(context).pop();
-
-                                if (result) {
-                                  ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .autoBackupLocation = pathToSave;
-                                  ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .lastAutoBackup = now;
-
-                                  ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .isAutoBackupEnabled = true;
-
-                                  await showDialog<dynamic>(
-                                    context: context,
-                                    barrierDismissible: false,
-                                    builder: (_) => Platform.isAndroid
-                                        ? StackOkDialog(
-                                            title:
-                                                "Stack Auto Backup saved to:",
-                                            message: fileToSave,
-                                          )
-                                        : const StackOkDialog(
-                                            title: "Stack Auto Backup saved"),
-                                  );
-                                  if (mounted) {
-                                    passwordController.text = "";
-                                    passwordRepeatController.text = "";
-
-                                    Navigator.of(context).popUntil(
-                                        ModalRoute.withName(
-                                            AutoBackupView.routeName));
-                                  }
-                                } else {
-                                  await showDialog<dynamic>(
-                                    context: context,
-                                    barrierDismissible: false,
-                                    builder: (_) => const StackOkDialog(
-                                        title: "Failed to update Auto Backup"),
-                                  );
-                                }
-                              }
-                            },
-                      child: Text(
-                        "Save",
-                        style: STextStyles.button(context),
-                      ),
+                setState(() {
+                  passwordFeedback = feedback;
+                });
+              },
+            ),
+          ),
+          if (passwordFocusNode.hasFocus ||
+              passwordRepeatFocusNode.hasFocus ||
+              passwordController.text.isNotEmpty)
+            Padding(
+              padding: EdgeInsets.only(
+                left: 12,
+                right: 12,
+                top: passwordFeedback.isNotEmpty ? 4 : 0,
+              ),
+              child: passwordFeedback.isNotEmpty
+                  ? Text(
+                      passwordFeedback,
+                      style: STextStyles.infoSmall(context),
                     )
-                  ],
+                  : null,
+            ),
+          if (passwordFocusNode.hasFocus ||
+              passwordRepeatFocusNode.hasFocus ||
+              passwordController.text.isNotEmpty)
+            Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                right: 12,
+                top: 10,
+              ),
+              child: ProgressBar(
+                key: const Key("createStackBackUpProgressBar"),
+                width: isDesktop
+                    ? 492
+                    : MediaQuery.of(context).size.width - 32 - 24,
+                height: 5,
+                fillColor: passwordStrength < 0.51
+                    ? Theme.of(context).extension<StackColors>()!.accentColorRed
+                    : passwordStrength < 1
+                        ? Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorYellow
+                        : Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorGreen,
+                backgroundColor: Theme.of(context)
+                    .extension<StackColors>()!
+                    .buttonBackSecondary,
+                percent: passwordStrength < 0.25 ? 0.03 : passwordStrength,
+              ),
+            ),
+          SizedBox(
+            height: isDesktop ? 16 : 10,
+          ),
+          ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              key: const Key("createBackupPasswordFieldKey2"),
+              focusNode: passwordRepeatFocusNode,
+              controller: passwordRepeatController,
+              style: STextStyles.field(context),
+              obscureText: hidePassword,
+              enableSuggestions: false,
+              autocorrect: false,
+              decoration: standardInputDecoration(
+                "Confirm passphrase",
+                passwordRepeatFocusNode,
+                context,
+              ).copyWith(
+                suffixIcon: UnconstrainedBox(
+                  child: Row(
+                    children: [
+                      const SizedBox(
+                        width: 16,
+                      ),
+                      GestureDetector(
+                        key: const Key(
+                            "createBackupPasswordFieldShowPasswordButtonKey"),
+                        onTap: () async {
+                          setState(() {
+                            hidePassword = !hidePassword;
+                          });
+                        },
+                        child: SvgPicture.asset(
+                          hidePassword ? Assets.svg.eye : Assets.svg.eyeSlash,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark3,
+                          width: 16,
+                          height: 16,
+                        ),
+                      ),
+                      const SizedBox(
+                        width: 12,
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              onChanged: (newValue) {
+                setState(() {});
+                // TODO: ? check if passwords match?
+              },
+            ),
+          ),
+          SizedBox(
+            height: isDesktop ? 24 : 32,
+          ),
+          Text(
+            "Auto Backup frequency",
+            style: isDesktop
+                ? STextStyles.desktopTextExtraSmall(context).copyWith(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.textDark3,
+                  )
+                : STextStyles.smallMed12(context),
+          ),
+          const SizedBox(
+            height: 10,
+          ),
+          if (isDesktop)
+            DropdownButtonHideUnderline(
+              child: DropdownButton2(
+                offset: const Offset(0, -10),
+                isExpanded: true,
+                dropdownElevation: 0,
+                value: _currentDropDownValue,
+                items: [
+                  ..._dropDownItems.map(
+                    (e) {
+                      String message = "";
+                      switch (e) {
+                        case BackupFrequencyType.everyTenMinutes:
+                          message = "Every 10 minutes";
+                          break;
+                        case BackupFrequencyType.everyAppStart:
+                          message = "Every app startup";
+                          break;
+                        case BackupFrequencyType.afterClosingAWallet:
+                          message = "After closing a cryptocurrency wallet";
+                          break;
+                      }
+
+                      return DropdownMenuItem(
+                        value: e,
+                        child: Text(message),
+                      );
+                    },
+                  ),
+                ],
+                onChanged: (value) {
+                  if (value is BackupFrequencyType) {
+                    if (ref
+                            .read(prefsChangeNotifierProvider)
+                            .backupFrequencyType !=
+                        value) {
+                      ref
+                          .read(prefsChangeNotifierProvider)
+                          .backupFrequencyType = value;
+                    }
+                    setState(() {
+                      _currentDropDownValue = value;
+                    });
+                  }
+                },
+                icon: SvgPicture.asset(
+                  Assets.svg.chevronDown,
+                  width: 10,
+                  height: 5,
+                  color: Theme.of(context).extension<StackColors>()!.textDark3,
+                ),
+                buttonPadding: const EdgeInsets.symmetric(
+                  horizontal: 16,
+                  vertical: 8,
+                ),
+                buttonDecoration: BoxDecoration(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldDefaultBG,
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
+                ),
+                dropdownDecoration: BoxDecoration(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldDefaultBG,
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
                 ),
               ),
             ),
-          );
-        }),
+          if (!isDesktop)
+            Stack(
+              children: [
+                TextField(
+                  autocorrect: Util.isDesktop ? false : true,
+                  enableSuggestions: Util.isDesktop ? false : true,
+                  readOnly: true,
+                  textInputAction: TextInputAction.none,
+                ),
+                Positioned.fill(
+                  child: RawMaterialButton(
+                    splashColor:
+                        Theme.of(context).extension<StackColors>()!.highlight,
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
+                      ),
+                    ),
+                    onPressed: () {
+                      showModalBottomSheet<dynamic>(
+                        backgroundColor: Colors.transparent,
+                        context: context,
+                        shape: const RoundedRectangleBorder(
+                          borderRadius: BorderRadius.vertical(
+                            top: Radius.circular(20),
+                          ),
+                        ),
+                        builder: (_) => const BackupFrequencyTypeSelectSheet(),
+                      );
+                    },
+                    child: Padding(
+                      padding: const EdgeInsets.symmetric(horizontal: 12.0),
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Text(
+                            Format.prettyFrequencyType(ref.watch(
+                                prefsChangeNotifierProvider.select(
+                                    (value) => value.backupFrequencyType))),
+                            style: STextStyles.itemSubtitle12(context),
+                          ),
+                          Padding(
+                            padding: const EdgeInsets.only(right: 4.0),
+                            child: SvgPicture.asset(
+                              Assets.svg.chevronDown,
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textSubtitle2,
+                              width: 12,
+                              height: 6,
+                            ),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                )
+              ],
+            ),
+          if (!isDesktop) const Spacer(),
+          SizedBox(
+            height: isDesktop ? 24 : 10,
+          ),
+          if (isDesktop)
+            Row(
+              children: [
+                Expanded(
+                  child: SecondaryButton(
+                    label: "Cancel",
+                    desktopMed: true,
+                    onPressed: Navigator.of(context).pop,
+                  ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Save",
+                    desktopMed: true,
+                    enabled: shouldEnableCreate,
+                    onPressed: onSavePressed,
+                  ),
+                ),
+              ],
+            ),
+          if (!isDesktop)
+            TextButton(
+              style: shouldEnableCreate
+                  ? Theme.of(context)
+                      .extension<StackColors>()!
+                      .getPrimaryEnabledButtonColor(context)
+                  : Theme.of(context)
+                      .extension<StackColors>()!
+                      .getPrimaryDisabledButtonColor(context),
+              onPressed: !shouldEnableCreate ? null : onSavePressed,
+              child: Text(
+                "Save",
+                style: STextStyles.button(context),
+              ),
+            )
+        ],
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 53ce55424..663c3f975 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:intl/intl.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart';
@@ -105,6 +106,44 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
     );
   }
 
+  Future<void> editAutoBackup() async {
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) => DesktopDialog(
+        maxWidth: 580,
+        maxHeight: double.infinity,
+        child: Column(
+          mainAxisSize: MainAxisSize.min,
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.only(left: 32),
+                  child: Text(
+                    "Edit auto backup",
+                    style: STextStyles.desktopH3(context),
+                  ),
+                ),
+                const DesktopDialogCloseButton(),
+              ],
+            ),
+            const Padding(
+              padding: EdgeInsets.only(
+                left: 32,
+                right: 32,
+                bottom: 32,
+              ),
+              child: EditAutoBackupView(),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
   Future<void> attemptDisable() async {
     final result = await showDialog<bool?>(
       context: context,
@@ -440,8 +479,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                                 width: 190,
                                                 label: "Edit auto backup",
                                                 onPressed: () {
-                                                  // Navigator.of(context).pop();
-                                                  createAutoBackup();
+                                                  editAutoBackup();
                                                 },
                                               ),
                                             ],
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index e383d6fe9..5e7e86fe1 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -383,7 +383,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                     ),
                   ),
                 const SizedBox(
-                  height: 10,
+                  height: 16,
                 ),
                 ClipRRect(
                   borderRadius: BorderRadius.circular(

From e053764554ef5ab32226110a0ed18a9d6ac1c5c5 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 13:24:40 -0600
Subject: [PATCH 244/426] basic desktop change passphrase functionality

---
 .../home/settings_menu/security_settings.dart | 820 +++++++++---------
 lib/utilities/desktop_password_service.dart   |  42 +
 2 files changed, 474 insertions(+), 388 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index 9ee9b5bfc..d752ece38 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -1,9 +1,13 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
-import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
@@ -47,6 +51,63 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
   String passwordFeedback =
       "Add another word or two. Uncommon words are better. Use a few words, avoid common phrases. No need for symbols, digits, or uppercase letters.";
 
+  Future<bool> attemptChangePW() async {
+    final String pw = passwordCurrentController.text;
+    final String pwNew = passwordController.text;
+    final String pwNewRepeat = passwordRepeatController.text;
+
+    final verified =
+        await ref.read(storageCryptoHandlerProvider).verifyPassphrase(pw);
+
+    if (verified) {
+      if (pwNew != pwNewRepeat) {
+        unawaited(
+          showFloatingFlushBar(
+            type: FlushBarType.warning,
+            message: "New passphrase does not match!",
+            context: context,
+          ),
+        );
+        return false;
+      } else {
+        final success =
+            await ref.read(storageCryptoHandlerProvider).changePassphrase(
+                  pw,
+                  pwNew,
+                );
+
+        if (success) {
+          unawaited(
+            showFloatingFlushBar(
+              type: FlushBarType.success,
+              message: "Passphrase successfully changed",
+              context: context,
+            ),
+          );
+          return true;
+        } else {
+          unawaited(
+            showFloatingFlushBar(
+              type: FlushBarType.warning,
+              message: "Passphrase change failed",
+              context: context,
+            ),
+          );
+          return false;
+        }
+      }
+    } else {
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "Current passphrase is not valid!",
+          context: context,
+        ),
+      );
+      return false;
+    }
+  }
+
   @override
   void initState() {
     passwordCurrentController = TextEditingController();
@@ -78,411 +139,394 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
     debugPrint("BUILD: $runtimeType");
     return Column(
       children: [
-        Padding(
-          padding: const EdgeInsets.only(
-            right: 30,
-          ),
-          child: RoundedWhiteContainer(
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                SvgPicture.asset(
-                  Assets.svg.circleLock,
-                  width: 48,
-                  height: 48,
-                ),
-                Center(
-                  child: Padding(
-                    padding: const EdgeInsets.all(10),
-                    child: RichText(
-                      textAlign: TextAlign.start,
-                      text: TextSpan(
-                        children: [
-                          TextSpan(
-                            text: "Change Password",
-                            style: STextStyles.desktopTextSmall(context),
-                          ),
-                          TextSpan(
-                            text:
-                                "\n\nProtect your Stack Wallet with a strong password. Stack Wallet does not store "
-                                "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
-                            style:
-                                STextStyles.desktopTextExtraExtraSmall(context),
-                          ),
-                        ],
-                      ),
-                    ),
-                  ),
-                ),
-                Column(
+        Row(
+          children: [
+            Expanded(
+              child: RoundedWhiteContainer(
+                radiusMultiplier: 2,
+                padding: const EdgeInsets.all(24),
+                child: Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
                   children: [
-                    Padding(
-                      padding: EdgeInsets.all(
-                        10,
-                      ),
-                      child: changePassword
-                          ? SizedBox(
-                              width: 512,
-                              child: Column(
-                                crossAxisAlignment: CrossAxisAlignment.start,
-                                children: [
-                                  Text(
-                                    "Current password",
-                                    style:
-                                        STextStyles.desktopTextExtraExtraSmall(
-                                                context)
-                                            .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark3),
-                                    textAlign: TextAlign.left,
-                                  ),
-                                  const SizedBox(height: 10),
-                                  ClipRRect(
-                                    borderRadius: BorderRadius.circular(
-                                      Constants.size.circularBorderRadius,
+                    SvgPicture.asset(
+                      Assets.svg.circleLock,
+                      width: 48,
+                      height: 48,
+                    ),
+                    Column(
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      children: [
+                        const SizedBox(
+                          height: 16,
+                        ),
+                        Text(
+                          "Change Password",
+                          style: STextStyles.desktopTextSmall(context),
+                        ),
+                        const SizedBox(
+                          height: 8,
+                        ),
+                        Text(
+                          "Protect your Stack Wallet with a strong password. Stack Wallet does not store "
+                          "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
+                          style:
+                              STextStyles.desktopTextExtraExtraSmall(context),
+                        ),
+                        const SizedBox(
+                          height: 20,
+                        ),
+                        changePassword
+                            ? SizedBox(
+                                width: 512,
+                                child: Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "Current password",
+                                      style: STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark3),
+                                      textAlign: TextAlign.left,
                                     ),
-                                    child: TextField(
-                                      key: const Key(
-                                          "desktopSecurityRestoreFromFilePasswordFieldKey"),
-                                      focusNode: passwordCurrentFocusNode,
-                                      controller: passwordCurrentController,
-                                      style: STextStyles.field(context),
-                                      obscureText: hidePassword,
-                                      enableSuggestions: false,
-                                      autocorrect: false,
-                                      decoration: standardInputDecoration(
-                                        "Enter current password",
-                                        passwordCurrentFocusNode,
-                                        context,
-                                      ).copyWith(
-                                        labelStyle:
-                                            STextStyles.fieldLabel(context),
-                                        suffixIcon: UnconstrainedBox(
-                                          child: Row(
-                                            children: [
-                                              const SizedBox(
-                                                width: 16,
-                                              ),
-                                              GestureDetector(
-                                                key: const Key(
-                                                    "desktopSecurityRestoreFromFilePasswordFieldShowPasswordButtonKey"),
-                                                onTap: () async {
-                                                  setState(() {
-                                                    hidePassword =
-                                                        !hidePassword;
-                                                  });
-                                                },
-                                                child: SvgPicture.asset(
-                                                  hidePassword
-                                                      ? Assets.svg.eye
-                                                      : Assets.svg.eyeSlash,
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .textDark3,
-                                                  width: 16,
-                                                  height: 16,
-                                                ),
-                                              ),
-                                              const SizedBox(
-                                                width: 12,
-                                              ),
-                                            ],
-                                          ),
-                                        ),
+                                    const SizedBox(height: 10),
+                                    ClipRRect(
+                                      borderRadius: BorderRadius.circular(
+                                        Constants.size.circularBorderRadius,
                                       ),
-                                      onChanged: (newValue) {},
-                                    ),
-                                  ),
-                                  const SizedBox(height: 16),
-                                  Text(
-                                    "New password",
-                                    style:
-                                        STextStyles.desktopTextExtraExtraSmall(
-                                                context)
-                                            .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark3),
-                                    textAlign: TextAlign.left,
-                                  ),
-                                  const SizedBox(height: 10),
-                                  ClipRRect(
-                                    borderRadius: BorderRadius.circular(
-                                      Constants.size.circularBorderRadius,
-                                    ),
-                                    child: TextField(
-                                      key: const Key(
-                                          "desktopSecurityCreateNewPasswordFieldKey1"),
-                                      focusNode: passwordFocusNode,
-                                      controller: passwordController,
-                                      style: STextStyles.field(context),
-                                      obscureText: hidePassword,
-                                      enableSuggestions: false,
-                                      autocorrect: false,
-                                      decoration: standardInputDecoration(
-                                        "Enter new password",
-                                        passwordFocusNode,
-                                        context,
-                                      ).copyWith(
-                                        labelStyle:
-                                            STextStyles.fieldLabel(context),
-                                        suffixIcon: UnconstrainedBox(
-                                          child: Row(
-                                            children: [
-                                              const SizedBox(
-                                                width: 16,
-                                              ),
-                                              GestureDetector(
-                                                key: const Key(
-                                                    "desktopSecurityCreateNewPasswordButtonKey1"),
-                                                onTap: () async {
-                                                  setState(() {
-                                                    hidePassword =
-                                                        !hidePassword;
-                                                  });
-                                                },
-                                                child: SvgPicture.asset(
-                                                  hidePassword
-                                                      ? Assets.svg.eye
-                                                      : Assets.svg.eyeSlash,
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .textDark3,
-                                                  width: 16,
-                                                  height: 16,
-                                                ),
-                                              ),
-                                              const SizedBox(
-                                                width: 12,
-                                              ),
-                                            ],
-                                          ),
-                                        ),
-                                      ),
-                                      onChanged: (newValue) {
-                                        if (newValue.isEmpty) {
-                                          setState(() {
-                                            passwordFeedback = "";
-                                          });
-                                          return;
-                                        }
-                                        final result =
-                                            zxcvbn.evaluate(newValue);
-                                        String suggestionsAndTips = "";
-                                        for (var sug in result
-                                            .feedback.suggestions!
-                                            .toSet()) {
-                                          suggestionsAndTips += "$sug\n";
-                                        }
-                                        suggestionsAndTips +=
-                                            result.feedback.warning!;
-                                        String feedback =
-                                            // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
-                                            suggestionsAndTips;
-
-                                        passwordStrength = result.score! / 4;
-
-                                        // hack fix to format back string returned from zxcvbn
-                                        if (feedback
-                                            .contains("phrasesNo need")) {
-                                          feedback = feedback.replaceFirst(
-                                              "phrasesNo need",
-                                              "phrases\nNo need");
-                                        }
-
-                                        if (feedback.endsWith("\n")) {
-                                          feedback = feedback.substring(
-                                              0, feedback.length - 2);
-                                        }
-
-                                        setState(() {
-                                          passwordFeedback = feedback;
-                                        });
-                                      },
-                                    ),
-                                  ),
-                                  if (passwordFocusNode.hasFocus ||
-                                      passwordRepeatFocusNode.hasFocus ||
-                                      passwordController.text.isNotEmpty)
-                                    Padding(
-                                      padding: EdgeInsets.only(
-                                        left: 12,
-                                        right: 12,
-                                        top:
-                                            passwordFeedback.isNotEmpty ? 4 : 0,
-                                      ),
-                                      child: passwordFeedback.isNotEmpty
-                                          ? Text(
-                                              passwordFeedback,
-                                              style: STextStyles.infoSmall(
-                                                  context),
-                                            )
-                                          : null,
-                                    ),
-                                  if (passwordFocusNode.hasFocus ||
-                                      passwordRepeatFocusNode.hasFocus ||
-                                      passwordController.text.isNotEmpty)
-                                    Padding(
-                                      padding: const EdgeInsets.only(
-                                        left: 12,
-                                        right: 12,
-                                        top: 10,
-                                      ),
-                                      child: ProgressBar(
+                                      child: TextField(
                                         key: const Key(
-                                            "desktopSecurityCreateStackBackUpProgressBar"),
-                                        width: 450,
-                                        height: 5,
-                                        fillColor: passwordStrength < 0.51
-                                            ? Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .accentColorRed
-                                            : passwordStrength < 1
-                                                ? Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .accentColorYellow
-                                                : Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .accentColorGreen,
-                                        backgroundColor: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .buttonBackSecondary,
-                                        percent: passwordStrength < 0.25
-                                            ? 0.03
-                                            : passwordStrength,
-                                      ),
-                                    ),
-                                  const SizedBox(height: 16),
-                                  Text(
-                                    "Confirm new password",
-                                    style:
-                                        STextStyles.desktopTextExtraExtraSmall(
-                                                context)
-                                            .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark3),
-                                    textAlign: TextAlign.left,
-                                  ),
-                                  const SizedBox(height: 10),
-                                  ClipRRect(
-                                    borderRadius: BorderRadius.circular(
-                                      Constants.size.circularBorderRadius,
-                                    ),
-                                    child: TextField(
-                                      key: const Key(
-                                          "desktopSecurityCreateNewPasswordFieldKey2"),
-                                      focusNode: passwordRepeatFocusNode,
-                                      controller: passwordRepeatController,
-                                      style: STextStyles.field(context),
-                                      obscureText: hidePassword,
-                                      enableSuggestions: false,
-                                      autocorrect: false,
-                                      decoration: standardInputDecoration(
-                                        "Confirm new password",
-                                        passwordRepeatFocusNode,
-                                        context,
-                                      ).copyWith(
-                                        labelStyle:
-                                            STextStyles.fieldLabel(context),
-                                        suffixIcon: UnconstrainedBox(
-                                          child: Row(
-                                            children: [
-                                              const SizedBox(
-                                                width: 16,
-                                              ),
-                                              GestureDetector(
-                                                key: const Key(
-                                                    "desktopSecurityCreateNewPasswordButtonKey2"),
-                                                onTap: () async {
-                                                  setState(() {
-                                                    hidePassword =
-                                                        !hidePassword;
-                                                  });
-                                                },
-                                                child: SvgPicture.asset(
-                                                  hidePassword
-                                                      ? Assets.svg.eye
-                                                      : Assets.svg.eyeSlash,
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .textDark3,
+                                            "desktopSecurityRestoreFromFilePasswordFieldKey"),
+                                        focusNode: passwordCurrentFocusNode,
+                                        controller: passwordCurrentController,
+                                        style: STextStyles.field(context),
+                                        obscureText: hidePassword,
+                                        enableSuggestions: false,
+                                        autocorrect: false,
+                                        decoration: standardInputDecoration(
+                                          "Enter current password",
+                                          passwordCurrentFocusNode,
+                                          context,
+                                        ).copyWith(
+                                          labelStyle:
+                                              STextStyles.fieldLabel(context),
+                                          suffixIcon: UnconstrainedBox(
+                                            child: Row(
+                                              children: [
+                                                const SizedBox(
                                                   width: 16,
-                                                  height: 16,
                                                 ),
-                                              ),
-                                              const SizedBox(
-                                                width: 12,
-                                              ),
-                                            ],
+                                                GestureDetector(
+                                                  key: const Key(
+                                                      "desktopSecurityRestoreFromFilePasswordFieldShowPasswordButtonKey"),
+                                                  onTap: () async {
+                                                    setState(() {
+                                                      hidePassword =
+                                                          !hidePassword;
+                                                    });
+                                                  },
+                                                  child: SvgPicture.asset(
+                                                    hidePassword
+                                                        ? Assets.svg.eye
+                                                        : Assets.svg.eyeSlash,
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark3,
+                                                    width: 16,
+                                                    height: 16,
+                                                  ),
+                                                ),
+                                                const SizedBox(
+                                                  width: 12,
+                                                ),
+                                              ],
+                                            ),
                                           ),
                                         ),
+                                        onChanged: (newValue) {
+                                          setState(() {});
+                                        },
                                       ),
-                                      onChanged: (newValue) {
-                                        setState(() {});
-                                      },
                                     ),
-                                  ),
-                                  const SizedBox(height: 20),
-                                  PrimaryButton(
-                                    width: 142,
-                                    desktopMed: true,
-                                    enabled: shouldEnableSave,
-                                    label: "Save changes",
-                                    onPressed: () {
-                                      setState(() {
-                                        changePassword = false;
-                                      });
-                                    },
-                                  )
-                                ],
+                                    const SizedBox(height: 16),
+                                    Text(
+                                      "New password",
+                                      style: STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark3),
+                                      textAlign: TextAlign.left,
+                                    ),
+                                    const SizedBox(height: 10),
+                                    ClipRRect(
+                                      borderRadius: BorderRadius.circular(
+                                        Constants.size.circularBorderRadius,
+                                      ),
+                                      child: TextField(
+                                        key: const Key(
+                                            "desktopSecurityCreateNewPasswordFieldKey1"),
+                                        focusNode: passwordFocusNode,
+                                        controller: passwordController,
+                                        style: STextStyles.field(context),
+                                        obscureText: hidePassword,
+                                        enableSuggestions: false,
+                                        autocorrect: false,
+                                        decoration: standardInputDecoration(
+                                          "Enter new password",
+                                          passwordFocusNode,
+                                          context,
+                                        ).copyWith(
+                                          labelStyle:
+                                              STextStyles.fieldLabel(context),
+                                          suffixIcon: UnconstrainedBox(
+                                            child: Row(
+                                              children: [
+                                                const SizedBox(
+                                                  width: 16,
+                                                ),
+                                                GestureDetector(
+                                                  key: const Key(
+                                                      "desktopSecurityCreateNewPasswordButtonKey1"),
+                                                  onTap: () async {
+                                                    setState(() {
+                                                      hidePassword =
+                                                          !hidePassword;
+                                                    });
+                                                  },
+                                                  child: SvgPicture.asset(
+                                                    hidePassword
+                                                        ? Assets.svg.eye
+                                                        : Assets.svg.eyeSlash,
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark3,
+                                                    width: 16,
+                                                    height: 16,
+                                                  ),
+                                                ),
+                                                const SizedBox(
+                                                  width: 12,
+                                                ),
+                                              ],
+                                            ),
+                                          ),
+                                        ),
+                                        onChanged: (newValue) {
+                                          if (newValue.isEmpty) {
+                                            setState(() {
+                                              passwordFeedback = "";
+                                            });
+                                            return;
+                                          }
+                                          final result =
+                                              zxcvbn.evaluate(newValue);
+                                          String suggestionsAndTips = "";
+                                          for (var sug in result
+                                              .feedback.suggestions!
+                                              .toSet()) {
+                                            suggestionsAndTips += "$sug\n";
+                                          }
+                                          suggestionsAndTips +=
+                                              result.feedback.warning!;
+                                          String feedback =
+                                              // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
+                                              suggestionsAndTips;
+
+                                          passwordStrength = result.score! / 4;
+
+                                          // hack fix to format back string returned from zxcvbn
+                                          if (feedback
+                                              .contains("phrasesNo need")) {
+                                            feedback = feedback.replaceFirst(
+                                                "phrasesNo need",
+                                                "phrases\nNo need");
+                                          }
+
+                                          if (feedback.endsWith("\n")) {
+                                            feedback = feedback.substring(
+                                                0, feedback.length - 2);
+                                          }
+
+                                          setState(() {
+                                            passwordFeedback = feedback;
+                                          });
+                                        },
+                                      ),
+                                    ),
+                                    if (passwordFocusNode.hasFocus ||
+                                        passwordRepeatFocusNode.hasFocus ||
+                                        passwordController.text.isNotEmpty)
+                                      Padding(
+                                        padding: EdgeInsets.only(
+                                          left: 12,
+                                          right: 12,
+                                          top: passwordFeedback.isNotEmpty
+                                              ? 4
+                                              : 0,
+                                        ),
+                                        child: passwordFeedback.isNotEmpty
+                                            ? Text(
+                                                passwordFeedback,
+                                                style: STextStyles.infoSmall(
+                                                    context),
+                                              )
+                                            : null,
+                                      ),
+                                    if (passwordFocusNode.hasFocus ||
+                                        passwordRepeatFocusNode.hasFocus ||
+                                        passwordController.text.isNotEmpty)
+                                      Padding(
+                                        padding: const EdgeInsets.only(
+                                          left: 12,
+                                          right: 12,
+                                          top: 10,
+                                        ),
+                                        child: ProgressBar(
+                                          key: const Key(
+                                              "desktopSecurityCreateStackBackUpProgressBar"),
+                                          width: 450,
+                                          height: 5,
+                                          fillColor: passwordStrength < 0.51
+                                              ? Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorRed
+                                              : passwordStrength < 1
+                                                  ? Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .accentColorYellow
+                                                  : Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .accentColorGreen,
+                                          backgroundColor: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .buttonBackSecondary,
+                                          percent: passwordStrength < 0.25
+                                              ? 0.03
+                                              : passwordStrength,
+                                        ),
+                                      ),
+                                    const SizedBox(height: 16),
+                                    Text(
+                                      "Confirm new password",
+                                      style: STextStyles
+                                              .desktopTextExtraExtraSmall(
+                                                  context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark3),
+                                      textAlign: TextAlign.left,
+                                    ),
+                                    const SizedBox(height: 10),
+                                    ClipRRect(
+                                      borderRadius: BorderRadius.circular(
+                                        Constants.size.circularBorderRadius,
+                                      ),
+                                      child: TextField(
+                                        key: const Key(
+                                            "desktopSecurityCreateNewPasswordFieldKey2"),
+                                        focusNode: passwordRepeatFocusNode,
+                                        controller: passwordRepeatController,
+                                        style: STextStyles.field(context),
+                                        obscureText: hidePassword,
+                                        enableSuggestions: false,
+                                        autocorrect: false,
+                                        decoration: standardInputDecoration(
+                                          "Confirm new password",
+                                          passwordRepeatFocusNode,
+                                          context,
+                                        ).copyWith(
+                                          labelStyle:
+                                              STextStyles.fieldLabel(context),
+                                          suffixIcon: UnconstrainedBox(
+                                            child: Row(
+                                              children: [
+                                                const SizedBox(
+                                                  width: 16,
+                                                ),
+                                                GestureDetector(
+                                                  key: const Key(
+                                                      "desktopSecurityCreateNewPasswordButtonKey2"),
+                                                  onTap: () async {
+                                                    setState(() {
+                                                      hidePassword =
+                                                          !hidePassword;
+                                                    });
+                                                  },
+                                                  child: SvgPicture.asset(
+                                                    hidePassword
+                                                        ? Assets.svg.eye
+                                                        : Assets.svg.eyeSlash,
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark3,
+                                                    width: 16,
+                                                    height: 16,
+                                                  ),
+                                                ),
+                                                const SizedBox(
+                                                  width: 12,
+                                                ),
+                                              ],
+                                            ),
+                                          ),
+                                        ),
+                                        onChanged: (newValue) {
+                                          setState(() {});
+                                        },
+                                      ),
+                                    ),
+                                    const SizedBox(height: 20),
+                                    PrimaryButton(
+                                      width: 160,
+                                      desktopMed: true,
+                                      enabled: shouldEnableSave,
+                                      label: "Save changes",
+                                      onPressed: () async {
+                                        final didChangePW =
+                                            await attemptChangePW();
+                                        if (didChangePW) {
+                                          setState(() {
+                                            changePassword = false;
+                                          });
+                                        }
+                                      },
+                                    )
+                                  ],
+                                ),
+                              )
+                            : PrimaryButton(
+                                width: 210,
+                                desktopMed: true,
+                                enabled: true,
+                                label: "Set up new password",
+                                onPressed: () {
+                                  setState(() {
+                                    changePassword = true;
+                                  });
+                                },
                               ),
-                            )
-                          : PrimaryButton(
-                              width: 192,
-                              desktopMed: true,
-                              enabled: true,
-                              label: "Set up new password",
-                              onPressed: () {
-                                setState(() {
-                                  changePassword = true;
-                                });
-                              },
-                            ),
+                      ],
                     ),
                   ],
                 ),
-              ],
+              ),
             ),
-          ),
+            const SizedBox(
+              width: 40,
+            ),
+          ],
         ),
       ],
     );
   }
 }
-
-class NewPasswordButton extends ConsumerWidget {
-  const NewPasswordButton({
-    Key? key,
-  }) : super(key: key);
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
-        child: Text(
-          "Set up new password",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
diff --git a/lib/utilities/desktop_password_service.dart b/lib/utilities/desktop_password_service.dart
index f20525873..9ef83932b 100644
--- a/lib/utilities/desktop_password_service.dart
+++ b/lib/utilities/desktop_password_service.dart
@@ -115,6 +115,48 @@ class DPS {
     }
   }
 
+  Future<bool> changePassphrase(
+    String passphraseOld,
+    String passphraseNew,
+  ) async {
+    final box = await Hive.openBox<String>(DB.boxNameDesktopData);
+    final keyBlob = DB.instance.get<String>(
+      boxName: DB.boxNameDesktopData,
+      key: _kKeyBlobKey,
+    );
+    await box.close();
+
+    if (keyBlob == null) {
+      // no passphrase key blob found so any passphrase is technically bad
+      return false;
+    }
+
+    if (!(await verifyPassphrase(passphraseOld))) {
+      return false;
+    }
+
+    try {
+      await _handler!.resetPassphrase(passphraseNew);
+
+      final box = await Hive.openBox<String>(DB.boxNameDesktopData);
+      await DB.instance.put<String>(
+        boxName: DB.boxNameDesktopData,
+        key: _kKeyBlobKey,
+        value: await _handler!.getKeyBlob(),
+      );
+      await box.close();
+
+      // successfully updated passphrase
+      return true;
+    } catch (e, s) {
+      Logging.instance.log(
+        "${_getMessageFromException(e)}\n$s",
+        level: LogLevel.Warning,
+      );
+      return false;
+    }
+  }
+
   Future<bool> hasPassword() async {
     final keyBlob = DB.instance.get<String>(
       boxName: DB.boxNameDesktopData,

From 9df0569bb16fb17583f97c83227d7b83b5cd0068 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 14 Nov 2022 13:35:14 -0600
Subject: [PATCH 245/426] add passphrase check before displaying wallet seed

---
 .../unlock_wallet_keys_desktop.dart           | 59 ++++++++++---------
 1 file changed, 30 insertions(+), 29 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
index e65820737..23360c98c 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
@@ -1,10 +1,15 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
+import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -196,36 +201,32 @@ class _UnlockWalletKeysDesktopState
                     enabled: continueEnabled,
                     onPressed: continueEnabled
                         ? () async {
-                            // todo: check password
-                            // Navigator.of(context).pop();
-                            final words = await ref
-                                .read(walletsChangeNotifierProvider)
-                                .getManager(widget.walletId)
-                                .mnemonic;
+                            final verified = await ref
+                                .read(storageCryptoHandlerProvider)
+                                .verifyPassphrase(passwordController.text);
 
-                            await Navigator.of(context).pushReplacementNamed(
-                              WalletKeysDesktopPopup.routeName,
-                              arguments: words,
-                            );
-                            //
-                            // await showDialog<void>(
-                            //   context: context,
-                            //   barrierDismissible: false,
-                            //   builder: (context) => Navigator(
-                            //     initialRoute: WalletKeysDesktopPopup.routeName,
-                            //     onGenerateRoute: RouteGenerator.generateRoute,
-                            //     onGenerateInitialRoutes: (_, __) {
-                            //       return [
-                            //         RouteGenerator.generateRoute(
-                            //           RouteSettings(
-                            //             name: WalletKeysDesktopPopup.routeName,
-                            //             arguments: words,
-                            //           ),
-                            //         )
-                            //       ];
-                            //     },
-                            //   ),
-                            // );
+                            if (verified) {
+                              final words = await ref
+                                  .read(walletsChangeNotifierProvider)
+                                  .getManager(widget.walletId)
+                                  .mnemonic;
+
+                              if (mounted) {
+                                await Navigator.of(context)
+                                    .pushReplacementNamed(
+                                  WalletKeysDesktopPopup.routeName,
+                                  arguments: words,
+                                );
+                              }
+                            } else {
+                              unawaited(
+                                showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  message: "Invalid passphrase!",
+                                  context: context,
+                                ),
+                              );
+                            }
                           }
                         : null,
                   ),

From 9417d78c8170b64a27acf23d24347f2822eff138 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 14 Nov 2022 13:29:43 -0700
Subject: [PATCH 246/426] wip: new contact emoji selection and crypto selection

---
 .../subviews/add_address_book_entry_view.dart | 858 ++++++++++--------
 1 file changed, 501 insertions(+), 357 deletions(-)

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 74f3dfde8..588ca5b26 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
@@ -15,15 +15,17 @@ import 'package:stackwallet/utilities/clipboard_interface.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/conditional_parent.dart';
 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/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/emoji_select_sheet.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';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class AddAddressBookEntryView extends ConsumerStatefulWidget {
   const AddAddressBookEntryView({
     Key? key,
@@ -108,395 +110,537 @@ class _AddAddressBookEntryViewState
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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(
-          "New contact",
-          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("addAddressBookEntryFavoriteButtonKey"),
-                size: 36,
-                shadows: const [],
-                color: Theme.of(context).extension<StackColors>()!.background,
-                icon: SvgPicture.asset(
-                  Assets.svg.star,
-                  color: _isFavorite
-                      ? Theme.of(context)
-                          .extension<StackColors>()!
-                          .favoriteStarActive
-                      : Theme.of(context)
-                          .extension<StackColors>()!
-                          .favoriteStarInactive,
-                  width: 20,
-                  height: 20,
-                ),
-                onPressed: () {
-                  setState(() {
-                    _isFavorite = !_isFavorite;
-                  });
+    final isDesktop = Util.isDesktop;
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              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();
+                  }
                 },
               ),
-            ),
-          ),
-        ],
-      ),
-      body: LayoutBuilder(
-        builder: (context, constraint) {
-          return Padding(
-            padding: const EdgeInsets.symmetric(horizontal: 12),
-            child: SingleChildScrollView(
-              controller: scrollController,
-              padding: const EdgeInsets.only(
-                // top: 8,
-                left: 4,
-                right: 4,
-                bottom: 16,
+              title: Text(
+                "New contact",
+                style: STextStyles.navBarTitle(context),
               ),
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  // subtract top and bottom padding set in parent
-                  minHeight: constraint.maxHeight - 16, // - 8,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    children: [
-                      const SizedBox(
-                        height: 4,
+              actions: [
+                Padding(
+                  padding: const EdgeInsets.only(
+                    top: 10,
+                    bottom: 10,
+                    right: 10,
+                  ),
+                  child: AspectRatio(
+                    aspectRatio: 1,
+                    child: AppBarIconButton(
+                      key: const Key("addAddressBookEntryFavoriteButtonKey"),
+                      size: 36,
+                      shadows: const [],
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .background,
+                      icon: SvgPicture.asset(
+                        Assets.svg.star,
+                        color: _isFavorite
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .favoriteStarActive
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .favoriteStarInactive,
+                        width: 20,
+                        height: 20,
                       ),
-                      GestureDetector(
-                        onTap: () {
-                          if (_selectedEmoji != null) {
+                      onPressed: () {
+                        setState(() {
+                          _isFavorite = !_isFavorite;
+                        });
+                      },
+                    ),
+                  ),
+                ),
+              ],
+            ),
+            body: child);
+      },
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) {
+          return Column(
+            children: [
+              Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Padding(
+                    padding: const EdgeInsets.all(32),
+                    child: Row(
+                      children: [
+                        Text(
+                          "New contact",
+                          style: STextStyles.desktopH3(context),
+                          textAlign: TextAlign.center,
+                        ),
+                        const SizedBox(width: 10),
+                        AppBarIconButton(
+                          key:
+                              const Key("addAddressBookEntryFavoriteButtonKey"),
+                          size: 36,
+                          shadows: const [],
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                          icon: SvgPicture.asset(
+                            Assets.svg.star,
+                            color: _isFavorite
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .favoriteStarActive
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .favoriteStarInactive,
+                            width: 20,
+                            height: 20,
+                          ),
+                          onPressed: () {
                             setState(() {
-                              _selectedEmoji = null;
+                              _isFavorite = !_isFavorite;
                             });
-                            return;
-                          }
-                          showModalBottomSheet<dynamic>(
-                            backgroundColor: Colors.transparent,
-                            context: context,
-                            shape: const RoundedRectangleBorder(
-                              borderRadius: BorderRadius.vertical(
-                                top: Radius.circular(20),
-                              ),
-                            ),
-                            builder: (_) => const EmojiSelectSheet(),
-                          ).then((value) {
-                            if (value is Emoji) {
+                          },
+                        ),
+                      ],
+                    ),
+                  ),
+                  const DesktopDialogCloseButton(),
+                ],
+              ),
+              Expanded(child: child),
+            ],
+          );
+        },
+        child: LayoutBuilder(
+          builder: (context, constraint) {
+            return Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 12),
+              child: SingleChildScrollView(
+                controller: scrollController,
+                padding: const EdgeInsets.only(
+                  // top: 8,
+                  left: 4,
+                  right: 4,
+                  bottom: 16,
+                ),
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    // subtract top and bottom padding set in parent
+                    minHeight: constraint.maxHeight - 16, // - 8,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Column(
+                      children: [
+                        const SizedBox(
+                          height: 4,
+                        ),
+                        GestureDetector(
+                          onTap: () {
+                            if (_selectedEmoji != null) {
                               setState(() {
-                                _selectedEmoji = value;
+                                _selectedEmoji = null;
                               });
+                              return;
                             }
-                          });
-                        },
-                        child: SizedBox(
-                          height: 48,
-                          width: 48,
-                          child: Stack(
-                            children: [
-                              Container(
-                                height: 48,
-                                width: 48,
-                                decoration: BoxDecoration(
-                                  borderRadius: BorderRadius.circular(24),
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textFieldActiveBG,
-                                ),
-                                child: Center(
-                                  child: _selectedEmoji == null
-                                      ? SvgPicture.asset(
-                                          Assets.svg.user,
-                                          height: 24,
-                                          width: 24,
-                                        )
-                                      : Text(
-                                          _selectedEmoji!.char,
-                                          style:
-                                              STextStyles.pageTitleH1(context),
+
+                            ///TODO if desktop make dialog
+                            !isDesktop
+                                ? showModalBottomSheet<dynamic>(
+                                    backgroundColor: Colors.transparent,
+                                    context: context,
+                                    shape: const RoundedRectangleBorder(
+                                      borderRadius: BorderRadius.vertical(
+                                        top: Radius.circular(20),
+                                      ),
+                                    ),
+                                    builder: (_) => const EmojiSelectSheet(),
+                                  ).then((value) {
+                                    if (value is Emoji) {
+                                      setState(() {
+                                        _selectedEmoji = value;
+                                      });
+                                    }
+                                  })
+                                : showDialog<dynamic>(
+                                    context: context,
+                                    builder: (context) {
+                                      return DesktopDialog(
+                                        maxHeight: 700,
+                                        maxWidth: 700,
+                                        child: Column(
+                                          children: [
+                                            Row(
+                                              children: [
+                                                Padding(
+                                                  padding:
+                                                      const EdgeInsets.all(32),
+                                                  child: Text(
+                                                    "Select emoji",
+                                                    style:
+                                                        STextStyles.desktopH3(
+                                                            context),
+                                                    textAlign: TextAlign.center,
+                                                  ),
+                                                ),
+                                              ],
+                                            ),
+                                            Expanded(
+                                              child: LayoutBuilder(
+                                                builder:
+                                                    (context, constraints) {
+                                                  return SingleChildScrollView(
+                                                    scrollDirection:
+                                                        Axis.vertical,
+                                                    child: ConstrainedBox(
+                                                      constraints:
+                                                          BoxConstraints(
+                                                        minHeight: constraints
+                                                            .maxHeight,
+                                                        minWidth: constraints
+                                                            .maxWidth,
+                                                      ),
+                                                      child: IntrinsicHeight(
+                                                        child: Column(
+                                                          children: const [
+                                                            Padding(
+                                                              padding: EdgeInsets
+                                                                  .symmetric(
+                                                                      horizontal:
+                                                                          32),
+                                                              // child:
+                                                              //     EmojiSelectSheet(),
+                                                            ),
+                                                          ],
+                                                        ),
+                                                      ),
+                                                    ),
+                                                  );
+                                                },
+                                              ),
+                                            ),
+                                          ],
                                         ),
-                                ),
-                              ),
-                              Align(
-                                alignment: Alignment.bottomRight,
-                                child: Container(
-                                  height: 14,
-                                  width: 14,
+                                      );
+                                    }).then((value) {
+                                    if (value is Emoji) {
+                                      setState(() {
+                                        _selectedEmoji = value;
+                                      });
+                                    }
+                                  });
+                          },
+                          child: SizedBox(
+                            height: 48,
+                            width: 48,
+                            child: Stack(
+                              children: [
+                                Container(
+                                  height: 48,
+                                  width: 48,
                                   decoration: BoxDecoration(
-                                      borderRadius: BorderRadius.circular(14),
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .accentColorDark),
+                                    borderRadius: BorderRadius.circular(24),
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textFieldActiveBG,
+                                  ),
                                   child: Center(
                                     child: _selectedEmoji == null
                                         ? SvgPicture.asset(
-                                            Assets.svg.plus,
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textWhite,
-                                            width: 12,
-                                            height: 12,
+                                            Assets.svg.user,
+                                            height: 24,
+                                            width: 24,
                                           )
-                                        : SvgPicture.asset(
-                                            Assets.svg.thickX,
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textWhite,
-                                            width: 8,
-                                            height: 8,
+                                        : Text(
+                                            _selectedEmoji!.char,
+                                            style: STextStyles.pageTitleH1(
+                                                context),
                                           ),
                                   ),
                                 ),
-                              )
-                            ],
-                          ),
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 8,
-                      ),
-                      ClipRRect(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
-                        ),
-                        child: TextField(
-                          autocorrect: Util.isDesktop ? false : true,
-                          enableSuggestions: Util.isDesktop ? false : true,
-                          controller: nameController,
-                          focusNode: nameFocusNode,
-                          style: STextStyles.field(context),
-                          decoration: standardInputDecoration(
-                            "Enter contact name",
-                            nameFocusNode,
-                            context,
-                          ).copyWith(
-                            suffixIcon: ref
-                                    .read(contactNameIsNotEmptyStateProvider
-                                        .state)
-                                    .state
-                                ? Padding(
-                                    padding: const EdgeInsets.only(right: 0),
-                                    child: UnconstrainedBox(
-                                      child: Row(
-                                        children: [
-                                          TextFieldIconButton(
-                                            child: const XIcon(),
-                                            onTap: () async {
-                                              setState(() {
-                                                nameController.text = "";
-                                              });
-                                            },
-                                          ),
-                                        ],
-                                      ),
+                                Align(
+                                  alignment: Alignment.bottomRight,
+                                  child: Container(
+                                    height: 14,
+                                    width: 14,
+                                    decoration: BoxDecoration(
+                                        borderRadius: BorderRadius.circular(14),
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .accentColorDark),
+                                    child: Center(
+                                      child: _selectedEmoji == null
+                                          ? SvgPicture.asset(
+                                              Assets.svg.plus,
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textWhite,
+                                              width: 12,
+                                              height: 12,
+                                            )
+                                          : SvgPicture.asset(
+                                              Assets.svg.thickX,
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textWhite,
+                                              width: 8,
+                                              height: 8,
+                                            ),
                                     ),
-                                  )
-                                : null,
+                                  ),
+                                )
+                              ],
+                            ),
                           ),
-                          onChanged: (newValue) {
-                            ref
-                                .read(contactNameIsNotEmptyStateProvider.state)
-                                .state = newValue.isNotEmpty;
-                          },
                         ),
-                      ),
-                      if (forms.length <= 1)
                         const SizedBox(
                           height: 8,
                         ),
-                      if (forms.length <= 1) forms[0],
-                      if (forms.length > 1)
-                        for (int i = 0; i < forms.length; i++)
-                          Column(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              const SizedBox(
-                                height: 12,
-                              ),
-                              Row(
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
-                                children: [
-                                  Text(
-                                    "Address ${i + 1}",
-                                    style: STextStyles.smallMed12(context),
-                                  ),
-                                  BlueTextButton(
-                                    onTap: () {
-                                      _removeForm(forms[i].id);
-                                    },
-                                    text: "Remove",
-                                  ),
-                                ],
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              forms[i],
-                            ],
+                        ClipRRect(
+                          borderRadius: BorderRadius.circular(
+                            Constants.size.circularBorderRadius,
                           ),
-                      const SizedBox(
-                        height: 16,
-                      ),
-                      BlueTextButton(
-                        onTap: () {
-                          _addForm();
-                          scrollController.animateTo(
-                            scrollController.position.maxScrollExtent + 500,
-                            duration: const Duration(milliseconds: 500),
-                            curve: Curves.easeInOut,
-                          );
-                        },
-                        text: "+ Add another address",
-                      ),
-                      // GestureDetector(
-                      //
-                      //   child: Text(
-                      //     "+ Add another address",
-                      //     style: STextStyles.largeMedium14(context),
-                      //   ),
-                      // ),
-                      const SizedBox(
-                        height: 16,
-                      ),
-                      const Spacer(),
-                      Row(
-                        children: [
-                          Expanded(
-                            child: TextButton(
-                              style: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .getSecondaryEnabledButtonColor(context),
-                              child: Text(
-                                "Cancel",
-                                style: STextStyles.button(context).copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .accentColorDark),
-                              ),
-                              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();
-                                }
-                              },
+                          child: TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
+                            controller: nameController,
+                            focusNode: nameFocusNode,
+                            style: STextStyles.field(context),
+                            decoration: standardInputDecoration(
+                              "Enter contact name",
+                              nameFocusNode,
+                              context,
+                            ).copyWith(
+                              suffixIcon: ref
+                                      .read(contactNameIsNotEmptyStateProvider
+                                          .state)
+                                      .state
+                                  ? Padding(
+                                      padding: const EdgeInsets.only(right: 0),
+                                      child: UnconstrainedBox(
+                                        child: Row(
+                                          children: [
+                                            TextFieldIconButton(
+                                              child: const XIcon(),
+                                              onTap: () async {
+                                                setState(() {
+                                                  nameController.text = "";
+                                                });
+                                              },
+                                            ),
+                                          ],
+                                        ),
+                                      ),
+                                    )
+                                  : null,
                             ),
+                            onChanged: (newValue) {
+                              ref
+                                  .read(
+                                      contactNameIsNotEmptyStateProvider.state)
+                                  .state = newValue.isNotEmpty;
+                            },
                           ),
+                        ),
+                        if (forms.length <= 1)
                           const SizedBox(
-                            width: 16,
+                            height: 8,
                           ),
-                          Expanded(
-                            child: Builder(
-                              builder: (context) {
-                                bool nameExists = ref
-                                    .watch(contactNameIsNotEmptyStateProvider
-                                        .state)
-                                    .state;
-
-                                bool validForms = ref.watch(
-                                    validContactStateProvider(forms
-                                        .map((e) => e.id)
-                                        .toList(growable: false)));
-
-                                bool shouldEnableSave =
-                                    validForms && nameExists;
-
-                                return TextButton(
-                                  style: shouldEnableSave
-                                      ? Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .getPrimaryEnabledButtonColor(context)
-                                      : Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .getPrimaryDisabledButtonColor(
-                                              context),
-                                  onPressed: shouldEnableSave
-                                      ? () async {
-                                          if (FocusScope.of(context).hasFocus) {
-                                            FocusScope.of(context).unfocus();
-                                            await Future<void>.delayed(
-                                              const Duration(milliseconds: 75),
-                                            );
-                                          }
-                                          List<ContactAddressEntry> entries =
-                                              [];
-                                          for (int i = 0;
-                                              i < forms.length;
-                                              i++) {
-                                            entries.add(ref
-                                                .read(addressEntryDataProvider(
-                                                    forms[i].id))
-                                                .buildAddressEntry());
-                                          }
-                                          Contact contact = Contact(
-                                            emojiChar: _selectedEmoji?.char,
-                                            name: nameController.text,
-                                            addresses: entries,
-                                            isFavorite: _isFavorite,
-                                          );
-
-                                          if (await ref
-                                              .read(addressBookServiceProvider)
-                                              .addContact(contact)) {
-                                            if (mounted) {
-                                              Navigator.of(context).pop();
-                                            }
-                                            // TODO show success notification
-                                          } else {
-                                            // TODO show error notification
-                                          }
-                                        }
-                                      : null,
-                                  child: Text(
-                                    "Save",
-                                    style: STextStyles.button(context).copyWith(
-                                      color: shouldEnableSave
-                                          ? Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .buttonTextPrimary
-                                          : Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .buttonTextPrimaryDisabled,
+                        if (forms.length <= 1) forms[0],
+                        if (forms.length > 1)
+                          for (int i = 0; i < forms.length; i++)
+                            Column(
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                const SizedBox(
+                                  height: 12,
+                                ),
+                                Row(
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  children: [
+                                    Text(
+                                      "Address ${i + 1}",
+                                      style: STextStyles.smallMed12(context),
                                     ),
-                                  ),
-                                );
-                              },
+                                    BlueTextButton(
+                                      onTap: () {
+                                        _removeForm(forms[i].id);
+                                      },
+                                      text: "Remove",
+                                    ),
+                                  ],
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                forms[i],
+                              ],
                             ),
-                          ),
-                        ],
-                      ),
-                    ],
+                        const SizedBox(
+                          height: 16,
+                        ),
+                        BlueTextButton(
+                          onTap: () {
+                            _addForm();
+                            scrollController.animateTo(
+                              scrollController.position.maxScrollExtent + 500,
+                              duration: const Duration(milliseconds: 500),
+                              curve: Curves.easeInOut,
+                            );
+                          },
+                          text: "+ Add another address",
+                        ),
+                        // GestureDetector(
+                        //
+                        //   child: Text(
+                        //     "+ Add another address",
+                        //     style: STextStyles.largeMedium14(context),
+                        //   ),
+                        // ),
+                        const SizedBox(
+                          height: 16,
+                        ),
+                        const Spacer(),
+                        Row(
+                          children: [
+                            Expanded(
+                              child: TextButton(
+                                style: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .getSecondaryEnabledButtonColor(context),
+                                child: Text(
+                                  "Cancel",
+                                  style: STextStyles.button(context).copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .accentColorDark),
+                                ),
+                                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();
+                                  }
+                                },
+                              ),
+                            ),
+                            const SizedBox(
+                              width: 16,
+                            ),
+                            Expanded(
+                              child: Builder(
+                                builder: (context) {
+                                  bool nameExists = ref
+                                      .watch(contactNameIsNotEmptyStateProvider
+                                          .state)
+                                      .state;
+
+                                  bool validForms = ref.watch(
+                                      validContactStateProvider(forms
+                                          .map((e) => e.id)
+                                          .toList(growable: false)));
+
+                                  bool shouldEnableSave =
+                                      validForms && nameExists;
+
+                                  return TextButton(
+                                    style: shouldEnableSave
+                                        ? Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .getPrimaryEnabledButtonColor(
+                                                context)
+                                        : Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .getPrimaryDisabledButtonColor(
+                                                context),
+                                    onPressed: shouldEnableSave
+                                        ? () async {
+                                            if (FocusScope.of(context)
+                                                .hasFocus) {
+                                              FocusScope.of(context).unfocus();
+                                              await Future<void>.delayed(
+                                                const Duration(
+                                                    milliseconds: 75),
+                                              );
+                                            }
+                                            List<ContactAddressEntry> entries =
+                                                [];
+                                            for (int i = 0;
+                                                i < forms.length;
+                                                i++) {
+                                              entries.add(ref
+                                                  .read(
+                                                      addressEntryDataProvider(
+                                                          forms[i].id))
+                                                  .buildAddressEntry());
+                                            }
+                                            Contact contact = Contact(
+                                              emojiChar: _selectedEmoji?.char,
+                                              name: nameController.text,
+                                              addresses: entries,
+                                              isFavorite: _isFavorite,
+                                            );
+
+                                            if (await ref
+                                                .read(
+                                                    addressBookServiceProvider)
+                                                .addContact(contact)) {
+                                              if (mounted) {
+                                                Navigator.of(context).pop();
+                                              }
+                                              // TODO show success notification
+                                            } else {
+                                              // TODO show error notification
+                                            }
+                                          }
+                                        : null,
+                                    child: Text(
+                                      "Save",
+                                      style:
+                                          STextStyles.button(context).copyWith(
+                                        color: shouldEnableSave
+                                            ? Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .buttonTextPrimary
+                                            : Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .buttonTextPrimaryDisabled,
+                                      ),
+                                    ),
+                                  );
+                                },
+                              ),
+                            ),
+                          ],
+                        ),
+                      ],
+                    ),
                   ),
                 ),
               ),
-            ),
-          );
-        },
+            );
+          },
+        ),
       ),
     );
   }

From e0555f53a437d37e8c5c951de2c9c7f90448b7eb Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 14 Nov 2022 16:00:09 -0700
Subject: [PATCH 247/426] WIP: desktop address book displays contacts

---
 .../address_book_views/address_book_view.dart | 553 +++++++++---------
 .../desktop_address_book.dart                 |  31 +-
 2 files changed, 288 insertions(+), 296 deletions(-)

diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index c9dd72d72..08c548627 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -13,7 +13,9 @@ 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';
+import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/address_book_card.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
@@ -21,8 +23,6 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class AddressBookView extends ConsumerStatefulWidget {
   const AddressBookView({Key? key, this.coin}) : super(key: key);
 
@@ -103,288 +103,287 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
     final addressBookEntriesFuture = ref.watch(
         addressBookServiceProvider.select((value) => value.addressBookEntries));
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Address book",
-          style: STextStyles.navBarTitle(context),
-        ),
-        actions: [
-          Padding(
-            padding: const EdgeInsets.only(
-              top: 10,
-              bottom: 10,
-              right: 10,
+    final isDesktop = Util.isDesktop;
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
             ),
-            child: AspectRatio(
-              aspectRatio: 1,
-              child: AppBarIconButton(
-                key: const Key("addressBookFilterViewButton"),
-                size: 36,
-                shadows: const [],
-                color: Theme.of(context).extension<StackColors>()!.background,
-                icon: SvgPicture.asset(
-                  Assets.svg.filter,
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .accentColorDark,
-                  width: 20,
-                  height: 20,
+            title: Text(
+              "Address book",
+              style: STextStyles.navBarTitle(context),
+            ),
+            actions: [
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
                 ),
-                onPressed: () {
-                  Navigator.of(context).pushNamed(
-                    AddressBookFilterView.routeName,
-                  );
-                },
-              ),
-            ),
-          ),
-          Padding(
-            padding: const EdgeInsets.only(
-              top: 10,
-              bottom: 10,
-              right: 10,
-            ),
-            child: AspectRatio(
-              aspectRatio: 1,
-              child: AppBarIconButton(
-                key: const Key("addressBookAddNewContactViewButton"),
-                size: 36,
-                shadows: const [],
-                color: Theme.of(context).extension<StackColors>()!.background,
-                icon: SvgPicture.asset(
-                  Assets.svg.plus,
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .accentColorDark,
-                  width: 20,
-                  height: 20,
-                ),
-                onPressed: () {
-                  Navigator.of(context).pushNamed(
-                    AddAddressBookEntryView.routeName,
-                  );
-                },
-              ),
-            ),
-          ),
-        ],
-      ),
-      body: LayoutBuilder(
-        builder: (builderContext, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            controller: _searchController,
-                            focusNode: _searchFocusNode,
-                            onChanged: (value) {
-                              setState(() {
-                                _searchTerm = value;
-                              });
-                            },
-                            style: STextStyles.field(context),
-                            decoration: standardInputDecoration(
-                              "Search",
-                              _searchFocusNode,
-                              context,
-                            ).copyWith(
-                              prefixIcon: Padding(
-                                padding: const EdgeInsets.symmetric(
-                                  horizontal: 10,
-                                  vertical: 16,
-                                ),
-                                child: SvgPicture.asset(
-                                  Assets.svg.search,
-                                  width: 16,
-                                  height: 16,
-                                ),
-                              ),
-                              suffixIcon: _searchController.text.isNotEmpty
-                                  ? Padding(
-                                      padding: const EdgeInsets.only(right: 0),
-                                      child: UnconstrainedBox(
-                                        child: Row(
-                                          children: [
-                                            TextFieldIconButton(
-                                              child: const XIcon(),
-                                              onTap: () async {
-                                                setState(() {
-                                                  _searchController.text = "";
-                                                });
-                                              },
-                                            ),
-                                          ],
-                                        ),
-                                      ),
-                                    )
-                                  : null,
-                            ),
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        Text(
-                          "Favorites",
-                          style: STextStyles.smallMed12(context),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        FutureBuilder(
-                          future: addressBookEntriesFuture,
-                          builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
-                            if (snapshot.connectionState ==
-                                    ConnectionState.done &&
-                                snapshot.hasData) {
-                              _cacheFav = snapshot.data!;
-                            }
-                            if (_cacheFav == null) {
-                              // TODO proper loading animation
-                              return const LoadingIndicator();
-                            } else {
-                              if (_cacheFav!.isNotEmpty) {
-                                return RoundedWhiteContainer(
-                                  padding: const EdgeInsets.all(0),
-                                  child: Column(
-                                    children: [
-                                      ..._cacheFav!
-                                          .where((element) => element.addresses
-                                              .where((e) => ref.watch(
-                                                  addressBookFilterProvider
-                                                      .select((value) => value
-                                                          .coins
-                                                          .contains(e.coin))))
-                                              .isNotEmpty)
-                                          .where((e) =>
-                                              e.isFavorite &&
-                                              ref
-                                                  .read(
-                                                      addressBookServiceProvider)
-                                                  .matches(_searchTerm, e))
-                                          .where(
-                                              (element) => element.isFavorite)
-                                          .map(
-                                            (e) => AddressBookCard(
-                                              key: Key(
-                                                  "favContactCard_${e.id}_key"),
-                                              contactId: e.id,
-                                            ),
-                                          ),
-                                    ],
-                                  ),
-                                );
-                              } else {
-                                return RoundedWhiteContainer(
-                                  child: Center(
-                                    child: Text(
-                                      "Your favorite contacts will appear here",
-                                      style: STextStyles.itemSubtitle(context),
-                                    ),
-                                  ),
-                                );
-                              }
-                            }
-                          },
-                        ),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        Text(
-                          "All contacts",
-                          style: STextStyles.smallMed12(context),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        FutureBuilder(
-                          future: addressBookEntriesFuture,
-                          builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
-                            if (snapshot.connectionState ==
-                                    ConnectionState.done &&
-                                snapshot.hasData) {
-                              _cache = snapshot.data!;
-                            }
-                            if (_cache == null) {
-                              // TODO proper loading animation
-                              return const LoadingIndicator();
-                            } else {
-                              if (_cache!.isNotEmpty) {
-                                return RoundedWhiteContainer(
-                                  padding: const EdgeInsets.all(0),
-                                  child: Column(
-                                    children: [
-                                      ..._cache!
-                                          .where((element) => element.addresses
-                                              .where((e) => ref.watch(
-                                                  addressBookFilterProvider
-                                                      .select((value) => value
-                                                          .coins
-                                                          .contains(e.coin))))
-                                              .isNotEmpty)
-                                          .where((e) => ref
-                                              .read(addressBookServiceProvider)
-                                              .matches(_searchTerm, e))
-                                          .where(
-                                              (element) => !element.isFavorite)
-                                          .map(
-                                            (e) => AddressBookCard(
-                                              key: Key(
-                                                  "contactCard_${e.id}_key"),
-                                              contactId: e.id,
-                                            ),
-                                          ),
-                                    ],
-                                  ),
-                                );
-                              } else {
-                                return RoundedWhiteContainer(
-                                  child: Center(
-                                    child: Text(
-                                      "Your contacts will appear here",
-                                      style: STextStyles.itemSubtitle(context),
-                                    ),
-                                  ),
-                                );
-                              }
-                            }
-                          },
-                        ),
-                      ],
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("addressBookFilterViewButton"),
+                    size: 36,
+                    shadows: const [],
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    icon: SvgPicture.asset(
+                      Assets.svg.filter,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                      width: 20,
+                      height: 20,
                     ),
+                    onPressed: () {
+                      Navigator.of(context).pushNamed(
+                        AddressBookFilterView.routeName,
+                      );
+                    },
                   ),
                 ),
               ),
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
+                ),
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("addressBookAddNewContactViewButton"),
+                    size: 36,
+                    shadows: const [],
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    icon: SvgPicture.asset(
+                      Assets.svg.plus,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                      width: 20,
+                      height: 20,
+                    ),
+                    onPressed: () {
+                      Navigator.of(context).pushNamed(
+                        AddAddressBookEntryView.routeName,
+                      );
+                    },
+                  ),
+                ),
+              ),
+            ],
+          ),
+          body: LayoutBuilder(
+            builder: (builderContext, constraints) {
+              return Padding(
+                padding: const EdgeInsets.only(
+                  left: 12,
+                  top: 12,
+                  right: 12,
+                ),
+                child: SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight - 24,
+                    ),
+                    child: IntrinsicHeight(
+                      child: Padding(
+                        padding: const EdgeInsets.all(4),
+                        child: child,
+                      ),
+                    ),
+                  ),
+                ),
+              );
+            },
+          ),
+        );
+      },
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.stretch,
+        children: [
+          ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
             ),
-          );
-        },
+            child: !isDesktop
+                ? TextField(
+                    autocorrect: Util.isDesktop ? false : true,
+                    enableSuggestions: Util.isDesktop ? false : true,
+                    controller: _searchController,
+                    focusNode: _searchFocusNode,
+                    onChanged: (value) {
+                      setState(() {
+                        _searchTerm = value;
+                      });
+                    },
+                    style: STextStyles.field(context),
+                    decoration: standardInputDecoration(
+                      "Search",
+                      _searchFocusNode,
+                      context,
+                    ).copyWith(
+                      prefixIcon: Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 10,
+                          vertical: 16,
+                        ),
+                        child: SvgPicture.asset(
+                          Assets.svg.search,
+                          width: 16,
+                          height: 16,
+                        ),
+                      ),
+                      suffixIcon: _searchController.text.isNotEmpty
+                          ? Padding(
+                              padding: const EdgeInsets.only(right: 0),
+                              child: UnconstrainedBox(
+                                child: Row(
+                                  children: [
+                                    TextFieldIconButton(
+                                      child: const XIcon(),
+                                      onTap: () async {
+                                        setState(() {
+                                          _searchController.text = "";
+                                        });
+                                      },
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            )
+                          : null,
+                    ),
+                  )
+                : null,
+          ),
+          if (!isDesktop) const SizedBox(height: 16),
+          Text(
+            "Favorites",
+            style: STextStyles.smallMed12(context),
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          FutureBuilder(
+            future: addressBookEntriesFuture,
+            builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
+              if (snapshot.connectionState == ConnectionState.done &&
+                  snapshot.hasData) {
+                _cacheFav = snapshot.data!;
+              }
+              if (_cacheFav == null) {
+                // TODO proper loading animation
+                return const LoadingIndicator();
+              } else {
+                if (_cacheFav!.isNotEmpty) {
+                  return RoundedWhiteContainer(
+                    padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+                    child: Column(
+                      children: [
+                        ..._cacheFav!
+                            .where((element) => element.addresses
+                                .where((e) => ref.watch(
+                                    addressBookFilterProvider.select((value) =>
+                                        value.coins.contains(e.coin))))
+                                .isNotEmpty)
+                            .where((e) =>
+                                e.isFavorite &&
+                                ref
+                                    .read(addressBookServiceProvider)
+                                    .matches(_searchTerm, e))
+                            .where((element) => element.isFavorite)
+                            .map(
+                              (e) => AddressBookCard(
+                                key: Key("favContactCard_${e.id}_key"),
+                                contactId: e.id,
+                              ),
+                            ),
+                      ],
+                    ),
+                  );
+                } else {
+                  return RoundedWhiteContainer(
+                    child: Center(
+                      child: Text(
+                        "Your favorite contacts will appear here",
+                        style: STextStyles.itemSubtitle(context),
+                      ),
+                    ),
+                  );
+                }
+              }
+            },
+          ),
+          const SizedBox(
+            height: 16,
+          ),
+          Text(
+            "All contacts",
+            style: STextStyles.smallMed12(context),
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          FutureBuilder(
+            future: addressBookEntriesFuture,
+            builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
+              if (snapshot.connectionState == ConnectionState.done &&
+                  snapshot.hasData) {
+                _cache = snapshot.data!;
+              }
+              if (_cache == null) {
+                // TODO proper loading animation
+                return const LoadingIndicator();
+              } else {
+                if (_cache!.isNotEmpty) {
+                  return RoundedWhiteContainer(
+                    padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+                    child: Column(
+                      children: [
+                        ..._cache!
+                            .where((element) => element.addresses
+                                .where((e) => ref.watch(
+                                    addressBookFilterProvider.select((value) =>
+                                        value.coins.contains(e.coin))))
+                                .isNotEmpty)
+                            .where((e) => ref
+                                .read(addressBookServiceProvider)
+                                .matches(_searchTerm, e))
+                            .where((element) => !element.isFavorite)
+                            .map(
+                              (e) => AddressBookCard(
+                                key: Key("desktopContactCard_${e.id}_key"),
+                                contactId: e.id,
+                              ),
+                            ),
+                      ],
+                    ),
+                  );
+                } else {
+                  return RoundedWhiteContainer(
+                    child: Center(
+                      child: Text(
+                        "Your contacts will appear here",
+                        style: STextStyles.itemSubtitle(context),
+                      ),
+                    ),
+                  );
+                }
+              }
+            },
+          ),
+        ],
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index e375bbcc7..475650722 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/contact.dart';
+import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
@@ -9,11 +10,11 @@ import 'package:stackwallet/utilities/assets.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/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
-import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
@@ -36,7 +37,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
 
   late bool hasContacts = false;
 
-  String filter = "";
+  String _searchTerm = "";
 
   Future<void> selectCryptocurrency() async {
     await showDialog<dynamic>(
@@ -123,25 +124,25 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                       Constants.size.circularBorderRadius,
                     ),
                     child: TextField(
-                      autocorrect: false,
-                      enableSuggestions: false,
+                      autocorrect: Util.isDesktop ? false : true,
+                      enableSuggestions: Util.isDesktop ? false : true,
                       controller: _searchController,
                       focusNode: _searchFocusNode,
-                      onChanged: (newString) {
-                        setState(() => filter = newString);
+                      onChanged: (value) {
+                        setState(() {
+                          _searchTerm = value;
+                        });
                       },
                       style: STextStyles.field(context),
                       decoration: standardInputDecoration(
-                        "Search...",
+                        "Search",
                         _searchFocusNode,
                         context,
                       ).copyWith(
-                        labelStyle: STextStyles.fieldLabel(context)
-                            .copyWith(fontSize: 16),
                         prefixIcon: Padding(
                           padding: const EdgeInsets.symmetric(
                             horizontal: 10,
-                            vertical: 16,
+                            vertical: 20,
                           ),
                           child: SvgPicture.asset(
                             Assets.svg.search,
@@ -160,7 +161,6 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                                         onTap: () async {
                                           setState(() {
                                             _searchController.text = "";
-                                            filter = "";
                                           });
                                         },
                                       ),
@@ -243,14 +243,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
           padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 26),
           child: SizedBox(
             width: 489,
-            child: RoundedWhiteContainer(
-              child: Center(
-                child: Text(
-                  "Your contacts will appear here",
-                  style: STextStyles.itemSubtitle(context),
-                ),
-              ),
-            ),
+            child: AddressBookView(),
           ),
         ),
       ],

From 3a7f1f9c49854c035e66c4254050a4c7dbfa67e7 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 14 Nov 2022 19:27:36 -0700
Subject: [PATCH 248/426] layout fix for new contact

---
 .../subviews/add_address_book_entry_view.dart | 659 ++++++++++++------
 .../new_contact_address_entry_form.dart       |   6 +-
 2 files changed, 464 insertions(+), 201 deletions(-)

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 588ca5b26..5835c80cd 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
@@ -224,7 +224,11 @@ class _AddAddressBookEntryViewState
                   const DesktopDialogCloseButton(),
                 ],
               ),
-              Expanded(child: child),
+              Expanded(
+                  child: Padding(
+                padding: const EdgeInsets.symmetric(horizontal: 10),
+                child: child,
+              )),
             ],
           );
         },
@@ -248,216 +252,473 @@ class _AddAddressBookEntryViewState
                   child: IntrinsicHeight(
                     child: Column(
                       children: [
-                        const SizedBox(
-                          height: 4,
-                        ),
-                        GestureDetector(
-                          onTap: () {
-                            if (_selectedEmoji != null) {
-                              setState(() {
-                                _selectedEmoji = null;
-                              });
-                              return;
-                            }
+                        if (!isDesktop) const SizedBox(height: 4),
+                        isDesktop
+                            ? Row(
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
+                                children: [
+                                  GestureDetector(
+                                    onTap: () {
+                                      if (_selectedEmoji != null) {
+                                        setState(() {
+                                          _selectedEmoji = null;
+                                        });
+                                        return;
+                                      }
 
-                            ///TODO if desktop make dialog
-                            !isDesktop
-                                ? showModalBottomSheet<dynamic>(
-                                    backgroundColor: Colors.transparent,
-                                    context: context,
-                                    shape: const RoundedRectangleBorder(
-                                      borderRadius: BorderRadius.vertical(
-                                        top: Radius.circular(20),
-                                      ),
-                                    ),
-                                    builder: (_) => const EmojiSelectSheet(),
-                                  ).then((value) {
-                                    if (value is Emoji) {
-                                      setState(() {
-                                        _selectedEmoji = value;
-                                      });
-                                    }
-                                  })
-                                : showDialog<dynamic>(
-                                    context: context,
-                                    builder: (context) {
-                                      return DesktopDialog(
-                                        maxHeight: 700,
-                                        maxWidth: 700,
-                                        child: Column(
-                                          children: [
-                                            Row(
-                                              children: [
-                                                Padding(
-                                                  padding:
-                                                      const EdgeInsets.all(32),
-                                                  child: Text(
-                                                    "Select emoji",
-                                                    style:
-                                                        STextStyles.desktopH3(
-                                                            context),
-                                                    textAlign: TextAlign.center,
-                                                  ),
+                                      ///TODO if desktop make dialog
+                                      !isDesktop
+                                          ? showModalBottomSheet<dynamic>(
+                                              backgroundColor:
+                                                  Colors.transparent,
+                                              context: context,
+                                              shape:
+                                                  const RoundedRectangleBorder(
+                                                borderRadius:
+                                                    BorderRadius.vertical(
+                                                  top: Radius.circular(20),
                                                 ),
-                                              ],
-                                            ),
-                                            Expanded(
-                                              child: LayoutBuilder(
-                                                builder:
-                                                    (context, constraints) {
-                                                  return SingleChildScrollView(
-                                                    scrollDirection:
-                                                        Axis.vertical,
-                                                    child: ConstrainedBox(
-                                                      constraints:
-                                                          BoxConstraints(
-                                                        minHeight: constraints
-                                                            .maxHeight,
-                                                        minWidth: constraints
-                                                            .maxWidth,
-                                                      ),
-                                                      child: IntrinsicHeight(
-                                                        child: Column(
-                                                          children: const [
-                                                            Padding(
-                                                              padding: EdgeInsets
-                                                                  .symmetric(
-                                                                      horizontal:
-                                                                          32),
-                                                              // child:
-                                                              //     EmojiSelectSheet(),
+                                              ),
+                                              builder: (_) =>
+                                                  const EmojiSelectSheet(),
+                                            ).then((value) {
+                                              if (value is Emoji) {
+                                                setState(() {
+                                                  _selectedEmoji = value;
+                                                });
+                                              }
+                                            })
+                                          : showDialog<dynamic>(
+                                              context: context,
+                                              builder: (context) {
+                                                return DesktopDialog(
+                                                  maxHeight: 700,
+                                                  maxWidth: 700,
+                                                  child: Column(
+                                                    children: [
+                                                      Row(
+                                                        children: [
+                                                          Padding(
+                                                            padding:
+                                                                const EdgeInsets
+                                                                    .all(32),
+                                                            child: Text(
+                                                              "Select emoji",
+                                                              style: STextStyles
+                                                                  .desktopH3(
+                                                                      context),
+                                                              textAlign:
+                                                                  TextAlign
+                                                                      .center,
                                                             ),
-                                                          ],
+                                                          ),
+                                                        ],
+                                                      ),
+                                                      Expanded(
+                                                        child: LayoutBuilder(
+                                                          builder: (context,
+                                                              constraints) {
+                                                            return SingleChildScrollView(
+                                                              scrollDirection:
+                                                                  Axis.vertical,
+                                                              child:
+                                                                  ConstrainedBox(
+                                                                constraints:
+                                                                    BoxConstraints(
+                                                                  minHeight:
+                                                                      constraints
+                                                                          .maxHeight,
+                                                                  minWidth:
+                                                                      constraints
+                                                                          .maxWidth,
+                                                                ),
+                                                                child:
+                                                                    IntrinsicHeight(
+                                                                  child: Column(
+                                                                    children: const [
+                                                                      Padding(
+                                                                        padding:
+                                                                            EdgeInsets.symmetric(horizontal: 32),
+                                                                        // child:
+                                                                        //     EmojiSelectSheet(),
+                                                                      ),
+                                                                    ],
+                                                                  ),
+                                                                ),
+                                                              ),
+                                                            );
+                                                          },
                                                         ),
                                                       ),
+                                                    ],
+                                                  ),
+                                                );
+                                              }).then((value) {
+                                              if (value is Emoji) {
+                                                setState(() {
+                                                  _selectedEmoji = value;
+                                                });
+                                              }
+                                            });
+                                    },
+                                    child: SizedBox(
+                                      height: 56,
+                                      width: 56,
+                                      child: Stack(
+                                        children: [
+                                          Container(
+                                            height: 56,
+                                            width: 56,
+                                            decoration: BoxDecoration(
+                                              borderRadius:
+                                                  BorderRadius.circular(24),
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textFieldActiveBG,
+                                            ),
+                                            child: Center(
+                                              child: _selectedEmoji == null
+                                                  ? SvgPicture.asset(
+                                                      Assets.svg.user,
+                                                      height: 30,
+                                                      width: 30,
+                                                    )
+                                                  : Text(
+                                                      _selectedEmoji!.char,
+                                                      style: STextStyles
+                                                          .pageTitleH1(context),
                                                     ),
-                                                  );
-                                                },
+                                            ),
+                                          ),
+                                          Align(
+                                            alignment: Alignment.bottomRight,
+                                            child: Container(
+                                              height: 14,
+                                              width: 14,
+                                              decoration: BoxDecoration(
+                                                  borderRadius:
+                                                      BorderRadius.circular(14),
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .accentColorDark),
+                                              child: Center(
+                                                child: _selectedEmoji == null
+                                                    ? SvgPicture.asset(
+                                                        Assets.svg.plus,
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .textWhite,
+                                                        width: 12,
+                                                        height: 12,
+                                                      )
+                                                    : SvgPicture.asset(
+                                                        Assets.svg.thickX,
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .textWhite,
+                                                        width: 8,
+                                                        height: 8,
+                                                      ),
                                               ),
                                             ),
-                                          ],
-                                        ),
-                                      );
-                                    }).then((value) {
-                                    if (value is Emoji) {
-                                      setState(() {
-                                        _selectedEmoji = value;
-                                      });
-                                    }
-                                  });
-                          },
-                          child: SizedBox(
-                            height: 48,
-                            width: 48,
-                            child: Stack(
-                              children: [
-                                Container(
-                                  height: 48,
-                                  width: 48,
-                                  decoration: BoxDecoration(
-                                    borderRadius: BorderRadius.circular(24),
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textFieldActiveBG,
-                                  ),
-                                  child: Center(
-                                    child: _selectedEmoji == null
-                                        ? SvgPicture.asset(
-                                            Assets.svg.user,
-                                            height: 24,
-                                            width: 24,
                                           )
-                                        : Text(
-                                            _selectedEmoji!.char,
-                                            style: STextStyles.pageTitleH1(
-                                                context),
-                                          ),
-                                  ),
-                                ),
-                                Align(
-                                  alignment: Alignment.bottomRight,
-                                  child: Container(
-                                    height: 14,
-                                    width: 14,
-                                    decoration: BoxDecoration(
-                                        borderRadius: BorderRadius.circular(14),
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorDark),
-                                    child: Center(
-                                      child: _selectedEmoji == null
-                                          ? SvgPicture.asset(
-                                              Assets.svg.plus,
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textWhite,
-                                              width: 12,
-                                              height: 12,
-                                            )
-                                          : SvgPicture.asset(
-                                              Assets.svg.thickX,
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textWhite,
-                                              width: 8,
-                                              height: 8,
-                                            ),
+                                        ],
+                                      ),
                                     ),
                                   ),
-                                )
-                              ],
-                            ),
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            controller: nameController,
-                            focusNode: nameFocusNode,
-                            style: STextStyles.field(context),
-                            decoration: standardInputDecoration(
-                              "Enter contact name",
-                              nameFocusNode,
-                              context,
-                            ).copyWith(
-                              suffixIcon: ref
-                                      .read(contactNameIsNotEmptyStateProvider
-                                          .state)
-                                      .state
-                                  ? Padding(
-                                      padding: const EdgeInsets.only(right: 0),
-                                      child: UnconstrainedBox(
-                                        child: Row(
-                                          children: [
-                                            TextFieldIconButton(
-                                              child: const XIcon(),
-                                              onTap: () async {
-                                                setState(() {
-                                                  nameController.text = "";
-                                                });
-                                              },
-                                            ),
-                                          ],
-                                        ),
+                                  const SizedBox(width: 8),
+                                  SizedBox(
+                                    width: isDesktop ? 450 : null,
+                                    child: ClipRRect(
+                                      borderRadius: BorderRadius.circular(
+                                        Constants.size.circularBorderRadius,
                                       ),
-                                    )
-                                  : null,
-                            ),
-                            onChanged: (newValue) {
-                              ref
-                                  .read(
-                                      contactNameIsNotEmptyStateProvider.state)
-                                  .state = newValue.isNotEmpty;
-                            },
-                          ),
-                        ),
+                                      child: TextField(
+                                        autocorrect:
+                                            Util.isDesktop ? false : true,
+                                        enableSuggestions:
+                                            Util.isDesktop ? false : true,
+                                        controller: nameController,
+                                        focusNode: nameFocusNode,
+                                        style: STextStyles.field(context),
+                                        decoration: standardInputDecoration(
+                                          "Enter contact name",
+                                          nameFocusNode,
+                                          context,
+                                        ).copyWith(
+                                          labelStyle:
+                                              STextStyles.fieldLabel(context),
+                                          suffixIcon: ref
+                                                  .read(
+                                                      contactNameIsNotEmptyStateProvider
+                                                          .state)
+                                                  .state
+                                              ? Padding(
+                                                  padding:
+                                                      const EdgeInsets.only(
+                                                          right: 0),
+                                                  child: UnconstrainedBox(
+                                                    child: Row(
+                                                      children: [
+                                                        TextFieldIconButton(
+                                                          child: const XIcon(),
+                                                          onTap: () async {
+                                                            setState(() {
+                                                              nameController
+                                                                  .text = "";
+                                                            });
+                                                          },
+                                                        ),
+                                                      ],
+                                                    ),
+                                                  ),
+                                                )
+                                              : null,
+                                        ),
+                                        onChanged: (newValue) {
+                                          ref
+                                              .read(
+                                                  contactNameIsNotEmptyStateProvider
+                                                      .state)
+                                              .state = newValue.isNotEmpty;
+                                        },
+                                      ),
+                                    ),
+                                  ),
+                                ],
+                              )
+                            : Column(
+                                children: [
+                                  GestureDetector(
+                                    onTap: () {
+                                      if (_selectedEmoji != null) {
+                                        setState(() {
+                                          _selectedEmoji = null;
+                                        });
+                                        return;
+                                      }
+
+                                      ///TODO if desktop make dialog
+                                      !isDesktop
+                                          ? showModalBottomSheet<dynamic>(
+                                              backgroundColor:
+                                                  Colors.transparent,
+                                              context: context,
+                                              shape:
+                                                  const RoundedRectangleBorder(
+                                                borderRadius:
+                                                    BorderRadius.vertical(
+                                                  top: Radius.circular(20),
+                                                ),
+                                              ),
+                                              builder: (_) =>
+                                                  const EmojiSelectSheet(),
+                                            ).then((value) {
+                                              if (value is Emoji) {
+                                                setState(() {
+                                                  _selectedEmoji = value;
+                                                });
+                                              }
+                                            })
+                                          : showDialog<dynamic>(
+                                              context: context,
+                                              builder: (context) {
+                                                return DesktopDialog(
+                                                  maxHeight: 700,
+                                                  maxWidth: 700,
+                                                  child: Column(
+                                                    children: [
+                                                      Row(
+                                                        children: [
+                                                          Padding(
+                                                            padding:
+                                                                const EdgeInsets
+                                                                    .all(32),
+                                                            child: Text(
+                                                              "Select emoji",
+                                                              style: STextStyles
+                                                                  .desktopH3(
+                                                                      context),
+                                                              textAlign:
+                                                                  TextAlign
+                                                                      .center,
+                                                            ),
+                                                          ),
+                                                        ],
+                                                      ),
+                                                      Expanded(
+                                                        child: LayoutBuilder(
+                                                          builder: (context,
+                                                              constraints) {
+                                                            return SingleChildScrollView(
+                                                              scrollDirection:
+                                                                  Axis.vertical,
+                                                              child:
+                                                                  ConstrainedBox(
+                                                                constraints:
+                                                                    BoxConstraints(
+                                                                  minHeight:
+                                                                      constraints
+                                                                          .maxHeight,
+                                                                  minWidth:
+                                                                      constraints
+                                                                          .maxWidth,
+                                                                ),
+                                                                child:
+                                                                    IntrinsicHeight(
+                                                                  child: Column(
+                                                                    children: const [
+                                                                      Padding(
+                                                                        padding:
+                                                                            EdgeInsets.symmetric(horizontal: 32),
+                                                                        // child:
+                                                                        //     EmojiSelectSheet(),
+                                                                      ),
+                                                                    ],
+                                                                  ),
+                                                                ),
+                                                              ),
+                                                            );
+                                                          },
+                                                        ),
+                                                      ),
+                                                    ],
+                                                  ),
+                                                );
+                                              }).then((value) {
+                                              if (value is Emoji) {
+                                                setState(() {
+                                                  _selectedEmoji = value;
+                                                });
+                                              }
+                                            });
+                                    },
+                                    child: SizedBox(
+                                      height: 48,
+                                      width: 48,
+                                      child: Stack(
+                                        children: [
+                                          Container(
+                                            height: 48,
+                                            width: 48,
+                                            decoration: BoxDecoration(
+                                              borderRadius:
+                                                  BorderRadius.circular(24),
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textFieldActiveBG,
+                                            ),
+                                            child: Center(
+                                              child: _selectedEmoji == null
+                                                  ? SvgPicture.asset(
+                                                      Assets.svg.user,
+                                                      height: 24,
+                                                      width: 24,
+                                                    )
+                                                  : Text(
+                                                      _selectedEmoji!.char,
+                                                      style: STextStyles
+                                                          .pageTitleH1(context),
+                                                    ),
+                                            ),
+                                          ),
+                                          Align(
+                                            alignment: Alignment.bottomRight,
+                                            child: Container(
+                                              height: 14,
+                                              width: 14,
+                                              decoration: BoxDecoration(
+                                                  borderRadius:
+                                                      BorderRadius.circular(14),
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .accentColorDark),
+                                              child: Center(
+                                                child: _selectedEmoji == null
+                                                    ? SvgPicture.asset(
+                                                        Assets.svg.plus,
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .textWhite,
+                                                        width: 12,
+                                                        height: 12,
+                                                      )
+                                                    : SvgPicture.asset(
+                                                        Assets.svg.thickX,
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .textWhite,
+                                                        width: 8,
+                                                        height: 8,
+                                                      ),
+                                              ),
+                                            ),
+                                          )
+                                        ],
+                                      ),
+                                    ),
+                                  ),
+                                  const SizedBox(height: 8),
+                                  ClipRRect(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                    child: TextField(
+                                      autocorrect:
+                                          Util.isDesktop ? false : true,
+                                      enableSuggestions:
+                                          Util.isDesktop ? false : true,
+                                      controller: nameController,
+                                      focusNode: nameFocusNode,
+                                      style: STextStyles.field(context),
+                                      decoration: standardInputDecoration(
+                                        "Enter contact name",
+                                        nameFocusNode,
+                                        context,
+                                      ).copyWith(
+                                        suffixIcon: ref
+                                                .read(
+                                                    contactNameIsNotEmptyStateProvider
+                                                        .state)
+                                                .state
+                                            ? Padding(
+                                                padding: const EdgeInsets.only(
+                                                    right: 0),
+                                                child: UnconstrainedBox(
+                                                  child: Row(
+                                                    children: [
+                                                      TextFieldIconButton(
+                                                        child: const XIcon(),
+                                                        onTap: () async {
+                                                          setState(() {
+                                                            nameController
+                                                                .text = "";
+                                                          });
+                                                        },
+                                                      ),
+                                                    ],
+                                                  ),
+                                                ),
+                                              )
+                                            : null,
+                                      ),
+                                      onChanged: (newValue) {
+                                        ref
+                                            .read(
+                                                contactNameIsNotEmptyStateProvider
+                                                    .state)
+                                            .state = newValue.isNotEmpty;
+                                      },
+                                    ),
+                                  ),
+                                ],
+                              ),
+                        if (!isDesktop) const SizedBox(height: 8),
                         if (forms.length <= 1)
                           const SizedBox(
                             height: 8,
diff --git a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
index ce98cee10..b6cf0aad4 100644
--- a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
+++ b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
@@ -14,14 +14,13 @@ import 'package:stackwallet/utilities/enums/coin_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/icon_widgets/clipboard_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.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';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class NewContactAddressEntryForm extends ConsumerStatefulWidget {
   const NewContactAddressEntryForm({
     Key? key,
@@ -70,6 +69,7 @@ class _NewContactAddressEntryFormState
 
   @override
   Widget build(BuildContext context) {
+    final isDesktop = Util.isDesktop;
     return Column(
       children: [
         TextField(
@@ -168,6 +168,7 @@ class _NewContactAddressEntryFormState
               addressLabelFocusNode,
               context,
             ).copyWith(
+              labelStyle: isDesktop ? STextStyles.fieldLabel(context) : null,
               suffixIcon: addressLabelController.text.isNotEmpty
                   ? Padding(
                       padding: const EdgeInsets.only(right: 0),
@@ -212,6 +213,7 @@ class _NewContactAddressEntryFormState
               addressFocusNode,
               context,
             ).copyWith(
+              labelStyle: isDesktop ? STextStyles.fieldLabel(context) : null,
               suffixIcon: UnconstrainedBox(
                 child: Row(
                   children: [

From e372db770860164485ae2ffd2c34fc2e14fc5ec6 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 14 Nov 2022 20:55:11 -0700
Subject: [PATCH 249/426] height size issue

---
 .../address_book_views/address_book_view.dart | 351 +++++++++---------
 1 file changed, 183 insertions(+), 168 deletions(-)

diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index 08c548627..50e51110b 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -209,181 +209,196 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
           ),
         );
       },
-      child: Column(
-        crossAxisAlignment: CrossAxisAlignment.stretch,
-        children: [
-          ClipRRect(
-            borderRadius: BorderRadius.circular(
-              Constants.size.circularBorderRadius,
-            ),
-            child: !isDesktop
-                ? TextField(
-                    autocorrect: Util.isDesktop ? false : true,
-                    enableSuggestions: Util.isDesktop ? false : true,
-                    controller: _searchController,
-                    focusNode: _searchFocusNode,
-                    onChanged: (value) {
-                      setState(() {
-                        _searchTerm = value;
-                      });
-                    },
-                    style: STextStyles.field(context),
-                    decoration: standardInputDecoration(
-                      "Search",
-                      _searchFocusNode,
-                      context,
-                    ).copyWith(
-                      prefixIcon: Padding(
-                        padding: const EdgeInsets.symmetric(
-                          horizontal: 10,
-                          vertical: 16,
-                        ),
-                        child: SvgPicture.asset(
-                          Assets.svg.search,
-                          width: 16,
-                          height: 16,
+      child: ConstrainedBox(
+        constraints: BoxConstraints(
+          minHeight: MediaQuery.of(context).size.height - 271,
+        ),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: [
+            ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: !isDesktop
+                  ? TextField(
+                      autocorrect: Util.isDesktop ? false : true,
+                      enableSuggestions: Util.isDesktop ? false : true,
+                      controller: _searchController,
+                      focusNode: _searchFocusNode,
+                      onChanged: (value) {
+                        setState(() {
+                          _searchTerm = value;
+                        });
+                      },
+                      style: STextStyles.field(context),
+                      decoration: standardInputDecoration(
+                        "Search",
+                        _searchFocusNode,
+                        context,
+                      ).copyWith(
+                        prefixIcon: Padding(
+                          padding: const EdgeInsets.symmetric(
+                            horizontal: 10,
+                            vertical: 16,
+                          ),
+                          child: SvgPicture.asset(
+                            Assets.svg.search,
+                            width: 16,
+                            height: 16,
+                          ),
                         ),
+                        suffixIcon: _searchController.text.isNotEmpty
+                            ? Padding(
+                                padding: const EdgeInsets.only(right: 0),
+                                child: UnconstrainedBox(
+                                  child: Row(
+                                    children: [
+                                      TextFieldIconButton(
+                                        child: const XIcon(),
+                                        onTap: () async {
+                                          setState(() {
+                                            _searchController.text = "";
+                                          });
+                                        },
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              )
+                            : null,
                       ),
-                      suffixIcon: _searchController.text.isNotEmpty
-                          ? Padding(
-                              padding: const EdgeInsets.only(right: 0),
-                              child: UnconstrainedBox(
-                                child: Row(
-                                  children: [
-                                    TextFieldIconButton(
-                                      child: const XIcon(),
-                                      onTap: () async {
-                                        setState(() {
-                                          _searchController.text = "";
-                                        });
-                                      },
-                                    ),
-                                  ],
+                    )
+                  : null,
+            ),
+            if (!isDesktop) const SizedBox(height: 16),
+            Text(
+              "Favorites",
+              style: STextStyles.smallMed12(context),
+            ),
+            const SizedBox(
+              height: 12,
+            ),
+            FutureBuilder(
+              future: addressBookEntriesFuture,
+              builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
+                if (snapshot.connectionState == ConnectionState.done &&
+                    snapshot.hasData) {
+                  _cacheFav = snapshot.data!;
+                }
+                if (_cacheFav == null) {
+                  // TODO proper loading animation
+                  return const LoadingIndicator();
+                } else {
+                  if (_cacheFav!.isNotEmpty) {
+                    return RoundedWhiteContainer(
+                      padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+                      child: Column(
+                        children: [
+                          ..._cacheFav!
+                              .where((element) => element.addresses
+                                  .where((e) => ref.watch(
+                                      addressBookFilterProvider.select(
+                                          (value) =>
+                                              value.coins.contains(e.coin))))
+                                  .isNotEmpty)
+                              .where((e) =>
+                                  e.isFavorite &&
+                                  ref
+                                      .read(addressBookServiceProvider)
+                                      .matches(_searchTerm, e))
+                              .where((element) => element.isFavorite)
+                              .map(
+                                (e) => AddressBookCard(
+                                  key: Key("favContactCard_${e.id}_key"),
+                                  contactId: e.id,
                                 ),
                               ),
-                            )
-                          : null,
-                    ),
-                  )
-                : null,
-          ),
-          if (!isDesktop) const SizedBox(height: 16),
-          Text(
-            "Favorites",
-            style: STextStyles.smallMed12(context),
-          ),
-          const SizedBox(
-            height: 12,
-          ),
-          FutureBuilder(
-            future: addressBookEntriesFuture,
-            builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
-              if (snapshot.connectionState == ConnectionState.done &&
-                  snapshot.hasData) {
-                _cacheFav = snapshot.data!;
-              }
-              if (_cacheFav == null) {
-                // TODO proper loading animation
-                return const LoadingIndicator();
-              } else {
-                if (_cacheFav!.isNotEmpty) {
-                  return RoundedWhiteContainer(
-                    padding: EdgeInsets.all(!isDesktop ? 0 : 15),
-                    child: Column(
-                      children: [
-                        ..._cacheFav!
-                            .where((element) => element.addresses
-                                .where((e) => ref.watch(
-                                    addressBookFilterProvider.select((value) =>
-                                        value.coins.contains(e.coin))))
-                                .isNotEmpty)
-                            .where((e) =>
-                                e.isFavorite &&
-                                ref
-                                    .read(addressBookServiceProvider)
-                                    .matches(_searchTerm, e))
-                            .where((element) => element.isFavorite)
-                            .map(
-                              (e) => AddressBookCard(
-                                key: Key("favContactCard_${e.id}_key"),
-                                contactId: e.id,
-                              ),
-                            ),
-                      ],
-                    ),
-                  );
-                } else {
-                  return RoundedWhiteContainer(
-                    child: Center(
-                      child: Text(
-                        "Your favorite contacts will appear here",
-                        style: STextStyles.itemSubtitle(context),
+                        ],
                       ),
-                    ),
-                  );
-                }
-              }
-            },
-          ),
-          const SizedBox(
-            height: 16,
-          ),
-          Text(
-            "All contacts",
-            style: STextStyles.smallMed12(context),
-          ),
-          const SizedBox(
-            height: 12,
-          ),
-          FutureBuilder(
-            future: addressBookEntriesFuture,
-            builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
-              if (snapshot.connectionState == ConnectionState.done &&
-                  snapshot.hasData) {
-                _cache = snapshot.data!;
-              }
-              if (_cache == null) {
-                // TODO proper loading animation
-                return const LoadingIndicator();
-              } else {
-                if (_cache!.isNotEmpty) {
-                  return RoundedWhiteContainer(
-                    padding: EdgeInsets.all(!isDesktop ? 0 : 15),
-                    child: Column(
-                      children: [
-                        ..._cache!
-                            .where((element) => element.addresses
-                                .where((e) => ref.watch(
-                                    addressBookFilterProvider.select((value) =>
-                                        value.coins.contains(e.coin))))
-                                .isNotEmpty)
-                            .where((e) => ref
-                                .read(addressBookServiceProvider)
-                                .matches(_searchTerm, e))
-                            .where((element) => !element.isFavorite)
-                            .map(
-                              (e) => AddressBookCard(
-                                key: Key("desktopContactCard_${e.id}_key"),
-                                contactId: e.id,
-                              ),
-                            ),
-                      ],
-                    ),
-                  );
-                } else {
-                  return RoundedWhiteContainer(
-                    child: Center(
-                      child: Text(
-                        "Your contacts will appear here",
-                        style: STextStyles.itemSubtitle(context),
+                    );
+                  } else {
+                    return RoundedWhiteContainer(
+                      child: Center(
+                        child: Text(
+                          "Your favorite contacts will appear here",
+                          style: STextStyles.itemSubtitle(context),
+                        ),
                       ),
-                    ),
-                  );
+                    );
+                  }
                 }
-              }
-            },
-          ),
-        ],
+              },
+            ),
+            const SizedBox(
+              height: 16,
+            ),
+            Text(
+              "All contacts",
+              style: STextStyles.smallMed12(context),
+            ),
+            const SizedBox(
+              height: 12,
+            ),
+            FutureBuilder(
+              future: addressBookEntriesFuture,
+              builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
+                if (snapshot.connectionState == ConnectionState.done &&
+                    snapshot.hasData) {
+                  _cache = snapshot.data!;
+                }
+                if (_cache == null) {
+                  // TODO proper loading animation
+                  return const LoadingIndicator();
+                } else {
+                  if (_cache!.isNotEmpty) {
+                    return Column(
+                      children: [
+                        RoundedWhiteContainer(
+                          padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+                          child: Padding(
+                            padding: const EdgeInsets.all(8.0),
+                            child: Column(
+                              children: [
+                                ..._cache!
+                                    .where((element) => element.addresses
+                                        .where((e) => ref.watch(
+                                            addressBookFilterProvider.select(
+                                                (value) => value.coins
+                                                    .contains(e.coin))))
+                                        .isNotEmpty)
+                                    .where((e) => ref
+                                        .read(addressBookServiceProvider)
+                                        .matches(_searchTerm, e))
+                                    .where((element) => !element.isFavorite)
+                                    .map(
+                                      (e) => AddressBookCard(
+                                        key: Key(
+                                            "desktopContactCard_${e.id}_key"),
+                                        contactId: e.id,
+                                      ),
+                                    ),
+                              ],
+                            ),
+                          ),
+                        ),
+                      ],
+                    );
+                  } else {
+                    return RoundedWhiteContainer(
+                      child: Center(
+                        child: Text(
+                          "Your contacts will appear here",
+                          style: STextStyles.itemSubtitle(context),
+                        ),
+                      ),
+                    );
+                  }
+                }
+              },
+            ),
+          ],
+        ),
       ),
     );
   }

From 591edeca63a2b7899e908ef9d493d2dc3ef09a6c Mon Sep 17 00:00:00 2001
From: Dan Miller <dan@cypherstack.com>
Date: Mon, 14 Nov 2022 20:40:44 -0800
Subject: [PATCH 250/426] Fix RFC6068 mailto link for support on desktop
 plaftorm.

---
 .../settings_views/global_settings_view/support_view.dart     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/support_view.dart b/lib/pages/settings_views/global_settings_view/support_view.dart
index 20aeedf61..6bf3544ae 100644
--- a/lib/pages/settings_views/global_settings_view/support_view.dart
+++ b/lib/pages/settings_views/global_settings_view/support_view.dart
@@ -330,7 +330,7 @@ class SupportView extends StatelessWidget {
               onPressed: () {
                 if (!isDesktop) {
                   launchUrl(
-                    Uri.parse("mailto://support@stackwallet.com"),
+                    Uri.parse("mailto:support@stackwallet.com"),
                     mode: LaunchMode.externalApplication,
                   );
                 }
@@ -367,7 +367,7 @@ class SupportView extends StatelessWidget {
                       text: isDesktop ? "support@stackwallet.com" : "",
                       onTap: () {
                         launchUrl(
-                          Uri.parse("mailto://support@stackwallet.com"),
+                          Uri.parse("mailto:support@stackwallet.com"),
                           mode: LaunchMode.externalApplication,
                         );
                       },

From 4a908564980fc4e426df61479a36192447aaa9e1 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 12:12:38 -0700
Subject: [PATCH 251/426] WIP: node settings scrollable

---
 .../home/settings_menu/nodes_settings.dart    | 29 +++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index 1d0317037..2343e3990 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -11,8 +11,10 @@ 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/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
+import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
 class NodesSettings extends ConsumerStatefulWidget {
   const NodesSettings({Key? key}) : super(key: key);
@@ -29,6 +31,8 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
   late final TextEditingController searchNodeController;
   late final FocusNode searchNodeFocusNode;
 
+  late final ScrollController nodeScrollController;
+
   String filter = "";
 
   @override
@@ -39,6 +43,8 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
     searchNodeController = TextEditingController();
     searchNodeFocusNode = FocusNode();
 
+    nodeScrollController = ScrollController();
+
     super.initState();
   }
 
@@ -134,6 +140,26 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                             height: 16,
                           ),
                         ),
+                        suffixIcon: searchNodeController.text.isNotEmpty
+                            ? Padding(
+                                padding: const EdgeInsets.only(right: 0),
+                                child: UnconstrainedBox(
+                                  child: Row(
+                                    children: [
+                                      TextFieldIconButton(
+                                        child: const XIcon(),
+                                        onTap: () async {
+                                          setState(() {
+                                            searchNodeController.text = "";
+                                            filter = "";
+                                          });
+                                        },
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              )
+                            : null,
                       ),
                     ),
                   ),
@@ -145,6 +171,9 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                     borderColor:
                         Theme.of(context).extension<StackColors>()!.background,
                     child: ListView.separated(
+                      controller: nodeScrollController,
+                      physics: const AlwaysScrollableScrollPhysics(),
+                      scrollDirection: Axis.vertical,
                       primary: false,
                       shrinkWrap: true,
                       itemBuilder: (context, index) {

From 8adec7ba5cba884d14181b78ad7056d5714cf21b Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 12:29:08 -0700
Subject: [PATCH 252/426] auto frequency dark mode text fix

---
 .../stack_backup_views/edit_auto_backup_view.dart         | 8 +++++++-
 .../backup_and_restore/create_auto_backup.dart            | 6 +++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
index 3b6d87b52..76d280980 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
@@ -424,6 +424,7 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
                 passwordFocusNode,
                 context,
               ).copyWith(
+                labelStyle: isDesktop ? STextStyles.fieldLabel(context) : null,
                 suffixIcon: UnconstrainedBox(
                   child: Row(
                     children: [
@@ -555,6 +556,7 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
                 passwordRepeatFocusNode,
                 context,
               ).copyWith(
+                labelStyle: isDesktop ? STextStyles.fieldLabel(context) : null,
                 suffixIcon: UnconstrainedBox(
                   child: Row(
                     children: [
@@ -631,7 +633,11 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
 
                       return DropdownMenuItem(
                         value: e,
-                        child: Text(message),
+                        child: Text(
+                          message,
+                          style:
+                              STextStyles.desktopTextExtraExtraSmall(context),
+                        ),
                       );
                     },
                   ),
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 5e7e86fe1..663136dba 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -492,7 +492,11 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
 
                             return DropdownMenuItem(
                               value: e,
-                              child: Text(message),
+                              child: Text(
+                                message,
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                    context),
+                              ),
                             );
                           },
                         ),

From a5d925fb98e8ab0c00cf37cafec6d20ba4f4d214 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 13:42:48 -0700
Subject: [PATCH 253/426] WIP: manual backup nav route error

---
 .../create_backup_view.dart                   | 121 ++++++++++++++++--
 1 file changed, 109 insertions(+), 12 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index b7ee6b4be..821504bf8 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -18,6 +18,7 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
@@ -523,7 +524,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
 
                               if (mounted) {
                                 // pop encryption progress dialog
-                                Navigator.of(context).pop();
+                                if (!isDesktop) Navigator.of(context).pop();
 
                                 if (result) {
                                   await showDialog<dynamic>(
@@ -607,14 +608,52 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                                     return;
                                   }
 
-                                  unawaited(showDialog<dynamic>(
-                                    context: context,
-                                    barrierDismissible: false,
-                                    builder: (_) => const StackDialog(
-                                      title: "Encrypting backup",
-                                      message: "This shouldn't take long",
+                                  unawaited(
+                                    showDialog<dynamic>(
+                                      context: context,
+                                      barrierDismissible: false,
+                                      builder: (_) {
+                                        if (Util.isDesktop) {
+                                          return DesktopDialog(
+                                            maxHeight: double.infinity,
+                                            maxWidth: 450,
+                                            child: Padding(
+                                              padding: const EdgeInsets.all(
+                                                32,
+                                              ),
+                                              child: Column(
+                                                mainAxisSize: MainAxisSize.min,
+                                                crossAxisAlignment:
+                                                    CrossAxisAlignment.start,
+                                                children: [
+                                                  Text(
+                                                    "Encrypting initial backup",
+                                                    style:
+                                                        STextStyles.desktopH3(
+                                                            context),
+                                                  ),
+                                                  const SizedBox(
+                                                    height: 40,
+                                                  ),
+                                                  Text(
+                                                    "This shouldn't take long",
+                                                    style: STextStyles
+                                                        .desktopTextExtraExtraSmall(
+                                                            context),
+                                                  ),
+                                                ],
+                                              ),
+                                            ),
+                                          );
+                                        } else {
+                                          return const StackDialog(
+                                            title: "Encrypting initial backup",
+                                            message: "This shouldn't take long",
+                                          );
+                                        }
+                                      },
                                     ),
-                                  ));
+                                  );
                                   // make sure the dialog is able to be displayed for at least 1 second
                                   await Future<void>.delayed(
                                       const Duration(seconds: 1));
@@ -637,7 +676,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
 
                                   if (mounted) {
                                     // pop encryption progress dialog
-                                    Navigator.of(context).pop();
+                                    if (!isDesktop) Navigator.of(context).pop();
 
                                     if (result) {
                                       await showDialog<dynamic>(
@@ -648,9 +687,67 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                                                 title: "Backup saved to:",
                                                 message: fileToSave,
                                               )
-                                            : const StackOkDialog(
-                                                title:
-                                                    "Backup creation succeeded"),
+                                            : !isDesktop
+                                                ? const StackOkDialog(
+                                                    title:
+                                                        "Backup creation succeeded")
+                                                : DesktopDialog(
+                                                    maxHeight: double.infinity,
+                                                    maxWidth: 500,
+                                                    child: Padding(
+                                                      padding:
+                                                          const EdgeInsets.only(
+                                                        left: 32,
+                                                        right: 32,
+                                                        bottom: 32,
+                                                      ),
+                                                      child: Column(
+                                                        mainAxisSize:
+                                                            MainAxisSize.min,
+                                                        crossAxisAlignment:
+                                                            CrossAxisAlignment
+                                                                .start,
+                                                        children: [
+                                                          const SizedBox(
+                                                              height: 26),
+                                                          Text(
+                                                            "Stack backup saved to: \n",
+                                                            style: STextStyles
+                                                                .desktopH3(
+                                                                    context),
+                                                          ),
+                                                          Text(
+                                                            fileToSave,
+                                                            style: STextStyles
+                                                                .desktopTextExtraExtraSmall(
+                                                                    context),
+                                                          ),
+                                                          const SizedBox(
+                                                            height: 40,
+                                                          ),
+                                                          Row(
+                                                            children: [
+                                                              // const Spacer(),
+                                                              Expanded(
+                                                                child:
+                                                                    PrimaryButton(
+                                                                  label: "Ok",
+                                                                  desktopMed:
+                                                                      true,
+                                                                  onPressed:
+                                                                      () {
+                                                                    // Navigator.of(
+                                                                    //         context)
+                                                                    //     .pop();
+                                                                  },
+                                                                ),
+                                                              ),
+                                                            ],
+                                                          )
+                                                        ],
+                                                      ),
+                                                    ),
+                                                  ),
                                       );
                                       passwordController.text = "";
                                       passwordRepeatController.text = "";

From 2ec1bda6f2ff3b51f893ed8d4793249a20f1a715 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 13:45:06 -0700
Subject: [PATCH 254/426] desktop address book contact buttons

---
 lib/widgets/address_book_card.dart | 180 ++++++++++++++---------------
 1 file changed, 88 insertions(+), 92 deletions(-)

diff --git a/lib/widgets/address_book_card.dart b/lib/widgets/address_book_card.dart
index cebcf166f..c9ac86052 100644
--- a/lib/widgets/address_book_card.dart
+++ b/lib/widgets/address_book_card.dart
@@ -9,7 +9,6 @@ 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/conditional_parent.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class AddressBookCard extends ConsumerStatefulWidget {
@@ -59,111 +58,108 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
       }
     }
 
-    return ConditionalParent(
-      condition: !isDesktop,
-      child: Row(
-        children: [
-          Container(
-            width: 32,
-            height: 32,
-            decoration: BoxDecoration(
-              color: contact.id == "default"
-                  ? Theme.of(context)
-                      .extension<StackColors>()!
-                      .myStackContactIconBG
-                  : Theme.of(context)
-                      .extension<StackColors>()!
-                      .textFieldDefaultBG,
-              borderRadius: BorderRadius.circular(32),
+    return RoundedWhiteContainer(
+      padding: const EdgeInsets.all(4),
+      child: RawMaterialButton(
+        // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+        padding: const EdgeInsets.all(0),
+        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+        shape: RoundedRectangleBorder(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
+          ),
+        ),
+        onPressed: () {
+          showDialog<void>(
+            context: context,
+            useSafeArea: true,
+            barrierDismissible: true,
+            builder: (_) => ContactPopUp(
+              contactId: contact.id,
             ),
-            child: contact.id == "default"
-                ? Center(
-                    child: SvgPicture.asset(
-                      Assets.svg.stackIcon(context),
-                      width: 20,
-                    ),
-                  )
-                : contact.emojiChar != null
+          );
+        },
+        child: Padding(
+          padding: const EdgeInsets.all(8.0),
+          child: Row(
+            children: [
+              Container(
+                width: 32,
+                height: 32,
+                decoration: BoxDecoration(
+                  color: contact.id == "default"
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .myStackContactIconBG
+                      : Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldDefaultBG,
+                  borderRadius: BorderRadius.circular(32),
+                ),
+                child: contact.id == "default"
                     ? Center(
-                        child: Text(contact.emojiChar!),
-                      )
-                    : Center(
                         child: SvgPicture.asset(
-                          Assets.svg.user,
-                          width: 18,
+                          Assets.svg.stackIcon(context),
+                          width: 20,
                         ),
-                      ),
-          ),
-          const SizedBox(
-            width: 12,
-          ),
-          if (isDesktop)
-            Text(
-              contact.name,
-              style: STextStyles.itemSubtitle12(context),
-            ),
-          if (isDesktop)
-            const SizedBox(
-              width: 16,
-            ),
-          if (isDesktop)
-            Text(
-              coinsString,
-              style: STextStyles.label(context),
-            ),
-          if (!isDesktop)
-            Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
+                      )
+                    : contact.emojiChar != null
+                        ? Center(
+                            child: Text(contact.emojiChar!),
+                          )
+                        : Center(
+                            child: SvgPicture.asset(
+                              Assets.svg.user,
+                              width: 18,
+                            ),
+                          ),
+              ),
+              const SizedBox(
+                width: 12,
+              ),
+              if (isDesktop)
                 Text(
                   contact.name,
                   style: STextStyles.itemSubtitle12(context),
                 ),
+              if (isDesktop)
                 const SizedBox(
-                  height: 4,
+                  width: 16,
                 ),
+              if (isDesktop)
                 Text(
                   coinsString,
                   style: STextStyles.label(context),
                 ),
-              ],
-            ),
-          if (isDesktop) const Spacer(),
-          if (isDesktop)
-            SvgPicture.asset(
-              widget.indicatorDown == true
-                  ? Assets.svg.chevronDown
-                  : Assets.svg.chevronUp,
-              width: 10,
-              height: 5,
-              color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
-            ),
-        ],
-      ),
-      builder: (child) => RoundedWhiteContainer(
-        padding: const EdgeInsets.all(4),
-        child: RawMaterialButton(
-          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-          padding: const EdgeInsets.all(0),
-          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-          shape: RoundedRectangleBorder(
-            borderRadius: BorderRadius.circular(
-              Constants.size.circularBorderRadius,
-            ),
-          ),
-          onPressed: () {
-            showDialog<void>(
-              context: context,
-              useSafeArea: true,
-              barrierDismissible: true,
-              builder: (_) => ContactPopUp(
-                contactId: contact.id,
-              ),
-            );
-          },
-          child: Padding(
-            padding: const EdgeInsets.all(8.0),
-            child: child,
+              if (!isDesktop)
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    Text(
+                      contact.name,
+                      style: STextStyles.itemSubtitle12(context),
+                    ),
+                    const SizedBox(
+                      height: 4,
+                    ),
+                    Text(
+                      coinsString,
+                      style: STextStyles.label(context),
+                    ),
+                  ],
+                ),
+              if (isDesktop) const Spacer(),
+              // if (isDesktop)
+              //   SvgPicture.asset(
+              //     widget.indicatorDown == true
+              //         ? Assets.svg.chevronDown
+              //         : Assets.svg.chevronUp,
+              //     width: 10,
+              //     height: 5,
+              //     color:
+              //         Theme.of(context).extension<StackColors>()!.textSubtitle2,
+              //   ),
+            ],
           ),
         ),
       ),

From d326c10f4236a071e55a7bb8eb63873a57103f06 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 11:59:53 -0600
Subject: [PATCH 255/426] desktop login loading indicator

---
 .../desktop_login_view.dart                      | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index 93a281bf8..363c1fb0d 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -17,6 +17,7 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 
 class DesktopLoginView extends ConsumerStatefulWidget {
@@ -45,6 +46,15 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
 
   Future<void> login() async {
     try {
+      unawaited(
+        showDialog(
+          context: context,
+          builder: (context) => const LoadingIndicator(
+            width: 200,
+          ),
+        ),
+      );
+
       await ref
           .read(storageCryptoHandlerProvider)
           .initFromExisting(passwordController.text);
@@ -55,6 +65,9 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
 
       // if no errors passphrase is correct
       if (mounted) {
+        // pop loading indicator
+        Navigator.of(context).pop();
+
         unawaited(
           Navigator.of(context).pushNamedAndRemoveUntil(
             DesktopHomeView.routeName,
@@ -63,6 +76,9 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
         );
       }
     } catch (e) {
+      // pop loading indicator
+      Navigator.of(context).pop();
+
       await showFloatingFlushBar(
         type: FlushBarType.warning,
         message: e.toString(),

From a48975940d2b1eeef817c4353718c246663c477f Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 12:16:12 -0600
Subject: [PATCH 256/426] desktop wallet keys and net info button highlight

---
 .../wallet_view/desktop_wallet_view.dart      |  4 +-
 .../sub_widgets/network_info_button.dart      | 39 +++++++++++++------
 .../sub_widgets/wallet_keys_button.dart       | 22 +++++------
 3 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 97efb2f68..81b531632 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -292,13 +292,13 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                     eventBus: eventBus,
                   ),
                   const SizedBox(
-                    width: 32,
+                    width: 2,
                   ),
                   WalletKeysButton(
                     walletId: walletId,
                   ),
                   const SizedBox(
-                    width: 32,
+                    width: 12,
                   ),
                 ],
               ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
index c001f9bf3..59d20a9df 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
@@ -98,25 +98,26 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
 
   Widget _buildNetworkIcon(WalletSyncStatus status, BuildContext context) {
     const size = 24.0;
+    final color = _getColor(status, context);
     switch (status) {
       case WalletSyncStatus.unableToSync:
         return SvgPicture.asset(
           Assets.svg.radioProblem,
-          color: Theme.of(context).extension<StackColors>()!.accentColorRed,
+          color: color,
           width: size,
           height: size,
         );
       case WalletSyncStatus.synced:
         return SvgPicture.asset(
           Assets.svg.radio,
-          color: Theme.of(context).extension<StackColors>()!.accentColorGreen,
+          color: color,
           width: size,
           height: size,
         );
       case WalletSyncStatus.syncing:
         return SvgPicture.asset(
           Assets.svg.radioSyncing,
-          color: Theme.of(context).extension<StackColors>()!.accentColorYellow,
+          color: color,
           width: size,
           height: size,
         );
@@ -125,35 +126,46 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
 
   Widget _buildText(WalletSyncStatus status, BuildContext context) {
     String label;
-    Color color;
 
     switch (status) {
       case WalletSyncStatus.unableToSync:
         label = "Unable to sync";
-        color = Theme.of(context).extension<StackColors>()!.accentColorRed;
         break;
       case WalletSyncStatus.synced:
         label = "Synchronised";
-        color = Theme.of(context).extension<StackColors>()!.accentColorGreen;
         break;
       case WalletSyncStatus.syncing:
         label = "Synchronising";
-        color = Theme.of(context).extension<StackColors>()!.accentColorYellow;
         break;
     }
 
     return Text(
       label,
       style: STextStyles.desktopMenuItemSelected(context).copyWith(
-        color: color,
+        color: _getColor(status, context),
       ),
     );
   }
 
+  Color _getColor(WalletSyncStatus status, BuildContext context) {
+    switch (status) {
+      case WalletSyncStatus.unableToSync:
+        return Theme.of(context).extension<StackColors>()!.accentColorRed;
+      case WalletSyncStatus.synced:
+        return Theme.of(context).extension<StackColors>()!.accentColorGreen;
+      case WalletSyncStatus.syncing:
+        return Theme.of(context).extension<StackColors>()!.accentColorYellow;
+    }
+  }
+
   @override
   Widget build(BuildContext context) {
-    return GestureDetector(
-      onTap: () {
+    return RawMaterialButton(
+      hoverColor: _getColor(_currentSyncStatus, context).withOpacity(0.1),
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(1000),
+      ),
+      onPressed: () {
         if (Util.isDesktop) {
           // showDialog<void>(
           //   context: context,
@@ -265,8 +277,11 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
           );
         }
       },
-      child: Container(
-        color: Colors.transparent,
+      child: Padding(
+        padding: const EdgeInsets.symmetric(
+          vertical: 16,
+          horizontal: 32,
+        ),
         child: Row(
           children: [
             _buildNetworkIcon(_currentSyncStatus, context),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
index 649433d52..32994dcb9 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
@@ -16,8 +16,11 @@ class WalletKeysButton extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return GestureDetector(
-      onTap: () {
+    return RawMaterialButton(
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(1000),
+      ),
+      onPressed: () {
         showDialog<void>(
           context: context,
           barrierDismissible: false,
@@ -36,17 +39,12 @@ class WalletKeysButton extends StatelessWidget {
             },
           ),
         );
-
-        // showDialog<void>(
-        //   context: context,
-        //   barrierDismissible: false,
-        //   builder: (context) => UnlockWalletKeysDesktop(
-        //     walletId: walletId,
-        //   ),
-        // );
       },
-      child: Container(
-        color: Colors.transparent,
+      child: Padding(
+        padding: const EdgeInsets.symmetric(
+          vertical: 19,
+          horizontal: 32,
+        ),
         child: Row(
           children: [
             SvgPicture.asset(

From 5211617082c1c458c7cf85ce19d2f64697a53cf5 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 14:56:05 -0600
Subject: [PATCH 257/426] WIP desktop fee dropdown

---
 .../sub_widgets/desktop_fee_dropdown.dart     | 369 ++++++++++++++++++
 .../wallet_view/sub_widgets/desktop_send.dart |  72 ++--
 2 files changed, 407 insertions(+), 34 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart
new file mode 100644
index 000000000..9acb3a6f9
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart
@@ -0,0 +1,369 @@
+import 'package:decimal/decimal.dart';
+import 'package:dropdown_button2/dropdown_button2.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/models/models.dart';
+import 'package:stackwallet/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/providers/ui/fee_rate_type_state_provider.dart';
+import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
+import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
+import 'package:stackwallet/utilities/format.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/animated_text.dart';
+
+class DesktopFeeDropDown extends ConsumerStatefulWidget {
+  const DesktopFeeDropDown({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  @override
+  ConsumerState<DesktopFeeDropDown> createState() => _DesktopFeeDropDownState();
+}
+
+class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
+  late final String walletId;
+
+  FeeObject? feeObject;
+  FeeRateType feeRateType = FeeRateType.average;
+
+  final stringsToLoopThrough = [
+    "Calculating",
+    "Calculating.",
+    "Calculating..",
+    "Calculating...",
+  ];
+
+  Future<Decimal> feeFor({
+    required int amount,
+    required FeeRateType feeRateType,
+    required int feeRate,
+    required Coin coin,
+  }) async {
+    switch (feeRateType) {
+      case FeeRateType.fast:
+        if (ref.read(feeSheetSessionCacheProvider).fast[amount] == null) {
+          final manager =
+              ref.read(walletsChangeNotifierProvider).getManager(walletId);
+
+          if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+              ref.read(publicPrivateBalanceStateProvider.state).state !=
+                  "Private") {
+            ref.read(feeSheetSessionCacheProvider).fast[amount] =
+                Format.satoshisToAmount(await (manager.wallet as FiroWallet)
+                    .estimateFeeForPublic(amount, feeRate));
+          } else {
+            ref.read(feeSheetSessionCacheProvider).fast[amount] =
+                Format.satoshisToAmount(
+                    await manager.estimateFeeFor(amount, feeRate));
+          }
+        }
+        return ref.read(feeSheetSessionCacheProvider).fast[amount]!;
+
+      case FeeRateType.average:
+        if (ref.read(feeSheetSessionCacheProvider).average[amount] == null) {
+          final manager =
+              ref.read(walletsChangeNotifierProvider).getManager(walletId);
+
+          if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+              ref.read(publicPrivateBalanceStateProvider.state).state !=
+                  "Private") {
+            ref.read(feeSheetSessionCacheProvider).average[amount] =
+                Format.satoshisToAmount(await (manager.wallet as FiroWallet)
+                    .estimateFeeForPublic(amount, feeRate));
+          } else {
+            ref.read(feeSheetSessionCacheProvider).average[amount] =
+                Format.satoshisToAmount(
+                    await manager.estimateFeeFor(amount, feeRate));
+          }
+        }
+        return ref.read(feeSheetSessionCacheProvider).average[amount]!;
+
+      case FeeRateType.slow:
+        if (ref.read(feeSheetSessionCacheProvider).slow[amount] == null) {
+          final manager =
+              ref.read(walletsChangeNotifierProvider).getManager(walletId);
+
+          if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+              ref.read(publicPrivateBalanceStateProvider.state).state !=
+                  "Private") {
+            ref.read(feeSheetSessionCacheProvider).slow[amount] =
+                Format.satoshisToAmount(await (manager.wallet as FiroWallet)
+                    .estimateFeeForPublic(amount, feeRate));
+          } else {
+            ref.read(feeSheetSessionCacheProvider).slow[amount] =
+                Format.satoshisToAmount(
+                    await manager.estimateFeeFor(amount, feeRate));
+          }
+        }
+        return ref.read(feeSheetSessionCacheProvider).slow[amount]!;
+    }
+  }
+
+  String estimatedTimeToBeIncludedInNextBlock(
+      int targetBlockTime, int estimatedNumberOfBlocks) {
+    int time = targetBlockTime * estimatedNumberOfBlocks;
+
+    int hours = (time / 3600).floor();
+    if (hours > 1) {
+      return "~$hours hours";
+    } else if (hours == 1) {
+      return "~$hours hour";
+    }
+
+    // less than an hour
+
+    final string = (time / 60).toStringAsFixed(1);
+
+    if (string == "1.0") {
+      return "~1 minute";
+    } else {
+      if (string.endsWith(".0")) {
+        return "~${(time / 60).floor()} minutes";
+      }
+      return "~$string minutes";
+    }
+  }
+
+  @override
+  void initState() {
+    walletId = widget.walletId;
+    super.initState();
+  }
+
+  String? labelSlow;
+  String? labelAverage;
+  String? labelFast;
+
+  @override
+  Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+
+    final manager = ref.watch(walletsChangeNotifierProvider
+        .select((value) => value.getManager(walletId)));
+
+    return FutureBuilder(
+        future: manager.fees,
+        builder: (context, AsyncSnapshot<FeeObject> snapshot) {
+          if (snapshot.connectionState == ConnectionState.done &&
+              snapshot.hasData) {
+            feeObject = snapshot.data!;
+          }
+          return DropdownButtonHideUnderline(
+            child: DropdownButton2(
+              offset: const Offset(0, -10),
+              isExpanded: true,
+              dropdownElevation: 0,
+              value: ref.watch(feeRateTypeStateProvider.state).state,
+              // selectedItemBuilder: (s) {
+              //   return [
+              //     ...FeeRateType.values.map(
+              //       (e) => DropdownMenuItem(
+              //         value: e,
+              //         child: FeeDropDownChild(
+              //           feeObject: feeObject,
+              //           feeRateType: e,
+              //           walletId: walletId,
+              //           amount: amount,
+              //           feeFor: feeFor,
+              //           isSelected: true,
+              //         ),
+              //       ),
+              //     ),
+              //   ];
+              // },
+              items: [
+                ...FeeRateType.values.map(
+                  (e) => DropdownMenuItem(
+                    value: e,
+                    child: FeeDropDownChild(
+                      feeObject: feeObject,
+                      feeRateType: e,
+                      walletId: walletId,
+                      feeFor: feeFor,
+                      isSelected: false,
+                    ),
+                  ),
+                ),
+              ],
+              onChanged: (newRateType) {
+                if (newRateType is FeeRateType) {
+                  ref.read(feeRateTypeStateProvider.state).state = newRateType;
+                }
+              },
+              icon: SvgPicture.asset(
+                Assets.svg.chevronDown,
+                width: 12,
+                height: 6,
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
+              ),
+              buttonPadding: const EdgeInsets.symmetric(
+                horizontal: 16,
+                vertical: 8,
+              ),
+              buttonDecoration: BoxDecoration(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultBG,
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
+              ),
+              dropdownDecoration: BoxDecoration(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultBG,
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
+              ),
+            ),
+          );
+        });
+  }
+}
+
+final sendAmountProvider =
+    StateProvider.autoDispose<Decimal>((_) => Decimal.zero);
+
+class FeeDropDownChild extends ConsumerWidget {
+  const FeeDropDownChild({
+    Key? key,
+    required this.feeObject,
+    required this.feeRateType,
+    required this.walletId,
+    required this.feeFor,
+    required this.isSelected,
+  }) : super(key: key);
+
+  final FeeObject? feeObject;
+  final FeeRateType feeRateType;
+  final String walletId;
+  final Future<Decimal> Function({
+    required int amount,
+    required FeeRateType feeRateType,
+    required int feeRate,
+    required Coin coin,
+  }) feeFor;
+  final bool isSelected;
+
+  static const stringsToLoopThrough = [
+    "Calculating",
+    "Calculating.",
+    "Calculating..",
+    "Calculating...",
+  ];
+
+  String estimatedTimeToBeIncludedInNextBlock(
+      int targetBlockTime, int estimatedNumberOfBlocks) {
+    int time = targetBlockTime * estimatedNumberOfBlocks;
+
+    int hours = (time / 3600).floor();
+    if (hours > 1) {
+      return "~$hours hours";
+    } else if (hours == 1) {
+      return "~$hours hour";
+    }
+
+    // less than an hour
+
+    final string = (time / 60).toStringAsFixed(1);
+
+    if (string == "1.0") {
+      return "~1 minute";
+    } else {
+      if (string.endsWith(".0")) {
+        return "~${(time / 60).floor()} minutes";
+      }
+      return "~$string minutes";
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    debugPrint("BUILD: $runtimeType : $feeRateType");
+
+    final manager = ref.watch(walletsChangeNotifierProvider
+        .select((value) => value.getManager(walletId)));
+
+    if (feeObject == null) {
+      return AnimatedText(
+        stringsToLoopThrough: stringsToLoopThrough,
+        style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+          color:
+              Theme.of(context).extension<StackColors>()!.textFieldActiveText,
+        ),
+      );
+    } else {
+      return FutureBuilder(
+        future: feeFor(
+          coin: manager.coin,
+          feeRateType: FeeRateType.fast,
+          feeRate: feeRateType == FeeRateType.fast
+              ? feeObject!.fast
+              : feeRateType == FeeRateType.slow
+                  ? feeObject!.slow
+                  : feeObject!.medium,
+          amount: Format.decimalAmountToSatoshis(
+            ref.watch(sendAmountProvider.state).state,
+          ),
+        ),
+        builder: (_, AsyncSnapshot<Decimal> snapshot) {
+          if (snapshot.connectionState == ConnectionState.done &&
+              snapshot.hasData) {
+            return Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Text(
+                  "${feeRateType.prettyName} (~${snapshot.data!} ${manager.coin.ticker})",
+                  style:
+                      STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .textFieldActiveText,
+                  ),
+                  textAlign: TextAlign.left,
+                ),
+                if (feeObject != null)
+                  Text(
+                    estimatedTimeToBeIncludedInNextBlock(
+                      Constants.targetBlockTimeInSeconds(manager.coin),
+                      feeRateType == FeeRateType.fast
+                          ? feeObject!.numberOfBlocksFast
+                          : feeRateType == FeeRateType.slow
+                              ? feeObject!.numberOfBlocksSlow
+                              : feeObject!.numberOfBlocksAverage,
+                    ),
+                    style: STextStyles.desktopTextExtraExtraSmall(context)
+                        .copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldActiveSearchIconRight,
+                    ),
+                  ),
+              ],
+            );
+          } else {
+            return AnimatedText(
+              stringsToLoopThrough: stringsToLoopThrough,
+              style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldActiveText,
+              ),
+            );
+          }
+        },
+      );
+    }
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index 071122def..cd19c53f8 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -13,6 +13,7 @@ import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dia
 import 'package:stackwallet/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/ui/fee_rate_type_state_provider.dart';
 import 'package:stackwallet/providers/ui/preview_tx_button_state_provider.dart';
@@ -94,11 +95,6 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
   late VoidCallback onCryptoAmountChanged;
 
   Future<void> previewSend() 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);
 
@@ -794,35 +790,25 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
       _addressToggleFlag = true;
     }
 
-    // _cryptoFocus.addListener(() {
-    //   if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
-    //     if (_amountToSend == null) {
-    //       setState(() {
-    //         _calculateFeesFuture = calculateFees(0);
-    //       });
-    //     } else {
-    //       setState(() {
-    //         _calculateFeesFuture =
-    //             calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
-    //       });
-    //     }
-    //   }
-    // });
-    //
-    // _baseFocus.addListener(() {
-    //   if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
-    //     if (_amountToSend == null) {
-    //       setState(() {
-    //         _calculateFeesFuture = calculateFees(0);
-    //       });
-    //     } else {
-    //       setState(() {
-    //         _calculateFeesFuture =
-    //             calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
-    //       });
-    //     }
-    //   }
-    // });
+    _cryptoFocus.addListener(() {
+      if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
+        if (_amountToSend == null) {
+          ref.refresh(sendAmountProvider);
+        } else {
+          ref.read(sendAmountProvider.state).state = _amountToSend!;
+        }
+      }
+    });
+
+    _baseFocus.addListener(() {
+      if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
+        if (_amountToSend == null) {
+          ref.refresh(sendAmountProvider);
+        } else {
+          ref.read(sendAmountProvider.state).state = _amountToSend!;
+        }
+      }
+    });
 
     super.initState();
   }
@@ -1371,6 +1357,24 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             ),
           ),
         ),
+        const SizedBox(
+          height: 20,
+        ),
+        Text(
+          "Transaction fee (estimated)",
+          style: STextStyles.desktopTextExtraSmall(context).copyWith(
+            color: Theme.of(context)
+                .extension<StackColors>()!
+                .textFieldActiveSearchIconRight,
+          ),
+          textAlign: TextAlign.left,
+        ),
+        const SizedBox(
+          height: 10,
+        ),
+        DesktopFeeDropDown(
+          walletId: walletId,
+        ),
         const SizedBox(
           height: 36,
         ),

From aead30504e36b2ceb7ad42dbb56ab50bb6945f14 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 14:12:55 -0700
Subject: [PATCH 258/426] alignment for settings pages icons

---
 assets/svg/configuration.svg                  |  11 +
 .../desktop_address_book.dart                 |   4 +-
 .../advanced_settings/advanced_settings.dart  |  11 +-
 .../settings_menu/appearance_settings.dart    |  11 +-
 .../currency_settings/currency_settings.dart  |  25 +-
 .../language_settings/language_settings.dart  |  11 +-
 .../home/settings_menu/nodes_settings.dart    |  11 +-
 .../home/settings_menu/security_settings.dart | 765 +++++++++---------
 .../syncing_preferences_settings.dart         |  14 +-
 lib/utilities/assets.dart                     |   1 +
 pubspec.yaml                                  |   1 +
 11 files changed, 442 insertions(+), 423 deletions(-)
 create mode 100644 assets/svg/configuration.svg

diff --git a/assets/svg/configuration.svg b/assets/svg/configuration.svg
new file mode 100644
index 000000000..516bbf320
--- /dev/null
+++ b/assets/svg/configuration.svg
@@ -0,0 +1,11 @@
+<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="48" height="48" rx="24" fill="#E0E3E3"/>
+<g clip-path="url(#clip0_5813_29086)">
+<path d="M13.5 30.5625C13.5 29.8365 14.0878 29.25 14.8125 29.25H17.0544C17.5605 28.0893 18.7172 27.2812 20.0625 27.2812C21.4078 27.2812 22.5275 28.0893 23.0689 29.25H33.1875C33.9135 29.25 34.5 29.8365 34.5 30.5625C34.5 31.2885 33.9135 31.875 33.1875 31.875H23.0689C22.5275 33.0357 21.4078 33.8438 20.0625 33.8438C18.7172 33.8438 17.5605 33.0357 17.0544 31.875H14.8125C14.0878 31.875 13.5 31.2885 13.5 30.5625ZM21.375 30.5625C21.375 29.8365 20.7885 29.25 20.0625 29.25C19.3365 29.25 18.75 29.8365 18.75 30.5625C18.75 31.2885 19.3365 31.875 20.0625 31.875C20.7885 31.875 21.375 31.2885 21.375 30.5625ZM27.9375 20.7188C29.2828 20.7188 30.4025 21.5268 30.9439 22.6875H33.1875C33.9135 22.6875 34.5 23.274 34.5 24C34.5 24.726 33.9135 25.3125 33.1875 25.3125H30.9439C30.4025 26.4732 29.2828 27.2812 27.9375 27.2812C26.5922 27.2812 25.4355 26.4732 24.9311 25.3125H14.8125C14.0878 25.3125 13.5 24.726 13.5 24C13.5 23.274 14.0878 22.6875 14.8125 22.6875H24.9311C25.4355 21.5268 26.5922 20.7188 27.9375 20.7188ZM29.25 24C29.25 23.274 28.6635 22.6875 27.9375 22.6875C27.2115 22.6875 26.625 23.274 26.625 24C26.625 24.726 27.2115 25.3125 27.9375 25.3125C28.6635 25.3125 29.25 24.726 29.25 24ZM33.1875 16.125C33.9135 16.125 34.5 16.7128 34.5 17.4375C34.5 18.1635 33.9135 18.75 33.1875 18.75H24.3814C23.84 19.9107 22.7203 20.7188 21.375 20.7188C20.0297 20.7188 18.873 19.9107 18.3686 18.75H14.8125C14.0878 18.75 13.5 18.1635 13.5 17.4375C13.5 16.7128 14.0878 16.125 14.8125 16.125H18.3686C18.873 14.9663 20.0297 14.1562 21.375 14.1562C22.7203 14.1562 23.84 14.9663 24.3814 16.125H33.1875ZM20.0625 17.4375C20.0625 18.1635 20.649 18.75 21.375 18.75C22.101 18.75 22.6875 18.1635 22.6875 17.4375C22.6875 16.7128 22.101 16.125 21.375 16.125C20.649 16.125 20.0625 16.7128 20.0625 17.4375Z" fill="black"/>
+</g>
+<defs>
+<clipPath id="clip0_5813_29086">
+<rect width="21" height="21" fill="white" transform="translate(13.5 13.5)"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index 475650722..407ed9897 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -239,8 +239,8 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
             ),
           ),
         ),
-        Padding(
-          padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 26),
+        const Padding(
+          padding: EdgeInsets.symmetric(horizontal: 24, vertical: 26),
           child: SizedBox(
             width: 489,
             child: AddressBookView(),
diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
index 8e89e3f67..0991a14ca 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
@@ -35,10 +35,13 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
-                SvgPicture.asset(
-                  Assets.svg.circleLanguage,
-                  width: 48,
-                  height: 48,
+                Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: SvgPicture.asset(
+                    Assets.svg.circleSliders,
+                    width: 48,
+                    height: 48,
+                  ),
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.stretch,
diff --git a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
index bf6fc81e2..27a10ca80 100644
--- a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
@@ -52,10 +52,13 @@ class _AppearanceOptionSettings
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
-                SvgPicture.asset(
-                  Assets.svg.circleSun,
-                  width: 48,
-                  height: 48,
+                Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: SvgPicture.asset(
+                    Assets.svg.circleSun,
+                    width: 48,
+                    height: 48,
+                  ),
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.stretch,
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index dab613f63..b1581d971 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -32,10 +32,13 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
-                SvgPicture.asset(
-                  Assets.svg.circleDollarSign,
-                  width: 48,
-                  height: 48,
+                Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: SvgPicture.asset(
+                    Assets.svg.circleDollarSign,
+                    width: 48,
+                    height: 48,
+                  ),
                 ),
                 Center(
                   child: Padding(
@@ -67,7 +70,7 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
                       padding: EdgeInsets.all(
                         10,
                       ),
-                      child: NewPasswordButton(),
+                      child: changeCurrency(),
                     ),
                   ],
                 ),
@@ -80,19 +83,11 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
   }
 }
 
-class NewPasswordButton extends ConsumerWidget {
-  const NewPasswordButton({
+class changeCurrency extends ConsumerWidget {
+  const changeCurrency({
     Key? key,
   }) : super(key: key);
   Future<void> chooseCurrency(BuildContext context) async {
-    // await showDialog<dynamic>(
-    //   context: context,
-    //   useSafeArea: false,
-    //   barrierDismissible: true,
-    //   builder: (context) {
-    //     return CurrencyDialog();
-    //   },
-    // );
     await showDialog<dynamic>(
       context: context,
       useSafeArea: false,
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
index 0f66d7dd5..2047d4eff 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
@@ -31,10 +31,13 @@ class _LanguageOptionSettings extends ConsumerState<LanguageOptionSettings> {
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
-                SvgPicture.asset(
-                  Assets.svg.circleLanguage,
-                  width: 48,
-                  height: 48,
+                Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: SvgPicture.asset(
+                    Assets.svg.circleLanguage,
+                    width: 48,
+                    height: 48,
+                  ),
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.stretch,
diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index 2343e3990..0f539f9f3 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -79,10 +79,13 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
               crossAxisAlignment: CrossAxisAlignment.start,
               mainAxisSize: MainAxisSize.min,
               children: [
-                SvgPicture.asset(
-                  Assets.svg.circleNode,
-                  width: 48,
-                  height: 48,
+                Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: SvgPicture.asset(
+                    Assets.svg.circleNode,
+                    width: 48,
+                    height: 48,
+                  ),
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.stretch,
diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index d752ece38..01a6c9c9b 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -139,392 +139,389 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
     debugPrint("BUILD: $runtimeType");
     return Column(
       children: [
-        Row(
-          children: [
-            Expanded(
-              child: RoundedWhiteContainer(
-                radiusMultiplier: 2,
-                padding: const EdgeInsets.all(24),
-                child: Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
-                    SvgPicture.asset(
-                      Assets.svg.circleLock,
-                      width: 48,
-                      height: 48,
-                    ),
-                    Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        Text(
-                          "Change Password",
-                          style: STextStyles.desktopTextSmall(context),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        Text(
-                          "Protect your Stack Wallet with a strong password. Stack Wallet does not store "
-                          "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
-                          style:
-                              STextStyles.desktopTextExtraExtraSmall(context),
-                        ),
-                        const SizedBox(
-                          height: 20,
-                        ),
-                        changePassword
-                            ? SizedBox(
-                                width: 512,
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Current password",
-                                      style: STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark3),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    const SizedBox(height: 10),
-                                    ClipRRect(
-                                      borderRadius: BorderRadius.circular(
-                                        Constants.size.circularBorderRadius,
-                                      ),
-                                      child: TextField(
-                                        key: const Key(
-                                            "desktopSecurityRestoreFromFilePasswordFieldKey"),
-                                        focusNode: passwordCurrentFocusNode,
-                                        controller: passwordCurrentController,
-                                        style: STextStyles.field(context),
-                                        obscureText: hidePassword,
-                                        enableSuggestions: false,
-                                        autocorrect: false,
-                                        decoration: standardInputDecoration(
-                                          "Enter current password",
-                                          passwordCurrentFocusNode,
-                                          context,
-                                        ).copyWith(
-                                          labelStyle:
-                                              STextStyles.fieldLabel(context),
-                                          suffixIcon: UnconstrainedBox(
-                                            child: Row(
-                                              children: [
-                                                const SizedBox(
-                                                  width: 16,
-                                                ),
-                                                GestureDetector(
-                                                  key: const Key(
-                                                      "desktopSecurityRestoreFromFilePasswordFieldShowPasswordButtonKey"),
-                                                  onTap: () async {
-                                                    setState(() {
-                                                      hidePassword =
-                                                          !hidePassword;
-                                                    });
-                                                  },
-                                                  child: SvgPicture.asset(
-                                                    hidePassword
-                                                        ? Assets.svg.eye
-                                                        : Assets.svg.eyeSlash,
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark3,
-                                                    width: 16,
-                                                    height: 16,
-                                                  ),
-                                                ),
-                                                const SizedBox(
-                                                  width: 12,
-                                                ),
-                                              ],
-                                            ),
-                                          ),
-                                        ),
-                                        onChanged: (newValue) {
-                                          setState(() {});
-                                        },
-                                      ),
-                                    ),
-                                    const SizedBox(height: 16),
-                                    Text(
-                                      "New password",
-                                      style: STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark3),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    const SizedBox(height: 10),
-                                    ClipRRect(
-                                      borderRadius: BorderRadius.circular(
-                                        Constants.size.circularBorderRadius,
-                                      ),
-                                      child: TextField(
-                                        key: const Key(
-                                            "desktopSecurityCreateNewPasswordFieldKey1"),
-                                        focusNode: passwordFocusNode,
-                                        controller: passwordController,
-                                        style: STextStyles.field(context),
-                                        obscureText: hidePassword,
-                                        enableSuggestions: false,
-                                        autocorrect: false,
-                                        decoration: standardInputDecoration(
-                                          "Enter new password",
-                                          passwordFocusNode,
-                                          context,
-                                        ).copyWith(
-                                          labelStyle:
-                                              STextStyles.fieldLabel(context),
-                                          suffixIcon: UnconstrainedBox(
-                                            child: Row(
-                                              children: [
-                                                const SizedBox(
-                                                  width: 16,
-                                                ),
-                                                GestureDetector(
-                                                  key: const Key(
-                                                      "desktopSecurityCreateNewPasswordButtonKey1"),
-                                                  onTap: () async {
-                                                    setState(() {
-                                                      hidePassword =
-                                                          !hidePassword;
-                                                    });
-                                                  },
-                                                  child: SvgPicture.asset(
-                                                    hidePassword
-                                                        ? Assets.svg.eye
-                                                        : Assets.svg.eyeSlash,
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark3,
-                                                    width: 16,
-                                                    height: 16,
-                                                  ),
-                                                ),
-                                                const SizedBox(
-                                                  width: 12,
-                                                ),
-                                              ],
-                                            ),
-                                          ),
-                                        ),
-                                        onChanged: (newValue) {
-                                          if (newValue.isEmpty) {
-                                            setState(() {
-                                              passwordFeedback = "";
-                                            });
-                                            return;
-                                          }
-                                          final result =
-                                              zxcvbn.evaluate(newValue);
-                                          String suggestionsAndTips = "";
-                                          for (var sug in result
-                                              .feedback.suggestions!
-                                              .toSet()) {
-                                            suggestionsAndTips += "$sug\n";
-                                          }
-                                          suggestionsAndTips +=
-                                              result.feedback.warning!;
-                                          String feedback =
-                                              // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
-                                              suggestionsAndTips;
-
-                                          passwordStrength = result.score! / 4;
-
-                                          // hack fix to format back string returned from zxcvbn
-                                          if (feedback
-                                              .contains("phrasesNo need")) {
-                                            feedback = feedback.replaceFirst(
-                                                "phrasesNo need",
-                                                "phrases\nNo need");
-                                          }
-
-                                          if (feedback.endsWith("\n")) {
-                                            feedback = feedback.substring(
-                                                0, feedback.length - 2);
-                                          }
-
-                                          setState(() {
-                                            passwordFeedback = feedback;
-                                          });
-                                        },
-                                      ),
-                                    ),
-                                    if (passwordFocusNode.hasFocus ||
-                                        passwordRepeatFocusNode.hasFocus ||
-                                        passwordController.text.isNotEmpty)
-                                      Padding(
-                                        padding: EdgeInsets.only(
-                                          left: 12,
-                                          right: 12,
-                                          top: passwordFeedback.isNotEmpty
-                                              ? 4
-                                              : 0,
-                                        ),
-                                        child: passwordFeedback.isNotEmpty
-                                            ? Text(
-                                                passwordFeedback,
-                                                style: STextStyles.infoSmall(
-                                                    context),
-                                              )
-                                            : null,
-                                      ),
-                                    if (passwordFocusNode.hasFocus ||
-                                        passwordRepeatFocusNode.hasFocus ||
-                                        passwordController.text.isNotEmpty)
-                                      Padding(
-                                        padding: const EdgeInsets.only(
-                                          left: 12,
-                                          right: 12,
-                                          top: 10,
-                                        ),
-                                        child: ProgressBar(
-                                          key: const Key(
-                                              "desktopSecurityCreateStackBackUpProgressBar"),
-                                          width: 450,
-                                          height: 5,
-                                          fillColor: passwordStrength < 0.51
-                                              ? Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .accentColorRed
-                                              : passwordStrength < 1
-                                                  ? Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .accentColorYellow
-                                                  : Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .accentColorGreen,
-                                          backgroundColor: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .buttonBackSecondary,
-                                          percent: passwordStrength < 0.25
-                                              ? 0.03
-                                              : passwordStrength,
-                                        ),
-                                      ),
-                                    const SizedBox(height: 16),
-                                    Text(
-                                      "Confirm new password",
-                                      style: STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark3),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    const SizedBox(height: 10),
-                                    ClipRRect(
-                                      borderRadius: BorderRadius.circular(
-                                        Constants.size.circularBorderRadius,
-                                      ),
-                                      child: TextField(
-                                        key: const Key(
-                                            "desktopSecurityCreateNewPasswordFieldKey2"),
-                                        focusNode: passwordRepeatFocusNode,
-                                        controller: passwordRepeatController,
-                                        style: STextStyles.field(context),
-                                        obscureText: hidePassword,
-                                        enableSuggestions: false,
-                                        autocorrect: false,
-                                        decoration: standardInputDecoration(
-                                          "Confirm new password",
-                                          passwordRepeatFocusNode,
-                                          context,
-                                        ).copyWith(
-                                          labelStyle:
-                                              STextStyles.fieldLabel(context),
-                                          suffixIcon: UnconstrainedBox(
-                                            child: Row(
-                                              children: [
-                                                const SizedBox(
-                                                  width: 16,
-                                                ),
-                                                GestureDetector(
-                                                  key: const Key(
-                                                      "desktopSecurityCreateNewPasswordButtonKey2"),
-                                                  onTap: () async {
-                                                    setState(() {
-                                                      hidePassword =
-                                                          !hidePassword;
-                                                    });
-                                                  },
-                                                  child: SvgPicture.asset(
-                                                    hidePassword
-                                                        ? Assets.svg.eye
-                                                        : Assets.svg.eyeSlash,
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark3,
-                                                    width: 16,
-                                                    height: 16,
-                                                  ),
-                                                ),
-                                                const SizedBox(
-                                                  width: 12,
-                                                ),
-                                              ],
-                                            ),
-                                          ),
-                                        ),
-                                        onChanged: (newValue) {
-                                          setState(() {});
-                                        },
-                                      ),
-                                    ),
-                                    const SizedBox(height: 20),
-                                    PrimaryButton(
-                                      width: 160,
-                                      desktopMed: true,
-                                      enabled: shouldEnableSave,
-                                      label: "Save changes",
-                                      onPressed: () async {
-                                        final didChangePW =
-                                            await attemptChangePW();
-                                        if (didChangePW) {
-                                          setState(() {
-                                            changePassword = false;
-                                          });
-                                        }
-                                      },
-                                    )
-                                  ],
-                                ),
-                              )
-                            : PrimaryButton(
-                                width: 210,
-                                desktopMed: true,
-                                enabled: true,
-                                label: "Set up new password",
-                                onPressed: () {
-                                  setState(() {
-                                    changePassword = true;
-                                  });
-                                },
-                              ),
-                      ],
-                    ),
-                  ],
+        Padding(
+          padding: const EdgeInsets.only(
+            right: 30,
+          ),
+          child: RoundedWhiteContainer(
+            // radiusMultiplier: 2,
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: SvgPicture.asset(
+                    Assets.svg.circleLock,
+                    width: 48,
+                    height: 48,
+                  ),
                 ),
-              ),
+                Padding(
+                  padding:
+                      const EdgeInsets.only(left: 10, right: 10, bottom: 10),
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      const SizedBox(
+                        height: 16,
+                      ),
+                      Text(
+                        "Change Password",
+                        style: STextStyles.desktopTextSmall(context),
+                      ),
+                      const SizedBox(
+                        height: 8,
+                      ),
+                      Text(
+                        "Protect your Stack Wallet with a strong password. Stack Wallet does not store "
+                        "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
+                        style: STextStyles.desktopTextExtraExtraSmall(context),
+                      ),
+                      const SizedBox(
+                        height: 20,
+                      ),
+                      changePassword
+                          ? SizedBox(
+                              width: 512,
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    "Current password",
+                                    style:
+                                        STextStyles.desktopTextExtraExtraSmall(
+                                                context)
+                                            .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark3),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                  const SizedBox(height: 10),
+                                  ClipRRect(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                    child: TextField(
+                                      key: const Key(
+                                          "desktopSecurityRestoreFromFilePasswordFieldKey"),
+                                      focusNode: passwordCurrentFocusNode,
+                                      controller: passwordCurrentController,
+                                      style: STextStyles.field(context),
+                                      obscureText: hidePassword,
+                                      enableSuggestions: false,
+                                      autocorrect: false,
+                                      decoration: standardInputDecoration(
+                                        "Enter current password",
+                                        passwordCurrentFocusNode,
+                                        context,
+                                      ).copyWith(
+                                        labelStyle:
+                                            STextStyles.fieldLabel(context),
+                                        suffixIcon: UnconstrainedBox(
+                                          child: Row(
+                                            children: [
+                                              const SizedBox(
+                                                width: 16,
+                                              ),
+                                              GestureDetector(
+                                                key: const Key(
+                                                    "desktopSecurityRestoreFromFilePasswordFieldShowPasswordButtonKey"),
+                                                onTap: () async {
+                                                  setState(() {
+                                                    hidePassword =
+                                                        !hidePassword;
+                                                  });
+                                                },
+                                                child: SvgPicture.asset(
+                                                  hidePassword
+                                                      ? Assets.svg.eye
+                                                      : Assets.svg.eyeSlash,
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark3,
+                                                  width: 16,
+                                                  height: 16,
+                                                ),
+                                              ),
+                                              const SizedBox(
+                                                width: 12,
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                      ),
+                                      onChanged: (newValue) {
+                                        setState(() {});
+                                      },
+                                    ),
+                                  ),
+                                  const SizedBox(height: 16),
+                                  Text(
+                                    "New password",
+                                    style:
+                                        STextStyles.desktopTextExtraExtraSmall(
+                                                context)
+                                            .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark3),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                  const SizedBox(height: 10),
+                                  ClipRRect(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                    child: TextField(
+                                      key: const Key(
+                                          "desktopSecurityCreateNewPasswordFieldKey1"),
+                                      focusNode: passwordFocusNode,
+                                      controller: passwordController,
+                                      style: STextStyles.field(context),
+                                      obscureText: hidePassword,
+                                      enableSuggestions: false,
+                                      autocorrect: false,
+                                      decoration: standardInputDecoration(
+                                        "Enter new password",
+                                        passwordFocusNode,
+                                        context,
+                                      ).copyWith(
+                                        labelStyle:
+                                            STextStyles.fieldLabel(context),
+                                        suffixIcon: UnconstrainedBox(
+                                          child: Row(
+                                            children: [
+                                              const SizedBox(
+                                                width: 16,
+                                              ),
+                                              GestureDetector(
+                                                key: const Key(
+                                                    "desktopSecurityCreateNewPasswordButtonKey1"),
+                                                onTap: () async {
+                                                  setState(() {
+                                                    hidePassword =
+                                                        !hidePassword;
+                                                  });
+                                                },
+                                                child: SvgPicture.asset(
+                                                  hidePassword
+                                                      ? Assets.svg.eye
+                                                      : Assets.svg.eyeSlash,
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark3,
+                                                  width: 16,
+                                                  height: 16,
+                                                ),
+                                              ),
+                                              const SizedBox(
+                                                width: 12,
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                      ),
+                                      onChanged: (newValue) {
+                                        if (newValue.isEmpty) {
+                                          setState(() {
+                                            passwordFeedback = "";
+                                          });
+                                          return;
+                                        }
+                                        final result =
+                                            zxcvbn.evaluate(newValue);
+                                        String suggestionsAndTips = "";
+                                        for (var sug in result
+                                            .feedback.suggestions!
+                                            .toSet()) {
+                                          suggestionsAndTips += "$sug\n";
+                                        }
+                                        suggestionsAndTips +=
+                                            result.feedback.warning!;
+                                        String feedback =
+                                            // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
+                                            suggestionsAndTips;
+
+                                        passwordStrength = result.score! / 4;
+
+                                        // hack fix to format back string returned from zxcvbn
+                                        if (feedback
+                                            .contains("phrasesNo need")) {
+                                          feedback = feedback.replaceFirst(
+                                              "phrasesNo need",
+                                              "phrases\nNo need");
+                                        }
+
+                                        if (feedback.endsWith("\n")) {
+                                          feedback = feedback.substring(
+                                              0, feedback.length - 2);
+                                        }
+
+                                        setState(() {
+                                          passwordFeedback = feedback;
+                                        });
+                                      },
+                                    ),
+                                  ),
+                                  if (passwordFocusNode.hasFocus ||
+                                      passwordRepeatFocusNode.hasFocus ||
+                                      passwordController.text.isNotEmpty)
+                                    Padding(
+                                      padding: EdgeInsets.only(
+                                        left: 12,
+                                        right: 12,
+                                        top:
+                                            passwordFeedback.isNotEmpty ? 4 : 0,
+                                      ),
+                                      child: passwordFeedback.isNotEmpty
+                                          ? Text(
+                                              passwordFeedback,
+                                              style: STextStyles.infoSmall(
+                                                  context),
+                                            )
+                                          : null,
+                                    ),
+                                  if (passwordFocusNode.hasFocus ||
+                                      passwordRepeatFocusNode.hasFocus ||
+                                      passwordController.text.isNotEmpty)
+                                    Padding(
+                                      padding: const EdgeInsets.only(
+                                        left: 12,
+                                        right: 12,
+                                        top: 10,
+                                      ),
+                                      child: ProgressBar(
+                                        key: const Key(
+                                            "desktopSecurityCreateStackBackUpProgressBar"),
+                                        width: 450,
+                                        height: 5,
+                                        fillColor: passwordStrength < 0.51
+                                            ? Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .accentColorRed
+                                            : passwordStrength < 1
+                                                ? Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .accentColorYellow
+                                                : Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .accentColorGreen,
+                                        backgroundColor: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .buttonBackSecondary,
+                                        percent: passwordStrength < 0.25
+                                            ? 0.03
+                                            : passwordStrength,
+                                      ),
+                                    ),
+                                  const SizedBox(height: 16),
+                                  Text(
+                                    "Confirm new password",
+                                    style:
+                                        STextStyles.desktopTextExtraExtraSmall(
+                                                context)
+                                            .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark3),
+                                    textAlign: TextAlign.left,
+                                  ),
+                                  const SizedBox(height: 10),
+                                  ClipRRect(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                    child: TextField(
+                                      key: const Key(
+                                          "desktopSecurityCreateNewPasswordFieldKey2"),
+                                      focusNode: passwordRepeatFocusNode,
+                                      controller: passwordRepeatController,
+                                      style: STextStyles.field(context),
+                                      obscureText: hidePassword,
+                                      enableSuggestions: false,
+                                      autocorrect: false,
+                                      decoration: standardInputDecoration(
+                                        "Confirm new password",
+                                        passwordRepeatFocusNode,
+                                        context,
+                                      ).copyWith(
+                                        labelStyle:
+                                            STextStyles.fieldLabel(context),
+                                        suffixIcon: UnconstrainedBox(
+                                          child: Row(
+                                            children: [
+                                              const SizedBox(
+                                                width: 16,
+                                              ),
+                                              GestureDetector(
+                                                key: const Key(
+                                                    "desktopSecurityCreateNewPasswordButtonKey2"),
+                                                onTap: () async {
+                                                  setState(() {
+                                                    hidePassword =
+                                                        !hidePassword;
+                                                  });
+                                                },
+                                                child: SvgPicture.asset(
+                                                  hidePassword
+                                                      ? Assets.svg.eye
+                                                      : Assets.svg.eyeSlash,
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark3,
+                                                  width: 16,
+                                                  height: 16,
+                                                ),
+                                              ),
+                                              const SizedBox(
+                                                width: 12,
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                      ),
+                                      onChanged: (newValue) {
+                                        setState(() {});
+                                      },
+                                    ),
+                                  ),
+                                  const SizedBox(height: 20),
+                                  PrimaryButton(
+                                    width: 160,
+                                    desktopMed: true,
+                                    enabled: shouldEnableSave,
+                                    label: "Save changes",
+                                    onPressed: () async {
+                                      final didChangePW =
+                                          await attemptChangePW();
+                                      if (didChangePW) {
+                                        setState(() {
+                                          changePassword = false;
+                                        });
+                                      }
+                                    },
+                                  )
+                                ],
+                              ),
+                            )
+                          : PrimaryButton(
+                              width: 210,
+                              desktopMed: true,
+                              enabled: true,
+                              label: "Set up new password",
+                              onPressed: () {
+                                setState(() {
+                                  changePassword = true;
+                                });
+                              },
+                            ),
+                    ],
+                  ),
+                ),
+              ],
             ),
-            const SizedBox(
-              width: 40,
-            ),
-          ],
+          ),
         ),
       ],
     );
diff --git a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
index 7f6aac260..618ee56da 100644
--- a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
@@ -2,13 +2,12 @@ import 'package:flutter/material.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import '../../../pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart';
-
 class SyncingPreferencesSettings extends ConsumerStatefulWidget {
   const SyncingPreferencesSettings({Key? key}) : super(key: key);
 
@@ -34,10 +33,13 @@ class _SyncingPreferencesSettings
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
-                SvgPicture.asset(
-                  Assets.svg.circleArrowRotate,
-                  width: 48,
-                  height: 48,
+                Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: SvgPicture.asset(
+                    Assets.svg.circleArrowRotate,
+                    width: 48,
+                    height: 48,
+                  ),
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.stretch,
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index e76a17c12..38d720969 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -59,6 +59,7 @@ class _SVG {
   String txExchangeFailed(BuildContext context) =>
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
 
+  String get circleSliders => "assets/svg/configuration.svg";
   String get circlePlus => "assets/svg/plus-circle.svg";
   String get framedGear => "assets/svg/framed-gear.svg";
   String get framedAddressBook => "assets/svg/framed-address-book.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index 10a00ff2e..bba5f6ed2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -315,6 +315,7 @@ flutter:
     - assets/svg/keys.svg
     - assets/svg/arrow-down.svg
     - assets/svg/plus-circle.svg
+    - assets/svg/configuration.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Litecoin.svg

From f11119119affc02e8a427dadac434f613669542d Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 14:32:44 -0700
Subject: [PATCH 259/426] changed all settings buttons to PrimaryButton

---
 .../currency_settings/currency_settings.dart  | 108 ++++++++----------
 .../language_settings/language_settings.dart  |  62 ++++------
 .../home/settings_menu/security_settings.dart |   8 +-
 .../syncing_preferences_settings.dart         |  35 ++----
 4 files changed, 79 insertions(+), 134 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index b1581d971..7ad8b38b9 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class CurrencySettings extends ConsumerStatefulWidget {
@@ -18,6 +19,41 @@ class CurrencySettings extends ConsumerStatefulWidget {
   ConsumerState<CurrencySettings> createState() => _CurrencySettings();
 }
 
+Future<void> chooseCurrency(BuildContext context) async {
+  await showDialog<dynamic>(
+    context: context,
+    useSafeArea: false,
+    barrierDismissible: true,
+    builder: (context) {
+      return DesktopDialog(
+        maxHeight: 800,
+        maxWidth: 600,
+        child: Column(
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.all(32),
+                  child: Text(
+                    "Select currency",
+                    style: STextStyles.desktopH3(context),
+                    textAlign: TextAlign.center,
+                  ),
+                ),
+                const DesktopDialogCloseButton(),
+              ],
+            ),
+            const Expanded(
+              child: BaseCurrencySettingsView(),
+            ),
+          ],
+        ),
+      );
+    },
+  );
+}
+
 class _CurrencySettings extends ConsumerState<CurrencySettings> {
   @override
   Widget build(BuildContext context) {
@@ -65,12 +101,20 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
+                  children: [
                     Padding(
                       padding: EdgeInsets.all(
                         10,
                       ),
-                      child: changeCurrency(),
+                      child: PrimaryButton(
+                        width: 210,
+                        desktopMed: true,
+                        enabled: true,
+                        label: "Change currency",
+                        onPressed: () {
+                          chooseCurrency(context);
+                        },
+                      ),
                     ),
                   ],
                 ),
@@ -82,63 +126,3 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
     );
   }
 }
-
-class changeCurrency extends ConsumerWidget {
-  const changeCurrency({
-    Key? key,
-  }) : super(key: key);
-  Future<void> chooseCurrency(BuildContext context) async {
-    await showDialog<dynamic>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: true,
-      builder: (context) {
-        return DesktopDialog(
-          maxHeight: 800,
-          maxWidth: 600,
-          child: Column(
-            children: [
-              Row(
-                mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                children: [
-                  Padding(
-                    padding: const EdgeInsets.all(32),
-                    child: Text(
-                      "Select currency",
-                      style: STextStyles.desktopH3(context),
-                      textAlign: TextAlign.center,
-                    ),
-                  ),
-                  const DesktopDialogCloseButton(),
-                ],
-              ),
-              const Expanded(
-                child: BaseCurrencySettingsView(),
-              ),
-            ],
-          ),
-        );
-      },
-    );
-  }
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {
-          chooseCurrency(context);
-        },
-        child: Text(
-          "Change currency",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
index 2047d4eff..96ce5cf61 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
@@ -4,7 +4,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class LanguageOptionSettings extends ConsumerStatefulWidget {
@@ -17,6 +17,17 @@ class LanguageOptionSettings extends ConsumerStatefulWidget {
       _LanguageOptionSettings();
 }
 
+Future<void> chooseLanguage(BuildContext context) async {
+  await showDialog<dynamic>(
+    context: context,
+    useSafeArea: false,
+    barrierDismissible: true,
+    builder: (context) {
+      return const LanguageDialog();
+    },
+  );
+}
+
 class _LanguageOptionSettings extends ConsumerState<LanguageOptionSettings> {
   @override
   Widget build(BuildContext context) {
@@ -66,12 +77,20 @@ class _LanguageOptionSettings extends ConsumerState<LanguageOptionSettings> {
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
+                  children: [
                     Padding(
                       padding: EdgeInsets.all(
                         10,
                       ),
-                      child: ChangeLanguageButton(),
+                      child: PrimaryButton(
+                        width: 210,
+                        desktopMed: true,
+                        enabled: true,
+                        label: "Change language",
+                        onPressed: () {
+                          chooseLanguage(context);
+                        },
+                      ),
                     ),
                   ],
                 ),
@@ -83,40 +102,3 @@ class _LanguageOptionSettings extends ConsumerState<LanguageOptionSettings> {
     );
   }
 }
-
-class ChangeLanguageButton extends ConsumerWidget {
-  const ChangeLanguageButton({
-    Key? key,
-  }) : super(key: key);
-
-  Future<void> chooseLanguage(BuildContext context) async {
-    await showDialog<dynamic>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: true,
-      builder: (context) {
-        return const LanguageDialog();
-      },
-    );
-  }
-
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {
-          chooseLanguage(context);
-        },
-        child: Text(
-          "Change language",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}
diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index 01a6c9c9b..de3505ace 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -157,20 +157,16 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
                   ),
                 ),
                 Padding(
-                  padding:
-                      const EdgeInsets.only(left: 10, right: 10, bottom: 10),
+                  padding: const EdgeInsets.all(10),
                   child: Column(
                     crossAxisAlignment: CrossAxisAlignment.start,
                     children: [
-                      const SizedBox(
-                        height: 16,
-                      ),
                       Text(
                         "Change Password",
                         style: STextStyles.desktopTextSmall(context),
                       ),
                       const SizedBox(
-                        height: 8,
+                        height: 16,
                       ),
                       Text(
                         "Protect your Stack Wallet with a strong password. Stack Wallet does not store "
diff --git a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
index 618ee56da..b245f8d43 100644
--- a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
@@ -5,7 +5,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class SyncingPreferencesSettings extends ConsumerStatefulWidget {
@@ -75,12 +75,18 @@ class _SyncingPreferencesSettings
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
-                  children: const [
+                  children: [
                     Padding(
                       padding: EdgeInsets.all(
                         10,
                       ),
-                      child: ChangePrefButton(),
+                      child: PrimaryButton(
+                        width: 210,
+                        desktopMed: true,
+                        enabled: true,
+                        label: "Change preferences",
+                        onPressed: () {},
+                      ),
                     ),
                   ],
                 ),
@@ -92,26 +98,3 @@ class _SyncingPreferencesSettings
     );
   }
 }
-
-class ChangePrefButton extends ConsumerWidget {
-  const ChangePrefButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    return SizedBox(
-      width: 200,
-      height: 48,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {},
-        child: Text(
-          "Change preferences",
-          style: STextStyles.button(context),
-        ),
-      ),
-    );
-  }
-}

From 1afc468d28b0ed4b8775a9692a848728c4a4e401 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 15:41:55 -0600
Subject: [PATCH 260/426] desktop nodes scroll layout fix

---
 .../home/settings_menu/nodes_settings.dart    | 395 +++++++++---------
 1 file changed, 198 insertions(+), 197 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index 0f539f9f3..e9417d2a7 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -2,8 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
-import 'package:stackwallet/providers/global/node_service_provider.dart';
-import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
@@ -52,12 +51,15 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
   void dispose() {
     searchNodeController.dispose();
     searchNodeFocusNode.dispose();
+    nodeScrollController.dispose();
 
     super.dispose();
   }
 
   @override
   Widget build(BuildContext context) {
+    debugPrint("BUILD: $runtimeType");
+
     bool showTestNet = ref.watch(
       prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
     );
@@ -66,217 +68,216 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
         ? _coins
         : _coins.sublist(0, _coins.length - kTestNetCoinCount);
 
-    debugPrint("BUILD: $runtimeType");
-    return Column(
-      mainAxisSize: MainAxisSize.min,
+    return Row(
+      crossAxisAlignment: CrossAxisAlignment.start,
       children: [
-        Padding(
-          padding: const EdgeInsets.only(
-            right: 30,
-          ),
-          child: RoundedWhiteContainer(
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              mainAxisSize: MainAxisSize.min,
-              children: [
-                Padding(
-                  padding: const EdgeInsets.all(8.0),
-                  child: SvgPicture.asset(
-                    Assets.svg.circleNode,
-                    width: 48,
-                    height: 48,
-                  ),
-                ),
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.stretch,
-                  mainAxisSize: MainAxisSize.min,
-                  children: [
-                    Padding(
-                      padding: const EdgeInsets.all(10),
-                      child: RichText(
-                        textAlign: TextAlign.start,
-                        text: TextSpan(
-                          children: [
-                            TextSpan(
-                              text: "Nodes",
-                              style: STextStyles.desktopTextSmall(context),
-                            ),
-                            TextSpan(
-                              text: "\n\nSelect a coin to see nodes",
-                              style: STextStyles.desktopTextExtraExtraSmall(
-                                  context),
-                            ),
-                          ],
-                        ),
+        Expanded(
+          child: Padding(
+            padding: const EdgeInsets.only(
+              right: 32,
+              bottom: 32,
+            ),
+            child: RoundedWhiteContainer(
+              radiusMultiplier: 2,
+              padding: const EdgeInsets.all(24),
+              child: Column(
+                mainAxisSize: MainAxisSize.min,
+                children: [
+                  Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    mainAxisSize: MainAxisSize.min,
+                    children: [
+                      SvgPicture.asset(
+                        Assets.svg.circleNode,
+                        width: 48,
+                        height: 48,
                       ),
-                    ),
-                  ],
-                ),
-                Padding(
-                  padding: const EdgeInsets.all(10.0),
-                  child: ClipRRect(
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
-                    ),
-                    child: TextField(
-                      autocorrect: Util.isDesktop ? false : true,
-                      enableSuggestions: Util.isDesktop ? false : true,
-                      controller: searchNodeController,
-                      focusNode: searchNodeFocusNode,
-                      onChanged: (newString) {
-                        setState(() => filter = newString);
-                      },
-                      style: STextStyles.field(context),
-                      decoration: standardInputDecoration(
-                        "Search",
-                        searchNodeFocusNode,
-                        context,
-                      ).copyWith(
-                        prefixIcon: Padding(
-                          padding: const EdgeInsets.symmetric(
-                            horizontal: 10,
-                            vertical: 16,
-                          ),
-                          child: SvgPicture.asset(
-                            Assets.svg.search,
-                            width: 16,
-                            height: 16,
-                          ),
-                        ),
-                        suffixIcon: searchNodeController.text.isNotEmpty
-                            ? Padding(
-                                padding: const EdgeInsets.only(right: 0),
-                                child: UnconstrainedBox(
-                                  child: Row(
-                                    children: [
-                                      TextFieldIconButton(
-                                        child: const XIcon(),
-                                        onTap: () async {
-                                          setState(() {
-                                            searchNodeController.text = "";
-                                            filter = "";
-                                          });
-                                        },
-                                      ),
-                                    ],
-                                  ),
-                                ),
-                              )
-                            : null,
+                      const SizedBox(
+                        height: 16,
                       ),
-                    ),
-                  ),
-                ),
-                Padding(
-                  padding: const EdgeInsets.all(10.0),
-                  child: RoundedWhiteContainer(
-                    padding: const EdgeInsets.all(0),
-                    borderColor:
-                        Theme.of(context).extension<StackColors>()!.background,
-                    child: ListView.separated(
-                      controller: nodeScrollController,
-                      physics: const AlwaysScrollableScrollPhysics(),
-                      scrollDirection: Axis.vertical,
-                      primary: false,
-                      shrinkWrap: true,
-                      itemBuilder: (context, index) {
-                        final coin = coins[index];
-                        final count = ref
-                            .watch(nodeServiceChangeNotifierProvider
-                                .select((value) => value.getNodesFor(coin)))
-                            .length;
-
-                        return Padding(
-                          padding: const EdgeInsets.all(0),
-                          child: RawMaterialButton(
-                            // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                            shape: RoundedRectangleBorder(
-                              borderRadius: BorderRadius.circular(
-                                Constants.size.circularBorderRadius,
+                      Text(
+                        "Nodes",
+                        style: STextStyles.desktopTextSmall(context),
+                      ),
+                      const SizedBox(
+                        height: 8,
+                      ),
+                      Text(
+                        "Select a coin to see nodes",
+                        style: STextStyles.desktopTextExtraExtraSmall(context),
+                      ),
+                      const SizedBox(
+                        height: 20,
+                      ),
+                      ClipRRect(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                        child: TextField(
+                          autocorrect: Util.isDesktop ? false : true,
+                          enableSuggestions: Util.isDesktop ? false : true,
+                          controller: searchNodeController,
+                          focusNode: searchNodeFocusNode,
+                          onChanged: (newString) {
+                            setState(() => filter = newString);
+                          },
+                          style: STextStyles.field(context),
+                          decoration: standardInputDecoration(
+                            "Search",
+                            searchNodeFocusNode,
+                            context,
+                          ).copyWith(
+                            prefixIcon: Padding(
+                              padding: const EdgeInsets.symmetric(
+                                horizontal: 10,
+                                vertical: 16,
+                              ),
+                              child: SvgPicture.asset(
+                                Assets.svg.search,
+                                width: 16,
+                                height: 16,
                               ),
                             ),
-                            materialTapTargetSize:
-                                MaterialTapTargetSize.shrinkWrap,
-                            onPressed: () {
-                              showDialog<void>(
-                                context: context,
-                                builder: (context) => Navigator(
-                                  initialRoute: CoinNodesView.routeName,
-                                  onGenerateRoute: RouteGenerator.generateRoute,
-                                  onGenerateInitialRoutes: (_, __) {
-                                    return [
-                                      FadePageRoute(
-                                        CoinNodesView(
-                                          coin: coin,
-                                          rootNavigator: true,
-                                        ),
-                                        const RouteSettings(
-                                          name: CoinNodesView.routeName,
-                                        ),
-                                      ),
-                                    ];
-                                  },
-                                ),
-                              );
-                            },
-                            child: Padding(
-                              padding: const EdgeInsets.all(
-                                12.0,
-                              ),
-                              child: Row(
-                                children: [
-                                  Row(
-                                    children: [
-                                      SvgPicture.asset(
-                                        Assets.svg.iconFor(coin: coin),
-                                        width: 24,
-                                        height: 24,
-                                      ),
-                                      const SizedBox(
-                                        width: 12,
-                                      ),
-                                      Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
+                            suffixIcon: searchNodeController.text.isNotEmpty
+                                ? Padding(
+                                    padding: const EdgeInsets.only(right: 0),
+                                    child: UnconstrainedBox(
+                                      child: Row(
                                         children: [
-                                          Text(
-                                            "${coin.prettyName} nodes",
-                                            style: STextStyles.titleBold12(
-                                                context),
-                                          ),
-                                          Text(
-                                            count > 1
-                                                ? "$count nodes"
-                                                : "Default",
-                                            style: STextStyles.label(context),
+                                          TextFieldIconButton(
+                                            child: const XIcon(),
+                                            onTap: () async {
+                                              setState(() {
+                                                searchNodeController.text = "";
+                                                filter = "";
+                                              });
+                                            },
                                           ),
                                         ],
                                       ),
-                                    ],
-                                  ),
-                                  Expanded(
-                                    child: SvgPicture.asset(
-                                      Assets.svg.chevronRight,
-                                      alignment: Alignment.centerRight,
                                     ),
+                                  )
+                                : null,
+                          ),
+                        ),
+                      ),
+                    ],
+                  ),
+                  const SizedBox(
+                    height: 20,
+                  ),
+                  Flexible(
+                    child: RoundedWhiteContainer(
+                      padding: const EdgeInsets.all(0),
+                      borderColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .background,
+                      child: ListView.separated(
+                        controller: nodeScrollController,
+                        physics: const AlwaysScrollableScrollPhysics(),
+                        scrollDirection: Axis.vertical,
+                        primary: false,
+                        shrinkWrap: true,
+                        itemBuilder: (context, index) {
+                          final coin = coins[index];
+                          final count = ref
+                              .watch(nodeServiceChangeNotifierProvider
+                                  .select((value) => value.getNodesFor(coin)))
+                              .length;
+
+                          return Padding(
+                            padding: const EdgeInsets.all(0),
+                            child: RawMaterialButton(
+                              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                              shape: RoundedRectangleBorder(
+                                borderRadius: BorderRadius.circular(
+                                  Constants.size.circularBorderRadius,
+                                ),
+                              ),
+                              materialTapTargetSize:
+                                  MaterialTapTargetSize.shrinkWrap,
+                              onPressed: () {
+                                showDialog<void>(
+                                  context: context,
+                                  builder: (context) => Navigator(
+                                    initialRoute: CoinNodesView.routeName,
+                                    onGenerateRoute:
+                                        RouteGenerator.generateRoute,
+                                    onGenerateInitialRoutes: (_, __) {
+                                      return [
+                                        FadePageRoute(
+                                          CoinNodesView(
+                                            coin: coin,
+                                            rootNavigator: true,
+                                          ),
+                                          const RouteSettings(
+                                            name: CoinNodesView.routeName,
+                                          ),
+                                        ),
+                                      ];
+                                    },
                                   ),
-                                ],
+                                );
+                              },
+                              child: Padding(
+                                padding: const EdgeInsets.all(
+                                  12.0,
+                                ),
+                                child: Row(
+                                  children: [
+                                    Row(
+                                      children: [
+                                        SvgPicture.asset(
+                                          Assets.svg.iconFor(coin: coin),
+                                          width: 24,
+                                          height: 24,
+                                        ),
+                                        const SizedBox(
+                                          width: 12,
+                                        ),
+                                        Column(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            Text(
+                                              "${coin.prettyName} nodes",
+                                              style: STextStyles.titleBold12(
+                                                  context),
+                                            ),
+                                            Text(
+                                              count > 1
+                                                  ? "$count nodes"
+                                                  : "Default",
+                                              style: STextStyles.label(context),
+                                            ),
+                                          ],
+                                        ),
+                                      ],
+                                    ),
+                                    Expanded(
+                                      child: SvgPicture.asset(
+                                        Assets.svg.chevronRight,
+                                        alignment: Alignment.centerRight,
+                                      ),
+                                    ),
+                                  ],
+                                ),
                               ),
                             ),
-                          ),
-                        );
-                      },
-                      separatorBuilder: (context, index) => Container(
-                        height: 1,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .background,
+                          );
+                        },
+                        separatorBuilder: (context, index) => Container(
+                          height: 1,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                        ),
+                        itemCount: coins.length,
                       ),
-                      itemCount: coins.length,
                     ),
                   ),
-                ),
-              ],
+                ],
+              ),
             ),
           ),
         ),

From 6cfbeb180e69db1e46444211d0764efe26090105 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 15:51:53 -0600
Subject: [PATCH 261/426] desktop nodes search

---
 .../home/settings_menu/nodes_settings.dart         | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index e9417d2a7..012f7b47a 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -34,6 +34,18 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
 
   String filter = "";
 
+  List<Coin> _search(String filter, List<Coin> coins) {
+    if (filter.isEmpty) {
+      return coins;
+    }
+    return coins
+        .where((coin) =>
+            coin.prettyName.contains(filter) ||
+            coin.name.contains(filter) ||
+            coin.ticker.toLowerCase().contains(filter.toLowerCase()))
+        .toList();
+  }
+
   @override
   void initState() {
     _coins = _coins.toList();
@@ -68,6 +80,8 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
         ? _coins
         : _coins.sublist(0, _coins.length - kTestNetCoinCount);
 
+    coins = _search(filter, coins);
+
     return Row(
       crossAxisAlignment: CrossAxisAlignment.start,
       children: [

From a57651a766a2a5e77b3b1f5ca3ffcacd3f4dfb1d Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 14:53:27 -0700
Subject: [PATCH 262/426] layout fix + correct currency description

---
 .../settings_menu/currency_settings/currency_settings.dart  | 5 ++---
 .../home/settings_menu/syncing_preferences_settings.dart    | 6 +++---
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index 7ad8b38b9..ecc19ebb7 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -4,7 +4,6 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/currency_view.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
@@ -89,8 +88,8 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
                           ),
                           TextSpan(
                             text:
-                                "\n\nProtect your Stack Wallet with a strong password. Stack Wallet does not store "
-                                "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
+                                "\n\nSelect a fiat currency to evaluate your crypto assets. We use CoinGecko conversion rates "
+                                "when displaying your balance and transaction amounts.",
                             style:
                                 STextStyles.desktopTextExtraExtraSmall(context),
                           ),
diff --git a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
index b245f8d43..3d8bebb81 100644
--- a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
@@ -56,7 +56,7 @@ class _SyncingPreferencesSettings
                             ),
                             TextSpan(
                               text:
-                                  "\nSet up your syncing preferences for all wallets in your Stack.",
+                                  "\n\nSet up your syncing preferences for all wallets in your Stack.",
                               style: STextStyles.desktopTextExtraExtraSmall(
                                   context),
                             ),
@@ -69,7 +69,7 @@ class _SyncingPreferencesSettings
 
                 ///TODO: ONLY SHOW SYNC OPTIONS ON BUTTON PRESS
                 Column(
-                  children: [
+                  children: const [
                     SyncingOptionsView(),
                   ],
                 ),
@@ -77,7 +77,7 @@ class _SyncingPreferencesSettings
                   crossAxisAlignment: CrossAxisAlignment.start,
                   children: [
                     Padding(
-                      padding: EdgeInsets.all(
+                      padding: const EdgeInsets.all(
                         10,
                       ),
                       child: PrimaryButton(

From 824d8036789f0cbc1ba0b6ae5090554cf4ff2561 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 14:54:12 -0700
Subject: [PATCH 263/426] cursor on hover of wallet

---
 .../home/my_stack_view/my_wallets.dart                       | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/my_wallets.dart b/lib/pages_desktop_specific/home/my_stack_view/my_wallets.dart
index 550db293e..13170d07e 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/my_wallets.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/my_wallets.dart
@@ -53,7 +53,10 @@ class _MyWalletsState extends ConsumerState<MyWallets> {
             height: 20,
           ),
           const Expanded(
-            child: WalletSummaryTable(),
+            child: MouseRegion(
+              cursor: SystemMouseCursors.click,
+              child: WalletSummaryTable(),
+            ),
           ),
         ],
       ),

From 19d070c61832659d7971aa1b860c41df400f4a7b Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 15:00:07 -0700
Subject: [PATCH 264/426] send/receive pointer finger on hover

---
 .../sub_widgets/send_receive_tab_menu.dart    | 48 +++++++++++--------
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart
index 54dca9a4c..251e4f301 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart
@@ -48,16 +48,20 @@ class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
                   const SizedBox(
                     height: 16,
                   ),
-                  Text(
-                    "Send",
-                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                      color: _selectedIndex == 0
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .textSubtitle1,
+                  MouseRegion(
+                    cursor: SystemMouseCursors.click,
+                    child: Text(
+                      "Send",
+                      style:
+                          STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color: _selectedIndex == 0
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorBlue
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textSubtitle1,
+                      ),
                     ),
                   ),
                   const SizedBox(
@@ -90,16 +94,20 @@ class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
                   const SizedBox(
                     height: 16,
                   ),
-                  Text(
-                    "Receive",
-                    style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                      color: _selectedIndex == 1
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .textSubtitle1,
+                  MouseRegion(
+                    cursor: SystemMouseCursors.click,
+                    child: Text(
+                      "Receive",
+                      style:
+                          STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color: _selectedIndex == 1
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorBlue
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .textSubtitle1,
+                      ),
                     ),
                   ),
                   const SizedBox(

From 15c51e32698c0436c672c832ac5c8b6adec609b8 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 16:21:52 -0600
Subject: [PATCH 265/426] support view buttons

---
 .../global_settings_view/support_view.dart    | 444 ++++++------------
 1 file changed, 145 insertions(+), 299 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/support_view.dart b/lib/pages/settings_views/global_settings_view/support_view.dart
index 20aeedf61..9c3c41296 100644
--- a/lib/pages/settings_views/global_settings_view/support_view.dart
+++ b/lib/pages/settings_views/global_settings_view/support_view.dart
@@ -17,14 +17,13 @@ class SupportView extends StatelessWidget {
   }) : super(key: key);
 
   static const String routeName = "/support";
-  final double iconSize = 28;
 
   @override
   Widget build(BuildContext context) {
-    final isDesktop = Util.isDesktop;
-
     debugPrint("BUILD: $runtimeType");
 
+    final isDesktop = Util.isDesktop;
+
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
@@ -64,321 +63,168 @@ class SupportView extends StatelessWidget {
               : const SizedBox(
                   height: 12,
                 ),
-          RoundedWhiteContainer(
-            padding: const EdgeInsets.all(0),
-            child: RawMaterialButton(
-              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-              shape: RoundedRectangleBorder(
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius,
-                ),
-              ),
-              onPressed: () {
-                if (!isDesktop) {
-                  launchUrl(
-                    Uri.parse("https://t.me/stackwallet"),
-                    mode: LaunchMode.externalApplication,
-                  );
-                }
-              },
-              child: Padding(
-                padding: const EdgeInsets.symmetric(
-                  horizontal: 12,
-                  vertical: 20,
-                ),
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  children: [
-                    Row(
-                      children: [
-                        SvgPicture.asset(
-                          Assets.socials.telegram,
-                          width: iconSize,
-                          height: iconSize,
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorDark,
-                        ),
-                        const SizedBox(
-                          width: 12,
-                        ),
-                        Text(
-                          "Telegram",
-                          style: STextStyles.titleBold12(context),
-                          textAlign: TextAlign.left,
-                        ),
-                      ],
-                    ),
-                    BlueTextButton(
-                      text: isDesktop ? "@stackwallet" : "",
-                      onTap: () {
-                        launchUrl(
-                          Uri.parse("https://t.me/stackwallet"),
-                          mode: LaunchMode.externalApplication,
-                        );
-                      },
-                    ),
-                  ],
-                ),
-              ),
-            ),
+          AboutItem(
+            linkUrl: "https://t.me/stackwallet",
+            label: "Telegram",
+            buttonText: "@stackwallet",
+            iconAsset: Assets.socials.telegram,
+            isDesktop: isDesktop,
           ),
           const SizedBox(
             height: 8,
           ),
-          RoundedWhiteContainer(
-            padding: const EdgeInsets.all(0),
-            child: RawMaterialButton(
-              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-              shape: RoundedRectangleBorder(
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius,
-                ),
-              ),
-              onPressed: () {
-                if (!isDesktop) {
-                  launchUrl(
-                    Uri.parse("https://discord.gg/RZMG3yUm"),
-                    mode: LaunchMode.externalApplication,
-                  );
-                }
-              },
-              child: Padding(
-                padding: const EdgeInsets.symmetric(
-                  horizontal: 12,
-                  vertical: 20,
-                ),
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  children: [
-                    Row(
-                      children: [
-                        SvgPicture.asset(
-                          Assets.socials.discord,
-                          width: iconSize,
-                          height: iconSize,
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorDark,
-                        ),
-                        const SizedBox(
-                          width: 12,
-                        ),
-                        Text(
-                          "Discord",
-                          style: STextStyles.titleBold12(context),
-                          textAlign: TextAlign.left,
-                        ),
-                      ],
-                    ),
-                    BlueTextButton(
-                      text: isDesktop ? "Stack Wallet" : "",
-                      onTap: () {
-                        launchUrl(
-                          Uri.parse(
-                              "https://discord.gg/RZMG3yUm"), //expired link?
-                          mode: LaunchMode.externalApplication,
-                        );
-                      },
-                    ),
-                  ],
-                ),
-              ),
-            ),
+          AboutItem(
+            linkUrl: "https://discord.gg/RZMG3yUm",
+            label: "Discord",
+            buttonText: "Stack Wallet",
+            iconAsset: Assets.socials.discord,
+            isDesktop: isDesktop,
           ),
           const SizedBox(
             height: 8,
           ),
-          RoundedWhiteContainer(
-            padding: const EdgeInsets.all(0),
-            child: RawMaterialButton(
-              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-              shape: RoundedRectangleBorder(
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius,
-                ),
-              ),
-              onPressed: () {
-                if (!isDesktop) {
-                  launchUrl(
-                    Uri.parse("https://www.reddit.com/r/stackwallet/"),
-                    mode: LaunchMode.externalApplication,
-                  );
-                }
-              },
-              child: Padding(
-                padding: const EdgeInsets.symmetric(
-                  horizontal: 12,
-                  vertical: 20,
-                ),
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  children: [
-                    Row(
-                      children: [
-                        SvgPicture.asset(
-                          Assets.socials.reddit,
-                          width: iconSize,
-                          height: iconSize,
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorDark,
-                        ),
-                        const SizedBox(
-                          width: 12,
-                        ),
-                        Text(
-                          "Reddit",
-                          style: STextStyles.titleBold12(context),
-                          textAlign: TextAlign.left,
-                        ),
-                      ],
-                    ),
-                    BlueTextButton(
-                      text: isDesktop ? "r/stackwallet" : "",
-                      onTap: () {
-                        launchUrl(
-                          Uri.parse("https://www.reddit.com/r/stackwallet/"),
-                          mode: LaunchMode.externalApplication,
-                        );
-                      },
-                    ),
-                  ],
-                ),
-              ),
-            ),
+          AboutItem(
+            linkUrl: "https://www.reddit.com/r/stackwallet/",
+            label: "Reddit",
+            buttonText: "r/stackwallet",
+            iconAsset: Assets.socials.reddit,
+            isDesktop: isDesktop,
           ),
           const SizedBox(
             height: 8,
           ),
-          RoundedWhiteContainer(
-            padding: const EdgeInsets.all(0),
-            child: RawMaterialButton(
-              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-              shape: RoundedRectangleBorder(
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius,
-                ),
-              ),
-              onPressed: () {
-                if (!isDesktop) {
-                  launchUrl(
-                    Uri.parse("https://twitter.com/stack_wallet"),
-                    mode: LaunchMode.externalApplication,
-                  );
-                }
-              },
-              child: Padding(
-                padding: const EdgeInsets.symmetric(
-                  horizontal: 12,
-                  vertical: 20,
-                ),
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  children: [
-                    Row(
-                      children: [
-                        SvgPicture.asset(
-                          Assets.socials.twitter,
-                          width: iconSize,
-                          height: iconSize,
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorDark,
-                        ),
-                        const SizedBox(
-                          width: 12,
-                        ),
-                        Text(
-                          "Twitter",
-                          style: STextStyles.titleBold12(context),
-                          textAlign: TextAlign.left,
-                        ),
-                      ],
-                    ),
-                    BlueTextButton(
-                      text: isDesktop ? "@stack_wallet" : "",
-                      onTap: () {
-                        launchUrl(
-                          Uri.parse("https://twitter.com/stack_wallet"),
-                          mode: LaunchMode.externalApplication,
-                        );
-                      },
-                    ),
-                  ],
-                ),
-              ),
-            ),
+          AboutItem(
+            linkUrl: "https://twitter.com/stack_wallet",
+            label: "Twitter",
+            buttonText: "@stack_wallet",
+            iconAsset: Assets.socials.twitter,
+            isDesktop: isDesktop,
           ),
           const SizedBox(
             height: 8,
           ),
-          RoundedWhiteContainer(
-            padding: const EdgeInsets.all(0),
-            child: RawMaterialButton(
-              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-              materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-              shape: RoundedRectangleBorder(
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius,
-                ),
-              ),
-              onPressed: () {
-                if (!isDesktop) {
-                  launchUrl(
-                    Uri.parse("mailto://support@stackwallet.com"),
-                    mode: LaunchMode.externalApplication,
-                  );
-                }
-              },
-              child: Padding(
-                padding: const EdgeInsets.symmetric(
-                  horizontal: 12,
-                  vertical: 20,
-                ),
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  children: [
-                    Row(
-                      children: [
-                        SvgPicture.asset(
-                          Assets.svg.envelope,
-                          width: iconSize,
-                          height: iconSize,
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorDark,
-                        ),
-                        const SizedBox(
-                          width: 12,
-                        ),
-                        Text(
-                          "Email",
-                          style: STextStyles.titleBold12(context),
-                          textAlign: TextAlign.left,
-                        ),
-                      ],
-                    ),
-                    BlueTextButton(
-                      text: isDesktop ? "support@stackwallet.com" : "",
-                      onTap: () {
-                        launchUrl(
-                          Uri.parse("mailto://support@stackwallet.com"),
-                          mode: LaunchMode.externalApplication,
-                        );
-                      },
-                    ),
-                  ],
-                ),
-              ),
-            ),
+          AboutItem(
+            linkUrl: "mailto://support@stackwallet.com",
+            label: "Email",
+            buttonText: "support@stackwallet.com",
+            iconAsset: Assets.svg.envelope,
+            isDesktop: isDesktop,
           ),
         ],
       ),
     );
   }
 }
+
+class AboutItem extends StatelessWidget {
+  const AboutItem({
+    Key? key,
+    required this.linkUrl,
+    required this.label,
+    required this.buttonText,
+    required this.iconAsset,
+    required this.isDesktop,
+  }) : super(key: key);
+
+  final String linkUrl;
+  final String label;
+  final String buttonText;
+  final String iconAsset;
+  final bool isDesktop;
+
+  @override
+  Widget build(BuildContext context) {
+    final double iconSize = isDesktop ? 20 : 28;
+
+    return RoundedWhiteContainer(
+      padding: const EdgeInsets.all(0),
+      child: ConditionalParent(
+        condition: !isDesktop,
+        builder: (child) => RawMaterialButton(
+          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+          ),
+          onPressed: () {
+            launchUrl(
+              Uri.parse(linkUrl),
+              mode: LaunchMode.externalApplication,
+            );
+          },
+          child: Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 12,
+              vertical: 20,
+            ),
+            child: child,
+          ),
+        ),
+        child: Padding(
+          padding: isDesktop
+              ? const EdgeInsets.symmetric(
+                  horizontal: 20,
+                  vertical: 15,
+                )
+              : const EdgeInsets.symmetric(
+                  horizontal: 12,
+                  vertical: 20,
+                ),
+          child: Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Row(
+                children: [
+                  ConditionalParent(
+                    condition: isDesktop,
+                    builder: (child) => Container(
+                      width: 40,
+                      height: 40,
+                      decoration: BoxDecoration(
+                        borderRadius: BorderRadius.circular(10000),
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .buttonBackSecondary,
+                      ),
+                      child: Center(
+                        child: child,
+                      ),
+                    ),
+                    child: SvgPicture.asset(
+                      iconAsset,
+                      width: iconSize,
+                      height: iconSize,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .bottomNavIconIcon,
+                    ),
+                  ),
+                  const SizedBox(
+                    width: 12,
+                  ),
+                  Text(
+                    label,
+                    style: STextStyles.titleBold12(context),
+                    textAlign: TextAlign.left,
+                  ),
+                ],
+              ),
+              if (isDesktop)
+                BlueTextButton(
+                  text: buttonText,
+                  onTap: () {
+                    launchUrl(
+                      Uri.parse(linkUrl),
+                      mode: LaunchMode.externalApplication,
+                    );
+                  },
+                ),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}

From 3eae7d0fabccca7e96715eeebf23567b9084e6ac Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 15:22:45 -0700
Subject: [PATCH 266/426] password eye icon pointer cursor

---
 .../create_password/create_password_view.dart | 56 ++++++++++---------
 .../desktop_login_view.dart                   | 21 ++++---
 2 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/lib/pages_desktop_specific/create_password/create_password_view.dart b/lib/pages_desktop_specific/create_password/create_password_view.dart
index c29fc3de6..8e752f508 100644
--- a/lib/pages_desktop_specific/create_password/create_password_view.dart
+++ b/lib/pages_desktop_specific/create_password/create_password_view.dart
@@ -203,15 +203,18 @@ class _CreatePasswordViewState extends ConsumerState<CreatePasswordView> {
                                       height: 32,
                                       width: 32,
                                       child: Center(
-                                        child: SvgPicture.asset(
-                                          hidePassword
-                                              ? Assets.svg.eye
-                                              : Assets.svg.eyeSlash,
-                                          color: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .textDark3,
-                                          width: 24,
-                                          height: 19,
+                                        child: MouseRegion(
+                                          cursor: SystemMouseCursors.click,
+                                          child: SvgPicture.asset(
+                                            hidePassword
+                                                ? Assets.svg.eye
+                                                : Assets.svg.eyeSlash,
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark3,
+                                            width: 24,
+                                            height: 19,
+                                          ),
                                         ),
                                       ),
                                     ),
@@ -354,22 +357,25 @@ class _CreatePasswordViewState extends ConsumerState<CreatePasswordView> {
                                       height: 32,
                                       width: 32,
                                       child: Center(
-                                        child: SvgPicture.asset(
-                                          fieldsMatch && passwordStrength == 1
-                                              ? Assets.svg.checkCircle
-                                              : hidePassword
-                                                  ? Assets.svg.eye
-                                                  : Assets.svg.eyeSlash,
-                                          color: fieldsMatch &&
-                                                  passwordStrength == 1
-                                              ? Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .accentColorGreen
-                                              : Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark3,
-                                          width: 24,
-                                          height: 19,
+                                        child: MouseRegion(
+                                          cursor: SystemMouseCursors.click,
+                                          child: SvgPicture.asset(
+                                            fieldsMatch && passwordStrength == 1
+                                                ? Assets.svg.checkCircle
+                                                : hidePassword
+                                                    ? Assets.svg.eye
+                                                    : Assets.svg.eyeSlash,
+                                            color: fieldsMatch &&
+                                                    passwordStrength == 1
+                                                ? Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .accentColorGreen
+                                                : Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark3,
+                                            width: 24,
+                                            height: 19,
+                                          ),
                                         ),
                                       ),
                                     ),
diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index 363c1fb0d..ebd1c334b 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -175,15 +175,18 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
                                     hidePassword = !hidePassword;
                                   });
                                 },
-                                child: SvgPicture.asset(
-                                  hidePassword
-                                      ? Assets.svg.eye
-                                      : Assets.svg.eyeSlash,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark3,
-                                  width: 24,
-                                  height: 24,
+                                child: MouseRegion(
+                                  cursor: SystemMouseCursors.click,
+                                  child: SvgPicture.asset(
+                                    hidePassword
+                                        ? Assets.svg.eye
+                                        : Assets.svg.eyeSlash,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark3,
+                                    width: 24,
+                                    height: 24,
+                                  ),
                                 ),
                               ),
                               const SizedBox(

From 1818b00ac66c25cb099cb0d3a72a3cfce6c7dcd1 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 16:29:12 -0600
Subject: [PATCH 267/426] slightly adjust mouse region

---
 .../sub_widgets/send_receive_tab_menu.dart    | 112 +++++++++---------
 1 file changed, 56 insertions(+), 56 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart
index 251e4f301..b2f6156c2 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart
@@ -39,18 +39,18 @@ class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
     return Row(
       children: [
         Expanded(
-          child: GestureDetector(
-            onTap: () => _onChanged(0),
-            child: Container(
-              color: Colors.transparent,
-              child: Column(
-                children: [
-                  const SizedBox(
-                    height: 16,
-                  ),
-                  MouseRegion(
-                    cursor: SystemMouseCursors.click,
-                    child: Text(
+          child: MouseRegion(
+            cursor: SystemMouseCursors.click,
+            child: GestureDetector(
+              onTap: () => _onChanged(0),
+              child: Container(
+                color: Colors.transparent,
+                child: Column(
+                  children: [
+                    const SizedBox(
+                      height: 16,
+                    ),
+                    Text(
                       "Send",
                       style:
                           STextStyles.desktopTextExtraSmall(context).copyWith(
@@ -63,40 +63,40 @@ class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
                                 .textSubtitle1,
                       ),
                     ),
-                  ),
-                  const SizedBox(
-                    height: 19,
-                  ),
-                  Container(
-                    height: 2,
-                    decoration: BoxDecoration(
-                      color: _selectedIndex == 0
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .background,
+                    const SizedBox(
+                      height: 19,
                     ),
-                  ),
-                ],
+                    Container(
+                      height: 2,
+                      decoration: BoxDecoration(
+                        color: _selectedIndex == 0
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorBlue
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .background,
+                      ),
+                    ),
+                  ],
+                ),
               ),
             ),
           ),
         ),
         Expanded(
-          child: GestureDetector(
-            onTap: () => _onChanged(1),
-            child: Container(
-              color: Colors.transparent,
-              child: Column(
-                children: [
-                  const SizedBox(
-                    height: 16,
-                  ),
-                  MouseRegion(
-                    cursor: SystemMouseCursors.click,
-                    child: Text(
+          child: MouseRegion(
+            cursor: SystemMouseCursors.click,
+            child: GestureDetector(
+              onTap: () => _onChanged(1),
+              child: Container(
+                color: Colors.transparent,
+                child: Column(
+                  children: [
+                    const SizedBox(
+                      height: 16,
+                    ),
+                    Text(
                       "Receive",
                       style:
                           STextStyles.desktopTextExtraSmall(context).copyWith(
@@ -109,23 +109,23 @@ class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
                                 .textSubtitle1,
                       ),
                     ),
-                  ),
-                  const SizedBox(
-                    height: 19,
-                  ),
-                  Container(
-                    height: 2,
-                    decoration: BoxDecoration(
-                      color: _selectedIndex == 1
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorBlue
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .background,
+                    const SizedBox(
+                      height: 19,
                     ),
-                  ),
-                ],
+                    Container(
+                      height: 2,
+                      decoration: BoxDecoration(
+                        color: _selectedIndex == 1
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorBlue
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .background,
+                      ),
+                    ),
+                  ],
+                ),
               ),
             ),
           ),

From b4488fceed20ab882992c2a331025a39b4174de7 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 15 Nov 2022 15:41:58 -0700
Subject: [PATCH 268/426] US spelling adjustment

---
 .../wallet_view/sub_widgets/network_info_button.dart          | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
index 59d20a9df..5195a4b9b 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
@@ -132,10 +132,10 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
         label = "Unable to sync";
         break;
       case WalletSyncStatus.synced:
-        label = "Synchronised";
+        label = "Synchronized";
         break;
       case WalletSyncStatus.syncing:
-        label = "Synchronising";
+        label = "Synchronizing";
         break;
     }
 

From 07cf1f3f92a304aa2ecd1c931454f0655ae7b951 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 16:44:23 -0600
Subject: [PATCH 269/426] Add MouseRegion to Expandable widget and clean up
 duplications

---
 .../home/my_stack_view/my_wallets.dart        |  5 +-
 lib/widgets/expandable.dart                   | 13 ++-
 lib/widgets/table_view/table_view.dart        |  3 +-
 .../wallet_info_row/wallet_info_row.dart      | 93 ++++++++++---------
 4 files changed, 59 insertions(+), 55 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/my_wallets.dart b/lib/pages_desktop_specific/home/my_stack_view/my_wallets.dart
index 13170d07e..550db293e 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/my_wallets.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/my_wallets.dart
@@ -53,10 +53,7 @@ class _MyWalletsState extends ConsumerState<MyWallets> {
             height: 20,
           ),
           const Expanded(
-            child: MouseRegion(
-              cursor: SystemMouseCursors.click,
-              child: WalletSummaryTable(),
-            ),
+            child: WalletSummaryTable(),
           ),
         ],
       ),
diff --git a/lib/widgets/expandable.dart b/lib/widgets/expandable.dart
index a0c2be5a4..47726d6d6 100644
--- a/lib/widgets/expandable.dart
+++ b/lib/widgets/expandable.dart
@@ -89,11 +89,14 @@ class _ExpandableState extends State<Expandable> with TickerProviderStateMixin {
     return Column(
       mainAxisSize: MainAxisSize.min,
       children: [
-        GestureDetector(
-          onTap: toggle,
-          child: Container(
-            color: Colors.transparent,
-            child: widget.header,
+        MouseRegion(
+          cursor: SystemMouseCursors.click,
+          child: GestureDetector(
+            onTap: toggle,
+            child: Container(
+              color: Colors.transparent,
+              child: widget.header,
+            ),
           ),
         ),
         SizeTransition(
diff --git a/lib/widgets/table_view/table_view.dart b/lib/widgets/table_view/table_view.dart
index 7e8693f0d..8c2d470bd 100644
--- a/lib/widgets/table_view/table_view.dart
+++ b/lib/widgets/table_view/table_view.dart
@@ -1,5 +1,4 @@
 import 'package:flutter/material.dart';
-import 'package:stackwallet/widgets/table_view/table_view_row.dart';
 
 class TableView extends StatefulWidget {
   const TableView({
@@ -9,7 +8,7 @@ class TableView extends StatefulWidget {
     this.shrinkWrap = false,
   }) : super(key: key);
 
-  final List<TableViewRow> rows;
+  final List<Widget> rows;
   final double rowSpacing;
   final bool shrinkWrap;
 
diff --git a/lib/widgets/wallet_info_row/wallet_info_row.dart b/lib/widgets/wallet_info_row/wallet_info_row.dart
index d5e42e814..fe006a67b 100644
--- a/lib/widgets/wallet_info_row/wallet_info_row.dart
+++ b/lib/widgets/wallet_info_row/wallet_info_row.dart
@@ -26,53 +26,58 @@ class WalletInfoRow extends ConsumerWidget {
         .getManagerProvider(walletId));
 
     if (Util.isDesktop) {
-      return GestureDetector(
-        onTap: onPressed,
-        child: Container(
-          color: Colors.transparent,
-          child: Row(
-            children: [
-              Expanded(
-                flex: 4,
-                child: Row(
-                  children: [
-                    WalletInfoCoinIcon(coin: manager.coin),
-                    const SizedBox(
-                      width: 12,
-                    ),
-                    Text(
-                      manager.walletName,
-                      style: STextStyles.desktopTextExtraSmall(context).copyWith(
-                        color:
-                            Theme.of(context).extension<StackColors>()!.textDark,
+      return MouseRegion(
+        cursor: SystemMouseCursors.click,
+        child: GestureDetector(
+          onTap: onPressed,
+          child: Container(
+            color: Colors.transparent,
+            child: Row(
+              children: [
+                Expanded(
+                  flex: 4,
+                  child: Row(
+                    children: [
+                      WalletInfoCoinIcon(coin: manager.coin),
+                      const SizedBox(
+                        width: 12,
                       ),
-                    ),
-                  ],
+                      Text(
+                        manager.walletName,
+                        style:
+                            STextStyles.desktopTextExtraSmall(context).copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark,
+                        ),
+                      ),
+                    ],
+                  ),
                 ),
-              ),
-              Expanded(
-                flex: 4,
-                child: WalletInfoRowBalanceFuture(
-                  walletId: walletId,
+                Expanded(
+                  flex: 4,
+                  child: WalletInfoRowBalanceFuture(
+                    walletId: walletId,
+                  ),
                 ),
-              ),
-              Expanded(
-                flex: 6,
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.end,
-                  children: [
-                    SvgPicture.asset(
-                      Assets.svg.chevronRight,
-                      width: 20,
-                      height: 20,
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .textSubtitle1,
-                    )
-                  ],
-                ),
-              )
-            ],
+                Expanded(
+                  flex: 6,
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.end,
+                    children: [
+                      SvgPicture.asset(
+                        Assets.svg.chevronRight,
+                        width: 20,
+                        height: 20,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textSubtitle1,
+                      )
+                    ],
+                  ),
+                )
+              ],
+            ),
           ),
         ),
       );

From cebbfcf82d3a54b3ec4b740878afbd653a42abfc Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 17:45:16 -0600
Subject: [PATCH 270/426] desktop currency update on save only

---
 .../global_settings_view/currency_view.dart   | 76 +++++++++++++------
 .../currency_settings/currency_settings.dart  |  2 +-
 2 files changed, 55 insertions(+), 23 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/currency_view.dart b/lib/pages/settings_views/global_settings_view/currency_view.dart
index 4f2c3258c..4e8fd5f6e 100644
--- a/lib/pages/settings_views/global_settings_view/currency_view.dart
+++ b/lib/pages/settings_views/global_settings_view/currency_view.dart
@@ -14,11 +14,10 @@ import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-import '../../../widgets/rounded_white_container.dart';
-
 class BaseCurrencySettingsView extends ConsumerStatefulWidget {
   const BaseCurrencySettingsView({Key? key}) : super(key: key);
 
@@ -37,14 +36,20 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
   final _searchFocusNode = FocusNode();
 
   void onTap(int index) {
-    if (currenciesWithoutSelected[index] == current || current.isEmpty) {
-      // ignore if already selected currency
-      return;
+    if (Util.isDesktop) {
+      setState(() {
+        current = currenciesWithoutSelected[index];
+      });
+    } else {
+      if (currenciesWithoutSelected[index] == current || current.isEmpty) {
+        // ignore if already selected currency
+        return;
+      }
+      current = currenciesWithoutSelected[index];
+      currenciesWithoutSelected.remove(current);
+      currenciesWithoutSelected.insert(0, current);
+      ref.read(prefsChangeNotifierProvider).currency = current;
     }
-    current = currenciesWithoutSelected[index];
-    currenciesWithoutSelected.remove(current);
-    currenciesWithoutSelected.insert(0, current);
-    ref.read(prefsChangeNotifierProvider).currency = current;
   }
 
   BorderRadius? _borderRadius(int index) {
@@ -82,6 +87,15 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
   @override
   void initState() {
     _searchController = TextEditingController();
+    if (Util.isDesktop) {
+      currenciesWithoutSelected =
+          ref.read(baseCurrenciesProvider).map.keys.toList();
+      current = ref.read(prefsChangeNotifierProvider).currency;
+      if (current.isNotEmpty) {
+        currenciesWithoutSelected.remove(current);
+        currenciesWithoutSelected.insert(0, current);
+      }
+    }
     super.initState();
   }
 
@@ -94,20 +108,25 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
 
   @override
   Widget build(BuildContext context) {
-    current = ref
-        .watch(prefsChangeNotifierProvider.select((value) => value.currency));
-
-    currenciesWithoutSelected = ref
-        .watch(baseCurrenciesProvider.select((value) => value.map))
-        .keys
-        .toList();
-    if (current.isNotEmpty) {
-      currenciesWithoutSelected.remove(current);
-      currenciesWithoutSelected.insert(0, current);
-    }
-    currenciesWithoutSelected = _filtered();
     final isDesktop = Util.isDesktop;
 
+    if (!isDesktop) {
+      current = ref
+          .watch(prefsChangeNotifierProvider.select((value) => value.currency));
+
+      currenciesWithoutSelected = ref
+          .watch(baseCurrenciesProvider.select((value) => value.map))
+          .keys
+          .toList();
+
+      if (current.isNotEmpty) {
+        currenciesWithoutSelected.remove(current);
+        currenciesWithoutSelected.insert(0, current);
+      }
+    }
+
+    currenciesWithoutSelected = _filtered();
+
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
@@ -181,7 +200,20 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
                       child: PrimaryButton(
                         label: "Save changes",
                         desktopMed: true,
-                        onPressed: Navigator.of(context).pop,
+                        onPressed: () {
+                          ref.read(prefsChangeNotifierProvider).currency =
+                              current;
+
+                          if (ref
+                              .read(prefsChangeNotifierProvider)
+                              .externalCalls) {
+                            ref
+                                .read(priceAnd24hChangeNotifierProvider)
+                                .updatePrice();
+                          }
+
+                          Navigator.of(context).pop();
+                        },
                       ),
                     ),
                   ],
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index ecc19ebb7..ad7d749ee 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -102,7 +102,7 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
                   crossAxisAlignment: CrossAxisAlignment.start,
                   children: [
                     Padding(
-                      padding: EdgeInsets.all(
+                      padding: const EdgeInsets.all(
                         10,
                       ),
                       child: PrimaryButton(

From f7b5462029f7bf9c3a19e4a2d5d4ac443a9b5cfb Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 17:55:34 -0600
Subject: [PATCH 271/426] increase min window height for desktop

---
 lib/main.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/main.dart b/lib/main.dart
index 21abd9df7..b1f917f58 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -76,7 +76,7 @@ void main() async {
 
   if (Util.isDesktop) {
     setWindowTitle('Stack Wallet');
-    setWindowMinSize(const Size(1200, 900));
+    setWindowMinSize(const Size(1200, 1100));
     setWindowMaxSize(Size.infinite);
   }
 

From 1b5ced50613c05c02cdb0bd0bde7208760b94b44 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 19:27:08 -0600
Subject: [PATCH 272/426] desktop save receiving qr image to file

---
 .../generate_receiving_uri_qr_code_view.dart  | 61 +++++++++++++++----
 1 file changed, 49 insertions(+), 12 deletions(-)

diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
index ae615bd96..75d0deba0 100644
--- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
+++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
@@ -1,9 +1,11 @@
+import 'dart:async';
 import 'dart:io';
 import 'dart:typed_data';
 import 'dart:ui' as ui;
 
 // import 'package:document_file_save_plus/document_file_save_plus.dart';
 import 'package:decimal/decimal.dart';
+import 'package:file_picker/file_picker.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/rendering.dart';
 import 'package:flutter_svg/svg.dart';
@@ -71,19 +73,53 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
           await image.toByteData(format: ui.ImageByteFormat.png);
       Uint8List pngBytes = byteData!.buffer.asUint8List();
 
-      // if (shouldSaveInsteadOfShare) {
-      //   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);
+      if (shouldSaveInsteadOfShare) {
+        if (Util.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,
+          );
 
-      await Share.shareFiles(["${tempDir.path}/qrcode.png"],
-          text: "Receive URI QR Code");
-      // }
+          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) {
       debugPrint(e.toString());
     }
@@ -567,6 +603,7 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                                   desktopMed: true,
                                   onPressed: () async {
                                     // TODO: add save functionality instead of share
+                                    // save works on linux at the moment
                                     await _capturePng(true);
                                   },
                                   label: "Save",

From 11bae1740db7eb132bb755717d45dee6ee4c80b1 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 19:52:20 -0600
Subject: [PATCH 273/426] desktop qr save only button

---
 .../generate_receiving_uri_qr_code_view.dart  | 42 +++++++++++--------
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
index 75d0deba0..981def830 100644
--- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
+++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
@@ -547,6 +547,7 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                         borderColor: Theme.of(context)
                             .extension<StackColors>()!
                             .background,
+                        width: isDesktop ? 370 : null,
                         child: Column(
                           children: [
                             Text(
@@ -578,26 +579,31 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                               height: 12,
                             ),
                             Row(
+                              mainAxisAlignment: isDesktop
+                                  ? MainAxisAlignment.center
+                                  : MainAxisAlignment.start,
                               children: [
-                                SecondaryButton(
-                                  width: 170,
-                                  desktopMed: true,
-                                  onPressed: () async {
-                                    await _capturePng(false);
-                                  },
-                                  label: "Share",
-                                  icon: SvgPicture.asset(
-                                    Assets.svg.share,
-                                    width: 20,
-                                    height: 20,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .buttonTextSecondary,
+                                if (!isDesktop)
+                                  SecondaryButton(
+                                    width: 170,
+                                    desktopMed: true,
+                                    onPressed: () async {
+                                      await _capturePng(false);
+                                    },
+                                    label: "Share",
+                                    icon: SvgPicture.asset(
+                                      Assets.svg.share,
+                                      width: 20,
+                                      height: 20,
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .buttonTextSecondary,
+                                    ),
+                                  ),
+                                if (!isDesktop)
+                                  const SizedBox(
+                                    width: 16,
                                   ),
-                                ),
-                                const SizedBox(
-                                  width: 16,
-                                ),
                                 PrimaryButton(
                                   width: 170,
                                   desktopMed: true,

From b64246228cadb58d4d9c32faf4b9fd005d9f4112 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 15 Nov 2022 19:58:32 -0600
Subject: [PATCH 274/426] update addressbookcard test

---
 test/widget_tests/address_book_card_test.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/widget_tests/address_book_card_test.dart b/test/widget_tests/address_book_card_test.dart
index 07b1387df..7c53d8d50 100644
--- a/test/widget_tests/address_book_card_test.dart
+++ b/test/widget_tests/address_book_card_test.dart
@@ -70,7 +70,7 @@ void main() {
       await widgetTester.tap(find.byType(RawMaterialButton));
       expect(find.byType(ContactPopUp), findsOneWidget);
     } else if (Util.isDesktop) {
-      expect(find.byType(RawMaterialButton), findsNothing);
+      expect(find.byType(RawMaterialButton), findsOneWidget);
     }
   });
 }

From bfc1603197abca97426b06c7599b12409d10f2ed Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 16 Nov 2022 08:11:25 -0700
Subject: [PATCH 275/426] fixed setting container corner rounding and padding

---
 .../advanced_settings/advanced_settings.dart              | 1 +
 .../home/settings_menu/appearance_settings.dart           | 1 +
 .../backup_and_restore/backup_and_restore_settings.dart   | 3 +++
 .../currency_settings/currency_settings.dart              | 1 +
 .../language_settings/language_settings.dart              | 1 +
 .../home/settings_menu/nodes_settings.dart                | 8 ++++----
 .../home/settings_menu/security_settings.dart             | 2 +-
 .../home/settings_menu/syncing_preferences_settings.dart  | 1 +
 8 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
index 0991a14ca..b4ff3fe6a 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
@@ -32,6 +32,7 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
             right: 30,
           ),
           child: RoundedWhiteContainer(
+            radiusMultiplier: 2,
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
diff --git a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
index 27a10ca80..7a9ed557f 100644
--- a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
@@ -49,6 +49,7 @@ class _AppearanceOptionSettings
             right: 30,
           ),
           child: RoundedWhiteContainer(
+            radiusMultiplier: 2,
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 663c3f975..7d70d4d0f 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -338,6 +338,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                       right: 30,
                     ),
                     child: RoundedWhiteContainer(
+                      radiusMultiplier: 2,
                       child: Column(
                         crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
@@ -501,6 +502,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                       right: 30,
                     ),
                     child: RoundedWhiteContainer(
+                      radiusMultiplier: 2,
                       child: Column(
                         crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
@@ -583,6 +585,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                       bottom: 40,
                     ),
                     child: RoundedWhiteContainer(
+                      radiusMultiplier: 2,
                       child: Column(
                         crossAxisAlignment: CrossAxisAlignment.start,
                         children: [
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index ad7d749ee..4c4225ce4 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -64,6 +64,7 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
             right: 30,
           ),
           child: RoundedWhiteContainer(
+            radiusMultiplier: 2,
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
index 96ce5cf61..08aeb9bc3 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
@@ -39,6 +39,7 @@ class _LanguageOptionSettings extends ConsumerState<LanguageOptionSettings> {
             right: 30,
           ),
           child: RoundedWhiteContainer(
+            radiusMultiplier: 2,
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
diff --git a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
index 012f7b47a..a7e95d33a 100644
--- a/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/nodes_settings.dart
@@ -88,12 +88,12 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
         Expanded(
           child: Padding(
             padding: const EdgeInsets.only(
-              right: 32,
-              bottom: 32,
+              right: 30,
+              // bottom: 32,
             ),
             child: RoundedWhiteContainer(
               radiusMultiplier: 2,
-              padding: const EdgeInsets.all(24),
+              padding: const EdgeInsets.all(20),
               child: Column(
                 mainAxisSize: MainAxisSize.min,
                 children: [
@@ -114,7 +114,7 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
                         style: STextStyles.desktopTextSmall(context),
                       ),
                       const SizedBox(
-                        height: 8,
+                        height: 16,
                       ),
                       Text(
                         "Select a coin to see nodes",
diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index de3505ace..9f870440b 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -144,7 +144,7 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
             right: 30,
           ),
           child: RoundedWhiteContainer(
-            // radiusMultiplier: 2,
+            radiusMultiplier: 2,
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
diff --git a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
index 3d8bebb81..408b93e15 100644
--- a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
@@ -30,6 +30,7 @@ class _SyncingPreferencesSettings
             right: 30,
           ),
           child: RoundedWhiteContainer(
+            radiusMultiplier: 2,
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [

From 0f3a0b18a4a156a7fdb79f162dde21c326fb4036 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 16 Nov 2022 09:53:51 -0700
Subject: [PATCH 276/426] manual backup ok button on dialog works

---
 .../create_backup_view.dart                   | 142 +++++++++---------
 1 file changed, 74 insertions(+), 68 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 821504bf8..55fc08087 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -654,9 +654,10 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                                       },
                                     ),
                                   );
+
                                   // make sure the dialog is able to be displayed for at least 1 second
-                                  await Future<void>.delayed(
-                                      const Duration(seconds: 1));
+                                  final fut = Future<void>.delayed(
+                                      const Duration(seconds: 2));
 
                                   final DateTime now = DateTime.now();
                                   final String fileToSave =
@@ -674,81 +675,86 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                                     jsonEncode(backup),
                                   );
 
+                                  await Future.wait([fut]);
+
                                   if (mounted) {
                                     // pop encryption progress dialog
                                     if (!isDesktop) Navigator.of(context).pop();
 
                                     if (result) {
                                       await showDialog<dynamic>(
-                                        context: context,
-                                        barrierDismissible: false,
-                                        builder: (_) => Platform.isAndroid
-                                            ? StackOkDialog(
+                                          context: context,
+                                          barrierDismissible: false,
+                                          builder: (context) {
+                                            if (Platform.isAndroid) {
+                                              return StackOkDialog(
                                                 title: "Backup saved to:",
                                                 message: fileToSave,
-                                              )
-                                            : !isDesktop
-                                                ? const StackOkDialog(
-                                                    title:
-                                                        "Backup creation succeeded")
-                                                : DesktopDialog(
-                                                    maxHeight: double.infinity,
-                                                    maxWidth: 500,
-                                                    child: Padding(
-                                                      padding:
-                                                          const EdgeInsets.only(
-                                                        left: 32,
-                                                        right: 32,
-                                                        bottom: 32,
-                                                      ),
-                                                      child: Column(
-                                                        mainAxisSize:
-                                                            MainAxisSize.min,
-                                                        crossAxisAlignment:
-                                                            CrossAxisAlignment
-                                                                .start,
-                                                        children: [
-                                                          const SizedBox(
-                                                              height: 26),
-                                                          Text(
-                                                            "Stack backup saved to: \n",
-                                                            style: STextStyles
-                                                                .desktopH3(
-                                                                    context),
-                                                          ),
-                                                          Text(
-                                                            fileToSave,
-                                                            style: STextStyles
-                                                                .desktopTextExtraExtraSmall(
-                                                                    context),
-                                                          ),
-                                                          const SizedBox(
-                                                            height: 40,
-                                                          ),
-                                                          Row(
-                                                            children: [
-                                                              // const Spacer(),
-                                                              Expanded(
-                                                                child:
-                                                                    PrimaryButton(
-                                                                  label: "Ok",
-                                                                  desktopMed:
-                                                                      true,
-                                                                  onPressed:
-                                                                      () {
-                                                                    // Navigator.of(
-                                                                    //         context)
-                                                                    //     .pop();
-                                                                  },
-                                                                ),
-                                                              ),
-                                                            ],
-                                                          )
-                                                        ],
-                                                      ),
-                                                    ),
+                                              );
+                                            } else if (isDesktop) {
+                                              return DesktopDialog(
+                                                maxHeight: double.infinity,
+                                                maxWidth: 500,
+                                                child: Padding(
+                                                  padding:
+                                                      const EdgeInsets.only(
+                                                    left: 32,
+                                                    right: 32,
+                                                    bottom: 32,
                                                   ),
-                                      );
+                                                  child: Column(
+                                                    mainAxisSize:
+                                                        MainAxisSize.min,
+                                                    crossAxisAlignment:
+                                                        CrossAxisAlignment
+                                                            .start,
+                                                    children: [
+                                                      const SizedBox(
+                                                          height: 26),
+                                                      Text(
+                                                        "Stack backup saved to: \n",
+                                                        style: STextStyles
+                                                            .desktopH3(context),
+                                                      ),
+                                                      Text(
+                                                        fileToSave,
+                                                        style: STextStyles
+                                                            .desktopTextExtraExtraSmall(
+                                                                context),
+                                                      ),
+                                                      const SizedBox(
+                                                        height: 40,
+                                                      ),
+                                                      Row(
+                                                        children: [
+                                                          // const Spacer(),
+                                                          Expanded(
+                                                            child:
+                                                                PrimaryButton(
+                                                              label: "Ok",
+                                                              desktopMed: true,
+                                                              onPressed: () {
+                                                                int count = 0;
+                                                                Navigator.of(
+                                                                        context)
+                                                                    .popUntil((_) =>
+                                                                        count++ >=
+                                                                        2);
+                                                              },
+                                                            ),
+                                                          ),
+                                                        ],
+                                                      )
+                                                    ],
+                                                  ),
+                                                ),
+                                              );
+                                            } else {
+                                              return const StackOkDialog(
+                                                  title:
+                                                      "Backup creation succeeded");
+                                            }
+                                          });
                                       passwordController.text = "";
                                       passwordRepeatController.text = "";
                                       setState(() {});

From e9a5cc85aec3e07b72a0b1eee81d03c0ea4454f6 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 16 Nov 2022 11:15:41 -0600
Subject: [PATCH 277/426] add delay for ui to update properly

---
 .../stack_backup_views/create_backup_view.dart               | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 55fc08087..02556beb9 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -655,9 +655,12 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                                     ),
                                   );
 
+                                  await Future<void>.delayed(
+                                      const Duration(seconds: 1));
+
                                   // make sure the dialog is able to be displayed for at least 1 second
                                   final fut = Future<void>.delayed(
-                                      const Duration(seconds: 2));
+                                      const Duration(seconds: 1));
 
                                   final DateTime now = DateTime.now();
                                   final String fileToSave =

From c50b2054fe8025fd804220695e0b6f1d88e62bb7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 16 Nov 2022 11:23:42 -0600
Subject: [PATCH 278/426] no notifications fix

---
 .../desktop_notifications_view.dart           | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart b/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart
index 0c51f899d..b9c03ff19 100644
--- a/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart
+++ b/lib/pages_desktop_specific/home/notifications/desktop_notifications_view.dart
@@ -39,13 +39,20 @@ class _DesktopNotificationsViewState
         ),
       ),
       body: notifications.isEmpty
-          ? RoundedWhiteContainer(
-              child: Center(
-                child: Text(
-                  "Notifications will appear here",
-                  style: STextStyles.desktopTextExtraExtraSmall(context),
+          ? Column(
+              children: [
+                Padding(
+                  padding: const EdgeInsets.all(24),
+                  child: RoundedWhiteContainer(
+                    child: Center(
+                      child: Text(
+                        "Notifications will appear here",
+                        style: STextStyles.desktopTextExtraExtraSmall(context),
+                      ),
+                    ),
+                  ),
                 ),
-              ),
+              ],
             )
           : ListView.builder(
               primary: false,

From 0ce2477cf81fcc1a278a41748b9f2cd5424fb97f Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 16 Nov 2022 12:08:19 -0600
Subject: [PATCH 279/426] desktop addressbook layout

---
 .../desktop_address_book.dart                 | 176 ++++++++----------
 1 file changed, 74 insertions(+), 102 deletions(-)

diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index 407ed9897..ec40e5f60 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -13,8 +13,10 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
-import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
@@ -89,37 +91,31 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
     final hasWallets = ref.watch(walletsChangeNotifierProvider).hasWallets;
-    final size = MediaQuery.of(context).size;
 
-    return Column(
-      mainAxisSize: MainAxisSize.min,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        DesktopAppBar(
-          isCompactHeight: true,
-          leading: Row(
-            children: [
-              const SizedBox(
-                width: 24,
-              ),
-              Text(
-                "Address Book",
-                style: STextStyles.desktopH3(context),
-              )
-            ],
-          ),
+    return DesktopScaffold(
+      appBar: DesktopAppBar(
+        isCompactHeight: true,
+        leading: Row(
+          children: [
+            const SizedBox(
+              width: 24,
+            ),
+            Text(
+              "Address Book",
+              style: STextStyles.desktopH3(context),
+            )
+          ],
         ),
-        const SizedBox(height: 53),
-        Padding(
-          padding: const EdgeInsets.symmetric(horizontal: 24),
-          child: RoundedContainer(
-            color: Theme.of(context).extension<StackColors>()!.background,
-            child: Row(
-              children: [
-                SizedBox(
-                  height: 60,
-                  width: size.width - 800,
-                  child: ClipRRect(
+      ),
+      body: Padding(
+        padding: const EdgeInsets.all(24),
+        child: Row(
+          children: [
+            Expanded(
+              flex: 6,
+              child: Column(
+                children: [
+                  ClipRRect(
                     borderRadius: BorderRadius.circular(
                       Constants.size.circularBorderRadius,
                     ),
@@ -172,81 +168,57 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                       ),
                     ),
                   ),
-                ),
-                const SizedBox(width: 20),
-                TextButton(
-                  style: Theme.of(context)
-                      .extension<StackColors>()!
-                      .getDesktopMenuButtonColorSelected(context),
-                  onPressed: () {
-                    selectCryptocurrency();
-                  },
-                  child: SizedBox(
-                    width: 200,
-                    height: 56,
-                    child: Row(
-                      mainAxisAlignment: MainAxisAlignment.center,
-                      children: [
-                        Padding(
-                          padding: const EdgeInsets.symmetric(horizontal: 10),
-                          child: SvgPicture.asset(Assets.svg.filter),
-                        ),
-                        Text(
-                          "Filter",
-                          style: STextStyles.desktopTextExtraExtraSmall(context)
-                              .copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark,
-                          ),
-                        ),
-                      ],
-                    ),
+                  const SizedBox(
+                    height: 24,
                   ),
-                ),
-                const SizedBox(width: 20),
-                TextButton(
-                  style: Theme.of(context)
-                      .extension<StackColors>()!
-                      .getPrimaryEnabledButtonColor(context),
-                  onPressed: () {
-                    newContact();
-                  },
-                  child: SizedBox(
-                    width: 200,
-                    height: 56,
-                    child: Row(
-                      mainAxisAlignment: MainAxisAlignment.center,
-                      children: [
-                        Padding(
-                          padding: const EdgeInsets.symmetric(horizontal: 10),
-                          child: SvgPicture.asset(Assets.svg.circlePlus),
-                        ),
-                        Text(
-                          "Add new",
-                          style: STextStyles.desktopTextExtraExtraSmall(context)
-                              .copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .popupBG,
-                          ),
-                        ),
-                      ],
-                    ),
-                  ),
-                ),
-              ],
+                  const AddressBookView(),
+                ],
+              ),
             ),
-          ),
+            const SizedBox(
+              width: 20,
+            ),
+            Expanded(
+              flex: 5,
+              child: Column(
+                children: [
+                  Row(
+                    children: [
+                      SecondaryButton(
+                        width: 184,
+                        label: "Filter",
+                        desktopMed: true,
+                        icon: SvgPicture.asset(
+                          Assets.svg.filter,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .buttonTextSecondary,
+                        ),
+                        onPressed: selectCryptocurrency,
+                      ),
+                      const SizedBox(
+                        width: 20,
+                      ),
+                      PrimaryButton(
+                        width: 184,
+                        label: "Add new",
+                        desktopMed: true,
+                        icon: SvgPicture.asset(
+                          Assets.svg.circlePlus,
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .buttonTextPrimary,
+                        ),
+                        onPressed: newContact,
+                      ),
+                    ],
+                  ),
+                ],
+              ),
+            ),
+          ],
         ),
-        const Padding(
-          padding: EdgeInsets.symmetric(horizontal: 24, vertical: 26),
-          child: SizedBox(
-            width: 489,
-            child: AddressBookView(),
-          ),
-        ),
-      ],
+      ),
     );
   }
 }

From f66b780e53ca89731f7dad19324e28a7f2ea76d4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 16 Nov 2022 12:09:19 -0600
Subject: [PATCH 280/426] desktop popup edge color fix

---
 lib/widgets/desktop/desktop_dialog.dart | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/widgets/desktop/desktop_dialog.dart b/lib/widgets/desktop/desktop_dialog.dart
index d11124ba6..59c59c575 100644
--- a/lib/widgets/desktop/desktop_dialog.dart
+++ b/lib/widgets/desktop/desktop_dialog.dart
@@ -25,6 +25,7 @@ class DesktopDialog extends StatelessWidget {
             maxHeight: maxHeight,
           ),
           child: Material(
+            color: Colors.transparent,
             borderRadius: BorderRadius.circular(
               20,
             ),

From 016b90e904e3e9c6651c42a9c0b50415bdb6839b Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 16 Nov 2022 12:22:09 -0600
Subject: [PATCH 281/426] support view full buttons desktop

---
 .../global_settings_view/support_view.dart    | 57 ++++++++-----------
 1 file changed, 25 insertions(+), 32 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/support_view.dart b/lib/pages/settings_views/global_settings_view/support_view.dart
index 02d281b66..9ff50345c 100644
--- a/lib/pages/settings_views/global_settings_view/support_view.dart
+++ b/lib/pages/settings_views/global_settings_view/support_view.dart
@@ -7,7 +7,6 @@ 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/custom_buttons/app_bar_icon_button.dart';
-import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:url_launcher/url_launcher.dart';
 
@@ -138,30 +137,20 @@ class AboutItem extends StatelessWidget {
 
     return RoundedWhiteContainer(
       padding: const EdgeInsets.all(0),
-      child: ConditionalParent(
-        condition: !isDesktop,
-        builder: (child) => RawMaterialButton(
-          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-          shape: RoundedRectangleBorder(
-            borderRadius: BorderRadius.circular(
-              Constants.size.circularBorderRadius,
-            ),
-          ),
-          onPressed: () {
-            launchUrl(
-              Uri.parse(linkUrl),
-              mode: LaunchMode.externalApplication,
-            );
-          },
-          child: Padding(
-            padding: const EdgeInsets.symmetric(
-              horizontal: 12,
-              vertical: 20,
-            ),
-            child: child,
+      child: RawMaterialButton(
+        // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+        shape: RoundedRectangleBorder(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
           ),
         ),
+        onPressed: () {
+          launchUrl(
+            Uri.parse(linkUrl),
+            mode: LaunchMode.externalApplication,
+          );
+        },
         child: Padding(
           padding: isDesktop
               ? const EdgeInsets.symmetric(
@@ -212,15 +201,19 @@ class AboutItem extends StatelessWidget {
                 ],
               ),
               if (isDesktop)
-                BlueTextButton(
-                  text: buttonText,
-                  onTap: () {
-                    launchUrl(
-                      Uri.parse(linkUrl),
-                      mode: LaunchMode.externalApplication,
-                    );
-                  },
-                ),
+                Text(
+                  buttonText,
+                  style: STextStyles.desktopTextExtraExtraSmall(context),
+                )
+              // BlueTextButton(
+              //   text: buttonText,
+              //   onTap: () {
+              //     launchUrl(
+              //       Uri.parse(linkUrl),
+              //       mode: LaunchMode.externalApplication,
+              //     );
+              //   },
+              // ),
             ],
           ),
         ),

From 2c88b017f3d399b72e0bb3aec9f4b26e5be200b9 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 16 Nov 2022 12:23:12 -0600
Subject: [PATCH 282/426] updated discord link

---
 lib/pages/settings_views/global_settings_view/support_view.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pages/settings_views/global_settings_view/support_view.dart b/lib/pages/settings_views/global_settings_view/support_view.dart
index 9ff50345c..ee00bdb00 100644
--- a/lib/pages/settings_views/global_settings_view/support_view.dart
+++ b/lib/pages/settings_views/global_settings_view/support_view.dart
@@ -73,7 +73,7 @@ class SupportView extends StatelessWidget {
             height: 8,
           ),
           AboutItem(
-            linkUrl: "https://discord.gg/RZMG3yUm",
+            linkUrl: "https://discord.com/invite/mRPZuXx3At",
             label: "Discord",
             buttonText: "Stack Wallet",
             iconAsset: Assets.socials.discord,

From be70d75d7551bc7b7cadf3227aeaf741512add9d Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 16 Nov 2022 12:27:57 -0600
Subject: [PATCH 283/426] mouse cursor for desktop favorites card

---
 .../sub_widgets/favorite_card.dart            | 357 +++++++++---------
 1 file changed, 183 insertions(+), 174 deletions(-)

diff --git a/lib/pages/wallets_view/sub_widgets/favorite_card.dart b/lib/pages/wallets_view/sub_widgets/favorite_card.dart
index 8ce8add17..7749f264d 100644
--- a/lib/pages/wallets_view/sub_widgets/favorite_card.dart
+++ b/lib/pages/wallets_view/sub_widgets/favorite_card.dart
@@ -13,6 +13,7 @@ import 'package:stackwallet/utilities/format.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:tuple/tuple.dart';
 
 class FavoriteCard extends ConsumerStatefulWidget {
@@ -54,190 +55,198 @@ class _FavoriteCardState extends ConsumerState<FavoriteCard> {
     final externalCalls = ref.watch(
         prefsChangeNotifierProvider.select((value) => value.externalCalls));
 
-    return GestureDetector(
-      onTap: () {
-        if (Util.isDesktop) {
-          Navigator.of(context).pushNamed(
-            DesktopWalletView.routeName,
-            arguments: walletId,
-          );
-        } else {
-          Navigator.of(context).pushNamed(
-            WalletView.routeName,
-            arguments: Tuple2(
-              walletId,
-              managerProvider,
-            ),
-          );
-        }
-      },
-      child: SizedBox(
-        width: widget.width,
-        height: widget.height,
-        child: CardOverlayStack(
-          background: Stack(
-            children: [
-              Container(
-                width: widget.width,
-                height: widget.height,
-                decoration: BoxDecoration(
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .colorForCoin(coin),
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
-                ),
+    return ConditionalParent(
+      condition: Util.isDesktop,
+      builder: (child) => MouseRegion(
+        cursor: SystemMouseCursors.click,
+        child: child,
+      ),
+      child: GestureDetector(
+        onTap: () {
+          if (Util.isDesktop) {
+            Navigator.of(context).pushNamed(
+              DesktopWalletView.routeName,
+              arguments: walletId,
+            );
+          } else {
+            Navigator.of(context).pushNamed(
+              WalletView.routeName,
+              arguments: Tuple2(
+                walletId,
+                managerProvider,
               ),
-              Column(
-                children: [
-                  const Spacer(),
-                  SizedBox(
-                    height: widget.width * 0.3,
-                    child: Row(
-                      children: [
-                        const Spacer(
-                          flex: 9,
-                        ),
-                        SvgPicture.asset(
-                          Assets.svg.ellipse2,
-                          height: widget.width * 0.3,
-                        ),
-                        // ),
-                        const Spacer(
-                          flex: 2,
-                        ),
-                      ],
-                    ),
-                  ),
-                ],
-              ),
-              Row(
-                children: [
-                  const Spacer(
-                    flex: 5,
-                  ),
-                  SizedBox(
-                    width: widget.width * 0.45,
-                    child: Column(
-                      children: [
-                        SvgPicture.asset(
-                          Assets.svg.ellipse1,
-                          width: widget.width * 0.45,
-                        ),
-                        const Spacer(),
-                      ],
-                    ),
-                  ),
-                  const Spacer(
-                    flex: 1,
-                  ),
-                ],
-              ),
-            ],
-          ),
-          child: Padding(
-            padding: const EdgeInsets.all(12.0),
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
+            );
+          }
+        },
+        child: SizedBox(
+          width: widget.width,
+          height: widget.height,
+          child: CardOverlayStack(
+            background: Stack(
               children: [
-                Expanded(
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.center,
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      Expanded(
-                        child: Text(
-                          ref.watch(managerProvider
-                              .select((value) => value.walletName)),
-                          style: STextStyles.itemSubtitle12(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textFavoriteCard,
-                          ),
-                          overflow: TextOverflow.fade,
-                        ),
-                      ),
-                      SvgPicture.asset(
-                        Assets.svg.iconFor(coin: coin),
-                        width: 24,
-                        height: 24,
-                      ),
-                    ],
+                Container(
+                  width: widget.width,
+                  height: widget.height,
+                  decoration: BoxDecoration(
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .colorForCoin(coin),
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
                   ),
                 ),
-                FutureBuilder(
-                  future: ref.watch(
-                      managerProvider.select((value) => value.totalBalance)),
-                  builder: (builderContext, AsyncSnapshot<Decimal> snapshot) {
-                    if (snapshot.connectionState == ConnectionState.done &&
-                        snapshot.hasData) {
-                      if (snapshot.data != null) {
-                        _cachedBalance = snapshot.data!;
-                        if (externalCalls) {
-                          _cachedFiatValue = _cachedBalance *
-                              ref
-                                  .watch(
-                                    priceAnd24hChangeNotifierProvider.select(
-                                      (value) => value.getPrice(coin),
-                                    ),
-                                  )
-                                  .item1;
-                        }
-                      }
-                    }
-                    return Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        FittedBox(
-                          fit: BoxFit.scaleDown,
-                          child: Text(
-                            "${Format.localizedStringAsFixed(
-                              decimalPlaces: 8,
-                              value: _cachedBalance,
-                              locale: ref.watch(
-                                localeServiceChangeNotifierProvider
-                                    .select((value) => value.locale),
-                              ),
-                            )} ${coin.ticker}",
-                            style: STextStyles.titleBold12(context).copyWith(
-                              fontSize: 16,
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textFavoriteCard,
-                            ),
+                Column(
+                  children: [
+                    const Spacer(),
+                    SizedBox(
+                      height: widget.width * 0.3,
+                      child: Row(
+                        children: [
+                          const Spacer(
+                            flex: 9,
                           ),
-                        ),
-                        if (externalCalls)
-                          const SizedBox(
-                            height: 4,
+                          SvgPicture.asset(
+                            Assets.svg.ellipse2,
+                            height: widget.width * 0.3,
                           ),
-                        if (externalCalls)
-                          Text(
-                            "${Format.localizedStringAsFixed(
-                              decimalPlaces: 2,
-                              value: _cachedFiatValue,
-                              locale: ref.watch(
-                                localeServiceChangeNotifierProvider
-                                    .select((value) => value.locale),
-                              ),
-                            )} ${ref.watch(
-                              prefsChangeNotifierProvider
-                                  .select((value) => value.currency),
-                            )}",
-                            style: STextStyles.itemSubtitle12(context).copyWith(
-                              fontSize: 10,
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textFavoriteCard,
-                            ),
+                          // ),
+                          const Spacer(
+                            flex: 2,
                           ),
-                      ],
-                    );
-                  },
+                        ],
+                      ),
+                    ),
+                  ],
+                ),
+                Row(
+                  children: [
+                    const Spacer(
+                      flex: 5,
+                    ),
+                    SizedBox(
+                      width: widget.width * 0.45,
+                      child: Column(
+                        children: [
+                          SvgPicture.asset(
+                            Assets.svg.ellipse1,
+                            width: widget.width * 0.45,
+                          ),
+                          const Spacer(),
+                        ],
+                      ),
+                    ),
+                    const Spacer(
+                      flex: 1,
+                    ),
+                  ],
                 ),
               ],
             ),
+            child: Padding(
+              padding: const EdgeInsets.all(12.0),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Expanded(
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      children: [
+                        Expanded(
+                          child: Text(
+                            ref.watch(managerProvider
+                                .select((value) => value.walletName)),
+                            style: STextStyles.itemSubtitle12(context).copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textFavoriteCard,
+                            ),
+                            overflow: TextOverflow.fade,
+                          ),
+                        ),
+                        SvgPicture.asset(
+                          Assets.svg.iconFor(coin: coin),
+                          width: 24,
+                          height: 24,
+                        ),
+                      ],
+                    ),
+                  ),
+                  FutureBuilder(
+                    future: ref.watch(
+                        managerProvider.select((value) => value.totalBalance)),
+                    builder: (builderContext, AsyncSnapshot<Decimal> snapshot) {
+                      if (snapshot.connectionState == ConnectionState.done &&
+                          snapshot.hasData) {
+                        if (snapshot.data != null) {
+                          _cachedBalance = snapshot.data!;
+                          if (externalCalls) {
+                            _cachedFiatValue = _cachedBalance *
+                                ref
+                                    .watch(
+                                      priceAnd24hChangeNotifierProvider.select(
+                                        (value) => value.getPrice(coin),
+                                      ),
+                                    )
+                                    .item1;
+                          }
+                        }
+                      }
+                      return Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          FittedBox(
+                            fit: BoxFit.scaleDown,
+                            child: Text(
+                              "${Format.localizedStringAsFixed(
+                                decimalPlaces: 8,
+                                value: _cachedBalance,
+                                locale: ref.watch(
+                                  localeServiceChangeNotifierProvider
+                                      .select((value) => value.locale),
+                                ),
+                              )} ${coin.ticker}",
+                              style: STextStyles.titleBold12(context).copyWith(
+                                fontSize: 16,
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textFavoriteCard,
+                              ),
+                            ),
+                          ),
+                          if (externalCalls)
+                            const SizedBox(
+                              height: 4,
+                            ),
+                          if (externalCalls)
+                            Text(
+                              "${Format.localizedStringAsFixed(
+                                decimalPlaces: 2,
+                                value: _cachedFiatValue,
+                                locale: ref.watch(
+                                  localeServiceChangeNotifierProvider
+                                      .select((value) => value.locale),
+                                ),
+                              )} ${ref.watch(
+                                prefsChangeNotifierProvider
+                                    .select((value) => value.currency),
+                              )}",
+                              style:
+                                  STextStyles.itemSubtitle12(context).copyWith(
+                                fontSize: 10,
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textFavoriteCard,
+                              ),
+                            ),
+                        ],
+                      );
+                    },
+                  ),
+                ],
+              ),
+            ),
           ),
         ),
       ),

From dfc52e3e7e6a3f3169b3e3c410ccbd0920a9e963 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 16 Nov 2022 12:29:51 -0700
Subject: [PATCH 284/426] unsuccessful login lag fixed

---
 lib/pages_desktop_specific/desktop_login_view.dart | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index ebd1c334b..f60ce2240 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -55,6 +55,8 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
         ),
       );
 
+      await Future<void>.delayed(const Duration(seconds: 1));
+
       await ref
           .read(storageCryptoHandlerProvider)
           .initFromExisting(passwordController.text);
@@ -79,6 +81,8 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
       // pop loading indicator
       Navigator.of(context).pop();
 
+      await Future<void>.delayed(const Duration(seconds: 1));
+
       await showFloatingFlushBar(
         type: FlushBarType.warning,
         message: e.toString(),

From 5f863bb35a49f661bea9a4b3bfeea19e1989f4a1 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 16 Nov 2022 13:18:32 -0700
Subject: [PATCH 285/426] QR button on desktop Send commented out

---
 .../wallet_view/sub_widgets/desktop_send.dart       | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index cd19c53f8..ec9a1620a 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -40,7 +40,6 @@ import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
-import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.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';
@@ -1247,12 +1246,12 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                           },
                           child: const AddressBookIcon(),
                         ),
-                      if (sendToController.text.isEmpty)
-                        TextFieldIconButton(
-                          key: const Key("sendViewScanQrButtonKey"),
-                          onTap: scanQr,
-                          child: const QrCodeIcon(),
-                        )
+                      // if (sendToController.text.isEmpty)
+                      //   TextFieldIconButton(
+                      //     key: const Key("sendViewScanQrButtonKey"),
+                      //     onTap: scanQr,
+                      //     child: const QrCodeIcon(),
+                      //   )
                     ],
                   ),
                 ),

From bd0b01efcd71d9cee38cd26eb3f7fb37e2c7fcdf Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 16 Nov 2022 15:51:49 -0700
Subject: [PATCH 286/426] desktop debug shows search bar when scrolling

---
 .../advanced_settings/debug_info_dialog.dart  | 122 ++++++++----------
 1 file changed, 57 insertions(+), 65 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
index cf687e3e7..3235a5549 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
@@ -108,10 +108,65 @@ class _DebugInfoDialog extends ConsumerState<DebugInfoDialog> {
               const DesktopDialogCloseButton(),
             ],
           ),
+          Padding(
+            padding: EdgeInsets.symmetric(horizontal: 32),
+            child: ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
+                controller: searchDebugController,
+                focusNode: searchDebugFocusNode,
+                onChanged: (newString) {
+                  setState(() => _searchTerm = newString);
+                },
+                style: STextStyles.field(context),
+                decoration: standardInputDecoration(
+                  "Search",
+                  searchDebugFocusNode,
+                  context,
+                ).copyWith(
+                  prefixIcon: Padding(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 10,
+                      vertical: 16,
+                    ),
+                    child: SvgPicture.asset(
+                      Assets.svg.search,
+                      width: 16,
+                      height: 16,
+                    ),
+                  ),
+                  suffixIcon: searchDebugController.text.isNotEmpty
+                      ? Padding(
+                          padding: const EdgeInsets.only(right: 0),
+                          child: UnconstrainedBox(
+                            child: Row(
+                              children: [
+                                TextFieldIconButton(
+                                  child: const XIcon(),
+                                  onTap: () async {
+                                    setState(() {
+                                      searchDebugController.text = "";
+                                      _searchTerm = "";
+                                    });
+                                  },
+                                ),
+                              ],
+                            ),
+                          ),
+                        )
+                      : null,
+                ),
+              ),
+            ),
+          ),
           Expanded(
             // flex: 24,
             child: NestedScrollView(
-              floatHeaderSlivers: true,
+              // floatHeaderSlivers: true,
               headerSliverBuilder: (context, innerBoxIsScrolled) {
                 return [
                   SliverOverlapAbsorber(
@@ -122,70 +177,7 @@ class _DebugInfoDialog extends ConsumerState<DebugInfoDialog> {
                         padding: const EdgeInsets.symmetric(
                             vertical: 16, horizontal: 32),
                         child: Column(
-                          children: [
-                            Padding(
-                              padding: const EdgeInsets.only(bottom: 16),
-                              child: ClipRRect(
-                                borderRadius: BorderRadius.circular(
-                                  Constants.size.circularBorderRadius,
-                                ),
-                                child: TextField(
-                                  autocorrect: Util.isDesktop ? false : true,
-                                  enableSuggestions:
-                                      Util.isDesktop ? false : true,
-                                  controller: searchDebugController,
-                                  focusNode: searchDebugFocusNode,
-                                  onChanged: (newString) {
-                                    setState(() => _searchTerm = newString);
-                                  },
-                                  style: STextStyles.field(context),
-                                  decoration: standardInputDecoration(
-                                    "Search",
-                                    searchDebugFocusNode,
-                                    context,
-                                  ).copyWith(
-                                    prefixIcon: Padding(
-                                      padding: const EdgeInsets.symmetric(
-                                        horizontal: 10,
-                                        vertical: 16,
-                                      ),
-                                      child: SvgPicture.asset(
-                                        Assets.svg.search,
-                                        width: 16,
-                                        height: 16,
-                                      ),
-                                    ),
-                                    suffixIcon: searchDebugController
-                                            .text.isNotEmpty
-                                        ? Padding(
-                                            padding:
-                                                const EdgeInsets.only(right: 0),
-                                            child: UnconstrainedBox(
-                                              child: Row(
-                                                children: [
-                                                  TextFieldIconButton(
-                                                    child: const XIcon(),
-                                                    onTap: () async {
-                                                      setState(() {
-                                                        searchDebugController
-                                                            .text = "";
-                                                        _searchTerm = "";
-                                                      });
-                                                    },
-                                                  ),
-                                                ],
-                                              ),
-                                            ),
-                                          )
-                                        : null,
-                                  ),
-                                ),
-                              ),
-                            ),
-                            const SizedBox(
-                              height: 12,
-                            ),
-                          ],
+                          children: const [],
                         ),
                       ),
                     ),

From 2936249bd6190be934a3623457ce2bb679b1cccc Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 16 Nov 2022 16:36:50 -0700
Subject: [PATCH 287/426] textfields clear on send

---
 .../wallet_view/sub_widgets/desktop_send.dart              | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index ec9a1620a..af2c2517a 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -248,6 +248,13 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                             label: "Yes",
                             onPressed: () {
                               Navigator.of(context).pop(true);
+
+                              setState(() {
+                                sendToController.text = "";
+                                cryptoAmountController.text = "";
+                                baseAmountController.text = "";
+                                noteController.text = "";
+                              });
                             },
                           ),
                         ),

From fc9e4d35dd3d7da66d10a587a052558feee0397d Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 07:02:56 -0600
Subject: [PATCH 288/426] remove loading future

---
 .../address_book_views/address_book_view.dart | 221 +++++++++---------
 1 file changed, 112 insertions(+), 109 deletions(-)

diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index 50e51110b..fd2a995cc 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -18,7 +18,6 @@ import 'package:stackwallet/widgets/address_book_card.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
-import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
@@ -38,9 +37,9 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
   late TextEditingController _searchController;
 
   final _searchFocusNode = FocusNode();
-
-  List<Contact>? _cache;
-  List<Contact>? _cacheFav;
+  //
+  // List<Contact>? _cache;
+  // List<Contact>? _cacheFav;
 
   String _searchTerm = "";
 
@@ -100,8 +99,10 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
-    final addressBookEntriesFuture = ref.watch(
-        addressBookServiceProvider.select((value) => value.addressBookEntries));
+    // final addressBookEntriesFuture = ref.watch(
+    //     addressBookServiceProvider.select((value) => value.addressBookEntries));
+    final contacts =
+        ref.watch(addressBookServiceProvider.select((value) => value.contacts));
 
     final isDesktop = Util.isDesktop;
     return ConditionalParent(
@@ -279,57 +280,58 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
             const SizedBox(
               height: 12,
             ),
-            FutureBuilder(
-              future: addressBookEntriesFuture,
-              builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
-                if (snapshot.connectionState == ConnectionState.done &&
-                    snapshot.hasData) {
-                  _cacheFav = snapshot.data!;
-                }
-                if (_cacheFav == null) {
-                  // TODO proper loading animation
-                  return const LoadingIndicator();
-                } else {
-                  if (_cacheFav!.isNotEmpty) {
-                    return RoundedWhiteContainer(
-                      padding: EdgeInsets.all(!isDesktop ? 0 : 15),
-                      child: Column(
-                        children: [
-                          ..._cacheFav!
-                              .where((element) => element.addresses
-                                  .where((e) => ref.watch(
-                                      addressBookFilterProvider.select(
-                                          (value) =>
-                                              value.coins.contains(e.coin))))
-                                  .isNotEmpty)
-                              .where((e) =>
-                                  e.isFavorite &&
-                                  ref
-                                      .read(addressBookServiceProvider)
-                                      .matches(_searchTerm, e))
-                              .where((element) => element.isFavorite)
-                              .map(
-                                (e) => AddressBookCard(
-                                  key: Key("favContactCard_${e.id}_key"),
-                                  contactId: e.id,
-                                ),
-                              ),
-                        ],
-                      ),
-                    );
-                  } else {
-                    return RoundedWhiteContainer(
-                      child: Center(
-                        child: Text(
-                          "Your favorite contacts will appear here",
-                          style: STextStyles.itemSubtitle(context),
+            // FutureBuilder(
+            //   future: addressBookEntriesFuture,
+            //   builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
+            //     if (snapshot.connectionState == ConnectionState.done &&
+            //         snapshot.hasData) {
+            //       _cacheFav = snapshot.data!;
+            //     }
+            //     if (_cacheFav == null) {
+            //       // TODO proper loading animation
+            //       return const LoadingIndicator();
+            //     } else {
+            //       if (_cacheFav!.isNotEmpty) {
+            //         return
+            RoundedWhiteContainer(
+              padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+              child: Column(
+                children: [
+                  ...contacts
+                      .where((element) => element.addresses
+                          .where((e) => ref.watch(addressBookFilterProvider
+                              .select((value) => value.coins.contains(e.coin))))
+                          .isNotEmpty)
+                      .where((e) =>
+                          e.isFavorite &&
+                          ref
+                              .read(addressBookServiceProvider)
+                              .matches(_searchTerm, e))
+                      .where((element) => element.isFavorite)
+                      .map(
+                        (e) => AddressBookCard(
+                          key: Key("favContactCard_${e.id}_key"),
+                          contactId: e.id,
                         ),
                       ),
-                    );
-                  }
-                }
-              },
-            ),
+                ],
+              ),
+            )
+            //         ;
+            //       } else {
+            //         return RoundedWhiteContainer(
+            //           child: Center(
+            //             child: Text(
+            //               "Your favorite contacts will appear here",
+            //               style: STextStyles.itemSubtitle(context),
+            //             ),
+            //           ),
+            //         );
+            //       }
+            //     }
+            //   },
+            // )
+            ,
             const SizedBox(
               height: 16,
             ),
@@ -340,63 +342,64 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
             const SizedBox(
               height: 12,
             ),
-            FutureBuilder(
-              future: addressBookEntriesFuture,
-              builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
-                if (snapshot.connectionState == ConnectionState.done &&
-                    snapshot.hasData) {
-                  _cache = snapshot.data!;
-                }
-                if (_cache == null) {
-                  // TODO proper loading animation
-                  return const LoadingIndicator();
-                } else {
-                  if (_cache!.isNotEmpty) {
-                    return Column(
+            // FutureBuilder(
+            //   future: addressBookEntriesFuture,
+            //   builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
+            //     if (snapshot.connectionState == ConnectionState.done &&
+            //         snapshot.hasData) {
+            //       _cache = snapshot.data!;
+            //     }
+            //     if (_cache == null) {
+            //       // TODO proper loading animation
+            //       return const LoadingIndicator();
+            //     } else {
+            //       if (_cache!.isNotEmpty) {
+            //         return
+            Column(
+              children: [
+                RoundedWhiteContainer(
+                  padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+                  child: Padding(
+                    padding: const EdgeInsets.all(8.0),
+                    child: Column(
                       children: [
-                        RoundedWhiteContainer(
-                          padding: EdgeInsets.all(!isDesktop ? 0 : 15),
-                          child: Padding(
-                            padding: const EdgeInsets.all(8.0),
-                            child: Column(
-                              children: [
-                                ..._cache!
-                                    .where((element) => element.addresses
-                                        .where((e) => ref.watch(
-                                            addressBookFilterProvider.select(
-                                                (value) => value.coins
-                                                    .contains(e.coin))))
-                                        .isNotEmpty)
-                                    .where((e) => ref
-                                        .read(addressBookServiceProvider)
-                                        .matches(_searchTerm, e))
-                                    .where((element) => !element.isFavorite)
-                                    .map(
-                                      (e) => AddressBookCard(
-                                        key: Key(
-                                            "desktopContactCard_${e.id}_key"),
-                                        contactId: e.id,
-                                      ),
-                                    ),
-                              ],
+                        ...contacts
+                            .where((element) => element.addresses
+                                .where((e) => ref.watch(
+                                    addressBookFilterProvider.select((value) =>
+                                        value.coins.contains(e.coin))))
+                                .isNotEmpty)
+                            .where((e) => ref
+                                .read(addressBookServiceProvider)
+                                .matches(_searchTerm, e))
+                            .where((element) => !element.isFavorite)
+                            .map(
+                              (e) => AddressBookCard(
+                                key: Key("desktopContactCard_${e.id}_key"),
+                                contactId: e.id,
+                              ),
                             ),
-                          ),
-                        ),
                       ],
-                    );
-                  } else {
-                    return RoundedWhiteContainer(
-                      child: Center(
-                        child: Text(
-                          "Your contacts will appear here",
-                          style: STextStyles.itemSubtitle(context),
-                        ),
-                      ),
-                    );
-                  }
-                }
-              },
-            ),
+                    ),
+                  ),
+                ),
+              ],
+            )
+            //         ;
+            //       } else {
+            //         return RoundedWhiteContainer(
+            //           child: Center(
+            //             child: Text(
+            //               "Your contacts will appear here",
+            //               style: STextStyles.itemSubtitle(context),
+            //             ),
+            //           ),
+            //         );
+            //       }
+            //     }
+            //   },
+            // )
+            ,
           ],
         ),
       ),

From 7e2160d7ccf37fca61f918771ed7337b71fbd153 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 07:03:09 -0600
Subject: [PATCH 289/426] fix duplicate keys error

---
 .../address_book_views/subviews/contact_details_view.dart     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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 c0c10b3b1..a48a535c6 100644
--- a/lib/pages/address_book_views/subviews/contact_details_view.dart
+++ b/lib/pages/address_book_views/subviews/contact_details_view.dart
@@ -469,7 +469,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
                               ..._cachedTransactions.map(
                                 (e) => TransactionCard(
                                   key: Key(
-                                      "contactDetailsTransaction_${e.item2.txid}_cardKey"),
+                                      "contactDetailsTransaction_${e.item1}_${e.item2.txid}_cardKey"),
                                   transaction: e.item2,
                                   walletId: e.item1,
                                 ),
@@ -499,7 +499,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
                               ..._cachedTransactions.map(
                                 (e) => TransactionCard(
                                   key: Key(
-                                      "contactDetailsTransaction_${e.item2.txid}_cardKey"),
+                                      "contactDetailsTransaction_${e.item1}_${e.item2.txid}_cardKey"),
                                   transaction: e.item2,
                                   walletId: e.item1,
                                 ),

From e0ef78685ddf9450ac62140544b74c4c8ce8b068 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 07:10:28 -0600
Subject: [PATCH 290/426] empty contacts list fix

---
 .../address_book_views/address_book_view.dart | 175 +++++++-----------
 1 file changed, 69 insertions(+), 106 deletions(-)

diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index fd2a995cc..147e677e0 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -99,8 +99,6 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
-    // final addressBookEntriesFuture = ref.watch(
-    //     addressBookServiceProvider.select((value) => value.addressBookEntries));
     final contacts =
         ref.watch(addressBookServiceProvider.select((value) => value.contacts));
 
@@ -280,58 +278,41 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
             const SizedBox(
               height: 12,
             ),
-            // FutureBuilder(
-            //   future: addressBookEntriesFuture,
-            //   builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
-            //     if (snapshot.connectionState == ConnectionState.done &&
-            //         snapshot.hasData) {
-            //       _cacheFav = snapshot.data!;
-            //     }
-            //     if (_cacheFav == null) {
-            //       // TODO proper loading animation
-            //       return const LoadingIndicator();
-            //     } else {
-            //       if (_cacheFav!.isNotEmpty) {
-            //         return
-            RoundedWhiteContainer(
-              padding: EdgeInsets.all(!isDesktop ? 0 : 15),
-              child: Column(
-                children: [
-                  ...contacts
-                      .where((element) => element.addresses
-                          .where((e) => ref.watch(addressBookFilterProvider
-                              .select((value) => value.coins.contains(e.coin))))
-                          .isNotEmpty)
-                      .where((e) =>
-                          e.isFavorite &&
-                          ref
-                              .read(addressBookServiceProvider)
-                              .matches(_searchTerm, e))
-                      .where((element) => element.isFavorite)
-                      .map(
-                        (e) => AddressBookCard(
-                          key: Key("favContactCard_${e.id}_key"),
-                          contactId: e.id,
+            if (contacts.isNotEmpty)
+              RoundedWhiteContainer(
+                padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+                child: Column(
+                  children: [
+                    ...contacts
+                        .where((element) => element.addresses
+                            .where((e) => ref.watch(
+                                addressBookFilterProvider.select(
+                                    (value) => value.coins.contains(e.coin))))
+                            .isNotEmpty)
+                        .where((e) =>
+                            e.isFavorite &&
+                            ref
+                                .read(addressBookServiceProvider)
+                                .matches(_searchTerm, e))
+                        .where((element) => element.isFavorite)
+                        .map(
+                          (e) => AddressBookCard(
+                            key: Key("favContactCard_${e.id}_key"),
+                            contactId: e.id,
+                          ),
                         ),
-                      ),
-                ],
+                  ],
+                ),
+              ),
+            if (contacts.isEmpty)
+              RoundedWhiteContainer(
+                child: Center(
+                  child: Text(
+                    "Your favorite contacts will appear here",
+                    style: STextStyles.itemSubtitle(context),
+                  ),
+                ),
               ),
-            )
-            //         ;
-            //       } else {
-            //         return RoundedWhiteContainer(
-            //           child: Center(
-            //             child: Text(
-            //               "Your favorite contacts will appear here",
-            //               style: STextStyles.itemSubtitle(context),
-            //             ),
-            //           ),
-            //         );
-            //       }
-            //     }
-            //   },
-            // )
-            ,
             const SizedBox(
               height: 16,
             ),
@@ -342,64 +323,46 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
             const SizedBox(
               height: 12,
             ),
-            // FutureBuilder(
-            //   future: addressBookEntriesFuture,
-            //   builder: (_, AsyncSnapshot<List<Contact>> snapshot) {
-            //     if (snapshot.connectionState == ConnectionState.done &&
-            //         snapshot.hasData) {
-            //       _cache = snapshot.data!;
-            //     }
-            //     if (_cache == null) {
-            //       // TODO proper loading animation
-            //       return const LoadingIndicator();
-            //     } else {
-            //       if (_cache!.isNotEmpty) {
-            //         return
-            Column(
-              children: [
-                RoundedWhiteContainer(
-                  padding: EdgeInsets.all(!isDesktop ? 0 : 15),
-                  child: Padding(
-                    padding: const EdgeInsets.all(8.0),
-                    child: Column(
-                      children: [
-                        ...contacts
-                            .where((element) => element.addresses
-                                .where((e) => ref.watch(
-                                    addressBookFilterProvider.select((value) =>
-                                        value.coins.contains(e.coin))))
-                                .isNotEmpty)
-                            .where((e) => ref
-                                .read(addressBookServiceProvider)
-                                .matches(_searchTerm, e))
-                            .where((element) => !element.isFavorite)
-                            .map(
-                              (e) => AddressBookCard(
-                                key: Key("desktopContactCard_${e.id}_key"),
-                                contactId: e.id,
+            if (contacts.isNotEmpty)
+              Column(
+                children: [
+                  RoundedWhiteContainer(
+                    padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+                    child: Padding(
+                      padding: const EdgeInsets.all(8.0),
+                      child: Column(
+                        children: [
+                          ...contacts
+                              .where((element) => element.addresses
+                                  .where((e) => ref.watch(
+                                      addressBookFilterProvider.select(
+                                          (value) =>
+                                              value.coins.contains(e.coin))))
+                                  .isNotEmpty)
+                              .where((e) => ref
+                                  .read(addressBookServiceProvider)
+                                  .matches(_searchTerm, e))
+                              .map(
+                                (e) => AddressBookCard(
+                                  key: Key("desktopContactCard_${e.id}_key"),
+                                  contactId: e.id,
+                                ),
                               ),
-                            ),
-                      ],
+                        ],
+                      ),
                     ),
                   ),
+                ],
+              ),
+            if (contacts.isEmpty)
+              RoundedWhiteContainer(
+                child: Center(
+                  child: Text(
+                    "Your contacts will appear here",
+                    style: STextStyles.itemSubtitle(context),
+                  ),
                 ),
-              ],
-            )
-            //         ;
-            //       } else {
-            //         return RoundedWhiteContainer(
-            //           child: Center(
-            //             child: Text(
-            //               "Your contacts will appear here",
-            //               style: STextStyles.itemSubtitle(context),
-            //             ),
-            //           ),
-            //         );
-            //       }
-            //     }
-            //   },
-            // )
-            ,
+              ),
           ],
         ),
       ),

From 7cc3c71b0d1949401d79dcbe453b0dd3783a8a27 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 07:22:53 -0600
Subject: [PATCH 291/426] desktop addressbook search

---
 .../address_book_views/address_book_view.dart | 306 +++++++++---------
 .../desktop_address_book.dart                 |  14 +-
 2 files changed, 158 insertions(+), 162 deletions(-)

diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index 147e677e0..35e2601e2 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -23,11 +23,16 @@ import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
 class AddressBookView extends ConsumerStatefulWidget {
-  const AddressBookView({Key? key, this.coin}) : super(key: key);
+  const AddressBookView({
+    Key? key,
+    this.coin,
+    this.filterTerm,
+  }) : super(key: key);
 
   static const String routeName = "/addressBook";
 
   final Coin? coin;
+  final String? filterTerm;
 
   @override
   ConsumerState<AddressBookView> createState() => _AddressBookViewState();
@@ -37,9 +42,6 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
   late TextEditingController _searchController;
 
   final _searchFocusNode = FocusNode();
-  //
-  // List<Contact>? _cache;
-  // List<Contact>? _cacheFav;
 
   String _searchTerm = "";
 
@@ -198,7 +200,12 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
                     child: IntrinsicHeight(
                       child: Padding(
                         padding: const EdgeInsets.all(4),
-                        child: child,
+                        child: ConstrainedBox(
+                          constraints: BoxConstraints(
+                            minHeight: MediaQuery.of(context).size.height - 271,
+                          ),
+                          child: child,
+                        ),
                       ),
                     ),
                   ),
@@ -208,163 +215,156 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
           ),
         );
       },
-      child: ConstrainedBox(
-        constraints: BoxConstraints(
-          minHeight: MediaQuery.of(context).size.height - 271,
-        ),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            ClipRRect(
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-              child: !isDesktop
-                  ? TextField(
-                      autocorrect: Util.isDesktop ? false : true,
-                      enableSuggestions: Util.isDesktop ? false : true,
-                      controller: _searchController,
-                      focusNode: _searchFocusNode,
-                      onChanged: (value) {
-                        setState(() {
-                          _searchTerm = value;
-                        });
-                      },
-                      style: STextStyles.field(context),
-                      decoration: standardInputDecoration(
-                        "Search",
-                        _searchFocusNode,
-                        context,
-                      ).copyWith(
-                        prefixIcon: Padding(
-                          padding: const EdgeInsets.symmetric(
-                            horizontal: 10,
-                            vertical: 16,
-                          ),
-                          child: SvgPicture.asset(
-                            Assets.svg.search,
-                            width: 16,
-                            height: 16,
-                          ),
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.stretch,
+        children: [
+          ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: !isDesktop
+                ? TextField(
+                    autocorrect: Util.isDesktop ? false : true,
+                    enableSuggestions: Util.isDesktop ? false : true,
+                    controller: _searchController,
+                    focusNode: _searchFocusNode,
+                    onChanged: (value) {
+                      setState(() {
+                        _searchTerm = value;
+                      });
+                    },
+                    style: STextStyles.field(context),
+                    decoration: standardInputDecoration(
+                      "Search",
+                      _searchFocusNode,
+                      context,
+                    ).copyWith(
+                      prefixIcon: Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 10,
+                          vertical: 16,
+                        ),
+                        child: SvgPicture.asset(
+                          Assets.svg.search,
+                          width: 16,
+                          height: 16,
                         ),
-                        suffixIcon: _searchController.text.isNotEmpty
-                            ? Padding(
-                                padding: const EdgeInsets.only(right: 0),
-                                child: UnconstrainedBox(
-                                  child: Row(
-                                    children: [
-                                      TextFieldIconButton(
-                                        child: const XIcon(),
-                                        onTap: () async {
-                                          setState(() {
-                                            _searchController.text = "";
-                                          });
-                                        },
-                                      ),
-                                    ],
-                                  ),
-                                ),
-                              )
-                            : null,
                       ),
-                    )
-                  : null,
-            ),
-            if (!isDesktop) const SizedBox(height: 16),
-            Text(
-              "Favorites",
-              style: STextStyles.smallMed12(context),
-            ),
-            const SizedBox(
-              height: 12,
-            ),
-            if (contacts.isNotEmpty)
-              RoundedWhiteContainer(
-                padding: EdgeInsets.all(!isDesktop ? 0 : 15),
-                child: Column(
-                  children: [
-                    ...contacts
-                        .where((element) => element.addresses
-                            .where((e) => ref.watch(
-                                addressBookFilterProvider.select(
-                                    (value) => value.coins.contains(e.coin))))
-                            .isNotEmpty)
-                        .where((e) =>
-                            e.isFavorite &&
-                            ref
-                                .read(addressBookServiceProvider)
-                                .matches(_searchTerm, e))
-                        .where((element) => element.isFavorite)
-                        .map(
-                          (e) => AddressBookCard(
-                            key: Key("favContactCard_${e.id}_key"),
-                            contactId: e.id,
-                          ),
-                        ),
-                  ],
-                ),
-              ),
-            if (contacts.isEmpty)
-              RoundedWhiteContainer(
-                child: Center(
-                  child: Text(
-                    "Your favorite contacts will appear here",
-                    style: STextStyles.itemSubtitle(context),
-                  ),
-                ),
-              ),
-            const SizedBox(
-              height: 16,
-            ),
-            Text(
-              "All contacts",
-              style: STextStyles.smallMed12(context),
-            ),
-            const SizedBox(
-              height: 12,
-            ),
-            if (contacts.isNotEmpty)
-              Column(
-                children: [
-                  RoundedWhiteContainer(
-                    padding: EdgeInsets.all(!isDesktop ? 0 : 15),
-                    child: Padding(
-                      padding: const EdgeInsets.all(8.0),
-                      child: Column(
-                        children: [
-                          ...contacts
-                              .where((element) => element.addresses
-                                  .where((e) => ref.watch(
-                                      addressBookFilterProvider.select(
-                                          (value) =>
-                                              value.coins.contains(e.coin))))
-                                  .isNotEmpty)
-                              .where((e) => ref
-                                  .read(addressBookServiceProvider)
-                                  .matches(_searchTerm, e))
-                              .map(
-                                (e) => AddressBookCard(
-                                  key: Key("desktopContactCard_${e.id}_key"),
-                                  contactId: e.id,
+                      suffixIcon: _searchController.text.isNotEmpty
+                          ? Padding(
+                              padding: const EdgeInsets.only(right: 0),
+                              child: UnconstrainedBox(
+                                child: Row(
+                                  children: [
+                                    TextFieldIconButton(
+                                      child: const XIcon(),
+                                      onTap: () async {
+                                        setState(() {
+                                          _searchController.text = "";
+                                        });
+                                      },
+                                    ),
+                                  ],
                                 ),
                               ),
-                        ],
-                      ),
+                            )
+                          : null,
                     ),
-                  ),
+                  )
+                : null,
+          ),
+          if (!isDesktop) const SizedBox(height: 16),
+          Text(
+            "Favorites",
+            style: STextStyles.smallMed12(context),
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          if (contacts.isNotEmpty)
+            RoundedWhiteContainer(
+              padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+              child: Column(
+                children: [
+                  ...contacts
+                      .where((element) => element.addresses
+                          .where((e) => ref.watch(addressBookFilterProvider
+                              .select((value) => value.coins.contains(e.coin))))
+                          .isNotEmpty)
+                      .where((e) =>
+                          e.isFavorite &&
+                          ref
+                              .read(addressBookServiceProvider)
+                              .matches(widget.filterTerm ?? _searchTerm, e))
+                      .where((element) => element.isFavorite)
+                      .map(
+                        (e) => AddressBookCard(
+                          key: Key("favContactCard_${e.id}_key"),
+                          contactId: e.id,
+                        ),
+                      ),
                 ],
               ),
-            if (contacts.isEmpty)
-              RoundedWhiteContainer(
-                child: Center(
-                  child: Text(
-                    "Your contacts will appear here",
-                    style: STextStyles.itemSubtitle(context),
-                  ),
+            ),
+          if (contacts.isEmpty)
+            RoundedWhiteContainer(
+              child: Center(
+                child: Text(
+                  "Your favorite contacts will appear here",
+                  style: STextStyles.itemSubtitle(context),
                 ),
               ),
-          ],
-        ),
+            ),
+          const SizedBox(
+            height: 16,
+          ),
+          Text(
+            "All contacts",
+            style: STextStyles.smallMed12(context),
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          if (contacts.isNotEmpty)
+            Column(
+              children: [
+                RoundedWhiteContainer(
+                  padding: EdgeInsets.all(!isDesktop ? 0 : 15),
+                  child: Padding(
+                    padding: const EdgeInsets.all(8.0),
+                    child: Column(
+                      children: [
+                        ...contacts
+                            .where((element) => element.addresses
+                                .where((e) => ref.watch(
+                                    addressBookFilterProvider.select((value) =>
+                                        value.coins.contains(e.coin))))
+                                .isNotEmpty)
+                            .where((e) => ref
+                                .read(addressBookServiceProvider)
+                                .matches(widget.filterTerm ?? _searchTerm, e))
+                            .map(
+                              (e) => AddressBookCard(
+                                key: Key("desktopContactCard_${e.id}_key"),
+                                contactId: e.id,
+                              ),
+                            ),
+                      ],
+                    ),
+                  ),
+                ),
+              ],
+            ),
+          if (contacts.isEmpty)
+            RoundedWhiteContainer(
+              child: Center(
+                child: Text(
+                  "Your contacts will appear here",
+                  style: STextStyles.itemSubtitle(context),
+                ),
+              ),
+            ),
+        ],
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index ec40e5f60..d561de946 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -1,11 +1,9 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
-import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -34,11 +32,6 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
 
   late final FocusNode _searchFocusNode;
 
-  List<Contact>? _cache;
-  List<Contact>? _cacheFav;
-
-  late bool hasContacts = false;
-
   String _searchTerm = "";
 
   Future<void> selectCryptocurrency() async {
@@ -90,7 +83,6 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
-    final hasWallets = ref.watch(walletsChangeNotifierProvider).hasWallets;
 
     return DesktopScaffold(
       appBar: DesktopAppBar(
@@ -171,7 +163,11 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                   const SizedBox(
                     height: 24,
                   ),
-                  const AddressBookView(),
+                  Expanded(
+                    child: AddressBookView(
+                      filterTerm: _searchTerm,
+                    ),
+                  ),
                 ],
               ),
             ),

From 49103c86f1b63bd56563a0aa1167bcda5ee69cd8 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 09:00:10 -0600
Subject: [PATCH 292/426] desktop addressbook layout fix

---
 .../desktop_address_book.dart                 | 442 +++++++++++++-----
 1 file changed, 338 insertions(+), 104 deletions(-)

diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index d561de946..abb797aac 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -1,23 +1,31 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
+import 'package:stackwallet/models/contact.dart';
+import 'package:stackwallet/models/contact_address_entry.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
+import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/address_book_card.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
+import '../../../providers/providers.dart';
+import '../../../providers/ui/address_book_providers/address_book_filter_provider.dart';
+
 class DesktopAddressBook extends ConsumerStatefulWidget {
   const DesktopAddressBook({Key? key}) : super(key: key);
 
@@ -69,6 +77,46 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
     _searchController = TextEditingController();
     _searchFocusNode = FocusNode();
 
+    ref.refresh(addressBookFilterProvider);
+
+    // if (widget.coin == null) {
+    List<Coin> coins = Coin.values.where((e) => !(e == Coin.epicCash)).toList();
+    coins.remove(Coin.firoTestNet);
+
+    bool showTestNet = ref.read(prefsChangeNotifierProvider).showTestNetCoins;
+
+    if (showTestNet) {
+      ref.read(addressBookFilterProvider).addAll(coins, false);
+    } else {
+      ref.read(addressBookFilterProvider).addAll(
+          coins.getRange(0, coins.length - kTestNetCoinCount + 1), false);
+    }
+    // } else {
+    //   ref.read(addressBookFilterProvider).add(widget.coin!, false);
+    // }
+
+    WidgetsBinding.instance.addPostFrameCallback((_) async {
+      List<ContactAddressEntry> addresses = [];
+      final managers = ref.read(walletsChangeNotifierProvider).managers;
+      for (final manager in managers) {
+        addresses.add(
+          ContactAddressEntry(
+            coin: manager.coin,
+            address: await manager.currentReceivingAddress,
+            label: "Current Receiving",
+            other: manager.walletName,
+          ),
+        );
+      }
+      final self = Contact(
+        name: "My Stack",
+        addresses: addresses,
+        isFavorite: true,
+        id: "default",
+      );
+      await ref.read(addressBookServiceProvider).editContact(self);
+    });
+
     super.initState();
   }
 
@@ -83,6 +131,32 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
+    final contacts =
+        ref.watch(addressBookServiceProvider.select((value) => value.contacts));
+
+    final allContacts = contacts
+        .where((element) => element.addresses
+            .where((e) => ref.watch(addressBookFilterProvider
+                .select((value) => value.coins.contains(e.coin))))
+            .isNotEmpty)
+        .where((e) =>
+            ref.read(addressBookServiceProvider).matches(_searchTerm, e));
+
+    final favorites = contacts
+        .where((element) => element.addresses
+            .where((e) => ref.watch(addressBookFilterProvider
+                .select((value) => value.coins.contains(e.coin))))
+            .isNotEmpty)
+        .where((e) =>
+            e.isFavorite &&
+            ref.read(addressBookServiceProvider).matches(_searchTerm, e))
+        .where((element) => element.isFavorite);
+
+    print("=========================================================");
+    print("contacts: ${contacts.length}");
+    print("favorites: ${favorites.length}");
+    print("allContacts: ${allContacts.length}");
+    print("=========================================================");
 
     return DesktopScaffold(
       appBar: DesktopAppBar(
@@ -100,121 +174,281 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
         ),
       ),
       body: Padding(
-        padding: const EdgeInsets.all(24),
-        child: Row(
+        padding: const EdgeInsets.only(
+          left: 24,
+          right: 24,
+          bottom: 24,
+        ),
+        child: DesktopAddressBookScaffold(
+          controlsLeft: ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
+              controller: _searchController,
+              focusNode: _searchFocusNode,
+              onChanged: (value) {
+                setState(() {
+                  _searchTerm = value;
+                });
+              },
+              style: STextStyles.field(context),
+              decoration: standardInputDecoration(
+                "Search",
+                _searchFocusNode,
+                context,
+              ).copyWith(
+                prefixIcon: Padding(
+                  padding: const EdgeInsets.symmetric(
+                    horizontal: 10,
+                    vertical: 20,
+                  ),
+                  child: SvgPicture.asset(
+                    Assets.svg.search,
+                    width: 16,
+                    height: 16,
+                  ),
+                ),
+                suffixIcon: _searchController.text.isNotEmpty
+                    ? Padding(
+                        padding: const EdgeInsets.only(right: 0),
+                        child: UnconstrainedBox(
+                          child: Row(
+                            children: [
+                              TextFieldIconButton(
+                                child: const XIcon(),
+                                onTap: () async {
+                                  setState(() {
+                                    _searchController.text = "";
+                                  });
+                                },
+                              ),
+                            ],
+                          ),
+                        ),
+                      )
+                    : null,
+              ),
+            ),
+          ),
+          controlsRight: Row(
+            mainAxisAlignment: MainAxisAlignment.end,
+            children: [
+              SecondaryButton(
+                width: 184,
+                label: "Filter",
+                desktopMed: true,
+                icon: SvgPicture.asset(
+                  Assets.svg.filter,
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .buttonTextSecondary,
+                ),
+                onPressed: selectCryptocurrency,
+              ),
+              const SizedBox(
+                width: 20,
+              ),
+              PrimaryButton(
+                width: 184,
+                label: "Add new",
+                desktopMed: true,
+                icon: SvgPicture.asset(
+                  Assets.svg.circlePlus,
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .buttonTextPrimary,
+                ),
+                onPressed: newContact,
+              ),
+            ],
+          ),
+          filterItems: Container(),
+          upperLabel: favorites.isEmpty && allContacts.isEmpty
+              ? null
+              : Text(
+                  favorites.isEmpty ? "All contacts" : "Favorites",
+                  style: STextStyles.smallMed12(context),
+                ),
+          lowerLabel: favorites.isEmpty
+              ? null
+              : Padding(
+                  padding: const EdgeInsets.only(
+                    top: 20,
+                    bottom: 12,
+                  ),
+                  child: Text(
+                    "All contacts",
+                    style: STextStyles.smallMed12(context),
+                  ),
+                ),
+          favorites: favorites.isNotEmpty
+              ? RoundedWhiteContainer(
+                  padding: const EdgeInsets.all(0),
+                  child: Column(
+                    children: [
+                      ...favorites.map(
+                        (e) => AddressBookCard(
+                          key: Key("favContactCard_${e.id}_key"),
+                          contactId: e.id,
+                        ),
+                      ),
+                    ],
+                  ),
+                )
+              : RoundedWhiteContainer(
+                  child: Center(
+                    child: Text(
+                      "Your favorite contacts will appear here",
+                      style: STextStyles.itemSubtitle(context),
+                    ),
+                  ),
+                ),
+          all: allContacts.isNotEmpty
+              ? Column(
+                  children: [
+                    RoundedWhiteContainer(
+                      padding: const EdgeInsets.all(0),
+                      child: Padding(
+                        padding: const EdgeInsets.all(8.0),
+                        child: Column(
+                          children: [
+                            ...allContacts.map(
+                              (e) => AddressBookCard(
+                                key: Key("desktopContactCard_${e.id}_key"),
+                                contactId: e.id,
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ],
+                )
+              : RoundedWhiteContainer(
+                  child: Center(
+                    child: Text(
+                      "Your contacts will appear here",
+                      style: STextStyles.itemSubtitle(context),
+                    ),
+                  ),
+                ),
+          details: Container(
+            color: Colors.purple,
+          ),
+        ),
+      ),
+    );
+  }
+}
+
+class DesktopAddressBookScaffold extends StatelessWidget {
+  const DesktopAddressBookScaffold({
+    Key? key,
+    required this.controlsLeft,
+    required this.controlsRight,
+    required this.filterItems,
+    required this.upperLabel,
+    required this.lowerLabel,
+    required this.favorites,
+    required this.all,
+    required this.details,
+  }) : super(key: key);
+
+  final Widget? controlsLeft;
+  final Widget? controlsRight;
+  final Widget? filterItems;
+  final Widget? upperLabel;
+  final Widget? lowerLabel;
+  final Widget? favorites;
+  final Widget? all;
+  final Widget? details;
+
+  static const double weirdRowHeight = 30;
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Row(
+          mainAxisAlignment: MainAxisAlignment.end,
           children: [
             Expanded(
               flex: 6,
-              child: Column(
-                children: [
-                  ClipRRect(
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
-                    ),
-                    child: TextField(
-                      autocorrect: Util.isDesktop ? false : true,
-                      enableSuggestions: Util.isDesktop ? false : true,
-                      controller: _searchController,
-                      focusNode: _searchFocusNode,
-                      onChanged: (value) {
-                        setState(() {
-                          _searchTerm = value;
-                        });
-                      },
-                      style: STextStyles.field(context),
-                      decoration: standardInputDecoration(
-                        "Search",
-                        _searchFocusNode,
-                        context,
-                      ).copyWith(
-                        prefixIcon: Padding(
-                          padding: const EdgeInsets.symmetric(
-                            horizontal: 10,
-                            vertical: 20,
-                          ),
-                          child: SvgPicture.asset(
-                            Assets.svg.search,
-                            width: 16,
-                            height: 16,
-                          ),
-                        ),
-                        suffixIcon: _searchController.text.isNotEmpty
-                            ? Padding(
-                                padding: const EdgeInsets.only(right: 0),
-                                child: UnconstrainedBox(
-                                  child: Row(
-                                    children: [
-                                      TextFieldIconButton(
-                                        child: const XIcon(),
-                                        onTap: () async {
-                                          setState(() {
-                                            _searchController.text = "";
-                                          });
-                                        },
-                                      ),
-                                    ],
-                                  ),
-                                ),
-                              )
-                            : null,
-                      ),
-                    ),
-                  ),
-                  const SizedBox(
-                    height: 24,
-                  ),
-                  Expanded(
-                    child: AddressBookView(
-                      filterTerm: _searchTerm,
-                    ),
-                  ),
-                ],
-              ),
+              child: controlsLeft ?? Container(),
             ),
             const SizedBox(
               width: 20,
             ),
             Expanded(
               flex: 5,
-              child: Column(
-                children: [
-                  Row(
-                    children: [
-                      SecondaryButton(
-                        width: 184,
-                        label: "Filter",
-                        desktopMed: true,
-                        icon: SvgPicture.asset(
-                          Assets.svg.filter,
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .buttonTextSecondary,
-                        ),
-                        onPressed: selectCryptocurrency,
-                      ),
-                      const SizedBox(
-                        width: 20,
-                      ),
-                      PrimaryButton(
-                        width: 184,
-                        label: "Add new",
-                        desktopMed: true,
-                        icon: SvgPicture.asset(
-                          Assets.svg.circlePlus,
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .buttonTextPrimary,
-                        ),
-                        onPressed: newContact,
-                      ),
-                    ],
-                  ),
-                ],
-              ),
+              child: controlsRight ?? Container(),
             ),
           ],
         ),
-      ),
+        const SizedBox(
+          height: 20,
+        ),
+        Row(
+          children: [
+            Expanded(
+              child: filterItems ?? Container(),
+            ),
+          ],
+        ),
+        Expanded(
+          child: Row(
+            children: [
+              Expanded(
+                flex: 6,
+                child: LayoutBuilder(
+                  builder: (context, constraints) {
+                    return SingleChildScrollView(
+                      child: ConstrainedBox(
+                        constraints: BoxConstraints(
+                          minHeight: constraints.maxHeight,
+                        ),
+                        child: IntrinsicHeight(
+                          child: Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              SizedBox(
+                                height: weirdRowHeight,
+                                child: upperLabel,
+                              ),
+                              favorites ?? Container(),
+                              lowerLabel ?? Container(),
+                              all ?? Container(),
+                            ],
+                          ),
+                        ),
+                      ),
+                    );
+                  },
+                ),
+              ),
+              const SizedBox(
+                width: 20,
+              ),
+              Expanded(
+                flex: 5,
+                child: Column(
+                  children: [
+                    const SizedBox(
+                      height: weirdRowHeight,
+                    ),
+                    Expanded(
+                      child: details ?? Container(),
+                    ),
+                  ],
+                ),
+              ),
+            ],
+          ),
+        )
+      ],
     );
   }
 }

From 8c0a6f5669de3d0bf4aa8b6c5329ff4d09e6bc30 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 09:04:54 -0600
Subject: [PATCH 293/426]  address book search fixes

---
 .../address_book_views/address_book_view.dart |  1 +
 .../desktop_address_book.dart                 | 51 +++++++++----------
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index 35e2601e2..cdc9fb5b7 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -261,6 +261,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
                                       onTap: () async {
                                         setState(() {
                                           _searchController.text = "";
+                                          _searchTerm = "";
                                         });
                                       },
                                     ),
diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index abb797aac..51b075284 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -152,12 +152,6 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
             ref.read(addressBookServiceProvider).matches(_searchTerm, e))
         .where((element) => element.isFavorite);
 
-    print("=========================================================");
-    print("contacts: ${contacts.length}");
-    print("favorites: ${favorites.length}");
-    print("allContacts: ${allContacts.length}");
-    print("=========================================================");
-
     return DesktopScaffold(
       appBar: DesktopAppBar(
         isCompactHeight: true,
@@ -222,6 +216,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                                 onTap: () async {
                                   setState(() {
                                     _searchController.text = "";
+                                    _searchTerm = "";
                                   });
                                 },
                               ),
@@ -284,8 +279,18 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                     style: STextStyles.smallMed12(context),
                   ),
                 ),
-          favorites: favorites.isNotEmpty
-              ? RoundedWhiteContainer(
+          favorites: favorites.isEmpty
+              ? contacts.isNotEmpty
+                  ? null
+                  : RoundedWhiteContainer(
+                      child: Center(
+                        child: Text(
+                          "Your favorite contacts will appear here",
+                          style: STextStyles.itemSubtitle(context),
+                        ),
+                      ),
+                    )
+              : RoundedWhiteContainer(
                   padding: const EdgeInsets.all(0),
                   child: Column(
                     children: [
@@ -297,17 +302,19 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                       ),
                     ],
                   ),
-                )
-              : RoundedWhiteContainer(
-                  child: Center(
-                    child: Text(
-                      "Your favorite contacts will appear here",
-                      style: STextStyles.itemSubtitle(context),
-                    ),
-                  ),
                 ),
-          all: allContacts.isNotEmpty
-              ? Column(
+          all: allContacts.isEmpty
+              ? contacts.isNotEmpty
+                  ? null
+                  : RoundedWhiteContainer(
+                      child: Center(
+                        child: Text(
+                          "Your contacts will appear here",
+                          style: STextStyles.itemSubtitle(context),
+                        ),
+                      ),
+                    )
+              : Column(
                   children: [
                     RoundedWhiteContainer(
                       padding: const EdgeInsets.all(0),
@@ -326,14 +333,6 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                       ),
                     ),
                   ],
-                )
-              : RoundedWhiteContainer(
-                  child: Center(
-                    child: Text(
-                      "Your contacts will appear here",
-                      style: STextStyles.itemSubtitle(context),
-                    ),
-                  ),
                 ),
           details: Container(
             color: Colors.purple,

From 72248d6a644807d6f7410c31529ae3a57869066f Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 10:12:19 -0600
Subject: [PATCH 294/426] expandable fix

---
 .../wallet_network_settings_view.dart                  | 10 +++++-----
 .../sub_widgets/contact_list_item.dart                 |  2 +-
 lib/widgets/expandable.dart                            |  6 +++---
 lib/widgets/node_card.dart                             |  6 +++---
 4 files changed, 12 insertions(+), 12 deletions(-)

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 accf244eb..3044467aa 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
@@ -77,7 +77,7 @@ class _WalletNetworkSettingsViewState
 
   late double _percent;
   late int _blocksRemaining;
-  bool _advancedIsExpanded = true;
+  bool _advancedIsExpanded = false;
 
   Future<void> _attemptRescan() async {
     if (!Platform.isLinux) await Wakelock.enable();
@@ -855,8 +855,8 @@ class _WalletNetworkSettingsViewState
                     ),
                     SvgPicture.asset(
                       _advancedIsExpanded
-                          ? Assets.svg.chevronDown
-                          : Assets.svg.chevronUp,
+                          ? Assets.svg.chevronUp
+                          : Assets.svg.chevronDown,
                       width: 12,
                       height: 6,
                       color: Theme.of(context)
@@ -877,11 +877,11 @@ class _WalletNetworkSettingsViewState
                         text: "Rescan",
                         onTap: () async {
                           await Navigator.of(context).push(
-                             FadePageRoute<void>(
+                            FadePageRoute<void>(
                               ConfirmFullRescanDialog(
                                 onConfirm: _attemptRescan,
                               ),
-                             const RouteSettings(),
+                              const RouteSettings(),
                             ),
                           );
                           // await showDialog<dynamic>(
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
index e030f9882..7acfaae9e 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
@@ -58,7 +58,7 @@ class _ContactListItemState extends ConsumerState<ContactListItem> {
           ),
           child: AddressBookCard(
             contactId: contactId,
-            indicatorDown: _state == ExpandableState.expanded,
+            indicatorDown: _state,
           ),
         ),
         body: Column(
diff --git a/lib/widgets/expandable.dart b/lib/widgets/expandable.dart
index 47726d6d6..737f4ce7d 100644
--- a/lib/widgets/expandable.dart
+++ b/lib/widgets/expandable.dart
@@ -1,8 +1,8 @@
 import 'package:flutter/material.dart';
 
 enum ExpandableState {
-  expanded,
   collapsed,
+  expanded,
 }
 
 class ExpandableController {
@@ -45,11 +45,11 @@ class _ExpandableState extends State<Expandable> with TickerProviderStateMixin {
   Future<void> toggle() async {
     if (animation.isDismissed) {
       await animationController.forward();
-      _toggleState = ExpandableState.collapsed;
+      _toggleState = ExpandableState.expanded;
       widget.onExpandChanged?.call(_toggleState);
     } else if (animation.isCompleted) {
       await animationController.reverse();
-      _toggleState = ExpandableState.expanded;
+      _toggleState = ExpandableState.collapsed;
       widget.onExpandChanged?.call(_toggleState);
     }
     controller?.state = _toggleState;
diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart
index 1da7e9012..c3fb36c70 100644
--- a/lib/widgets/node_card.dart
+++ b/lib/widgets/node_card.dart
@@ -46,7 +46,7 @@ class NodeCard extends ConsumerStatefulWidget {
 class _NodeCardState extends ConsumerState<NodeCard> {
   String _status = "Disconnected";
   late final String nodeId;
-  bool _advancedIsExpanded = true;
+  bool _advancedIsExpanded = false;
 
   Future<void> _notifyWalletsOfUpdatedNode(WidgetRef ref) async {
     final managers = ref
@@ -367,8 +367,8 @@ class _NodeCardState extends ConsumerState<NodeCard> {
                 if (isDesktop)
                   SvgPicture.asset(
                     _advancedIsExpanded
-                        ? Assets.svg.chevronDown
-                        : Assets.svg.chevronUp,
+                        ? Assets.svg.chevronUp
+                        : Assets.svg.chevronDown,
                     width: 12,
                     height: 6,
                     color: Theme.of(context)

From df810c2a1449458e046aa994960b2ccdd5cbeecb Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 10:12:38 -0600
Subject: [PATCH 295/426] "send from" contacts fix

---
 .../address_book_address_chooser.dart         | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
index 9f309a08e..92dd9f6fc 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
@@ -200,12 +200,19 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
 
                 final favorites = pullOutFavorites(contacts);
 
-                return ListView.builder(
+                final totalLength = favorites.length +
+                    contacts.length +
+                    2; // +2 for "fav" and "all" headers
+
+                return ListView.separated(
                   primary: false,
                   shrinkWrap: true,
-                  itemCount: favorites.length +
-                      contacts.length +
-                      2, // +2 for "fav" and "all" headers
+                  itemCount: totalLength,
+                  separatorBuilder: (context, index) {
+                    return const SizedBox(
+                      height: 10,
+                    );
+                  },
                   itemBuilder: (context, index) {
                     if (index == 0) {
                       return Padding(
@@ -220,7 +227,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
                               STextStyles.desktopTextExtraExtraSmall(context),
                         ),
                       );
-                    } else if (index <= favorites.length) {
+                    } else if (index < favorites.length + 1) {
                       final id = favorites[index - 1].id;
                       return ContactListItem(
                         key: Key("contactContactListItem_${id}_key"),
@@ -241,7 +248,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
                         ),
                       );
                     } else {
-                      final id = contacts[index - favorites.length - 1].id;
+                      final id = contacts[index - favorites.length - 2].id;
                       return ContactListItem(
                         key: Key("contactContactListItem_${id}_key"),
                         contactId: id,

From b988342bb146d1085f64527b4ce28f7765532c6f Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 10:12:59 -0600
Subject: [PATCH 296/426] "send from" contact card fix

---
 lib/widgets/address_book_card.dart | 185 +++++++++++++++--------------
 1 file changed, 95 insertions(+), 90 deletions(-)

diff --git a/lib/widgets/address_book_card.dart b/lib/widgets/address_book_card.dart
index c9ac86052..329e35fdf 100644
--- a/lib/widgets/address_book_card.dart
+++ b/lib/widgets/address_book_card.dart
@@ -9,6 +9,8 @@ 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/conditional_parent.dart';
+import 'package:stackwallet/widgets/expandable.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class AddressBookCard extends ConsumerStatefulWidget {
@@ -19,7 +21,7 @@ class AddressBookCard extends ConsumerStatefulWidget {
   }) : super(key: key);
 
   final String contactId;
-  final bool? indicatorDown;
+  final ExpandableState? indicatorDown;
 
   @override
   ConsumerState<AddressBookCard> createState() => _AddressBookCardState();
@@ -58,108 +60,111 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
       }
     }
 
-    return RoundedWhiteContainer(
-      padding: const EdgeInsets.all(4),
-      child: RawMaterialButton(
-        // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-        padding: const EdgeInsets.all(0),
-        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-        shape: RoundedRectangleBorder(
-          borderRadius: BorderRadius.circular(
-            Constants.size.circularBorderRadius,
-          ),
-        ),
-        onPressed: () {
-          showDialog<void>(
-            context: context,
-            useSafeArea: true,
-            barrierDismissible: true,
-            builder: (_) => ContactPopUp(
-              contactId: contact.id,
+    return ConditionalParent(
+      condition: !isDesktop,
+      child: Row(
+        children: [
+          Container(
+            width: 32,
+            height: 32,
+            decoration: BoxDecoration(
+              color: contact.id == "default"
+                  ? Theme.of(context)
+                      .extension<StackColors>()!
+                      .myStackContactIconBG
+                  : Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldDefaultBG,
+              borderRadius: BorderRadius.circular(32),
             ),
-          );
-        },
-        child: Padding(
-          padding: const EdgeInsets.all(8.0),
-          child: Row(
-            children: [
-              Container(
-                width: 32,
-                height: 32,
-                decoration: BoxDecoration(
-                  color: contact.id == "default"
-                      ? Theme.of(context)
-                          .extension<StackColors>()!
-                          .myStackContactIconBG
-                      : Theme.of(context)
-                          .extension<StackColors>()!
-                          .textFieldDefaultBG,
-                  borderRadius: BorderRadius.circular(32),
-                ),
-                child: contact.id == "default"
+            child: contact.id == "default"
+                ? Center(
+                    child: SvgPicture.asset(
+                      Assets.svg.stackIcon(context),
+                      width: 20,
+                    ),
+                  )
+                : contact.emojiChar != null
                     ? Center(
-                        child: SvgPicture.asset(
-                          Assets.svg.stackIcon(context),
-                          width: 20,
-                        ),
+                        child: Text(contact.emojiChar!),
                       )
-                    : contact.emojiChar != null
-                        ? Center(
-                            child: Text(contact.emojiChar!),
-                          )
-                        : Center(
-                            child: SvgPicture.asset(
-                              Assets.svg.user,
-                              width: 18,
-                            ),
-                          ),
-              ),
-              const SizedBox(
-                width: 12,
-              ),
-              if (isDesktop)
+                    : Center(
+                        child: SvgPicture.asset(
+                          Assets.svg.user,
+                          width: 18,
+                        ),
+                      ),
+          ),
+          const SizedBox(
+            width: 12,
+          ),
+          if (isDesktop)
+            Text(
+              contact.name,
+              style: STextStyles.itemSubtitle12(context),
+            ),
+          if (isDesktop)
+            const SizedBox(
+              width: 16,
+            ),
+          if (isDesktop)
+            Text(
+              coinsString,
+              style: STextStyles.label(context),
+            ),
+          if (!isDesktop)
+            Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              children: [
                 Text(
                   contact.name,
                   style: STextStyles.itemSubtitle12(context),
                 ),
-              if (isDesktop)
                 const SizedBox(
-                  width: 16,
+                  height: 4,
                 ),
-              if (isDesktop)
                 Text(
                   coinsString,
                   style: STextStyles.label(context),
                 ),
-              if (!isDesktop)
-                Column(
-                  crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
-                    Text(
-                      contact.name,
-                      style: STextStyles.itemSubtitle12(context),
-                    ),
-                    const SizedBox(
-                      height: 4,
-                    ),
-                    Text(
-                      coinsString,
-                      style: STextStyles.label(context),
-                    ),
-                  ],
-                ),
-              if (isDesktop) const Spacer(),
-              // if (isDesktop)
-              //   SvgPicture.asset(
-              //     widget.indicatorDown == true
-              //         ? Assets.svg.chevronDown
-              //         : Assets.svg.chevronUp,
-              //     width: 10,
-              //     height: 5,
-              //     color:
-              //         Theme.of(context).extension<StackColors>()!.textSubtitle2,
-              //   ),
-            ],
+              ],
+            ),
+          if (isDesktop) const Spacer(),
+          if (isDesktop)
+            SvgPicture.asset(
+              widget.indicatorDown == ExpandableState.collapsed
+                  ? Assets.svg.chevronDown
+                  : Assets.svg.chevronUp,
+              width: 10,
+              height: 5,
+              color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
+            ),
+        ],
+      ),
+      builder: (child) => RoundedWhiteContainer(
+        padding: const EdgeInsets.all(4),
+        child: RawMaterialButton(
+          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+          padding: const EdgeInsets.all(0),
+          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+          ),
+          onPressed: () {
+            showDialog<void>(
+              context: context,
+              useSafeArea: true,
+              barrierDismissible: true,
+              builder: (_) => ContactPopUp(
+                contactId: contact.id,
+              ),
+            );
+          },
+          child: Padding(
+            padding: const EdgeInsets.all(8.0),
+            child: child,
           ),
         ),
       ),

From b6e4357c3c63a6567fbdf2809ffb0b9c4b22b4a7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 10:23:12 -0600
Subject: [PATCH 297/426] wallet overview syncing/loading balance text color
 fix for darkmode

---
 .../wallet_view/sub_widgets/desktop_wallet_summary.dart         | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
index 7a9e93467..f4bfed976 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
@@ -243,7 +243,7 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
                               fontSize: 24,
                               color: Theme.of(context)
                                   .extension<StackColors>()!
-                                  .textFavoriteCard,
+                                  .textDark,
                             ),
                           ),
                           if (externalCalls)

From 81d5f757b3d039528f523df3af8b8d1cca21a81e Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 11:10:26 -0600
Subject: [PATCH 298/426] WIP: desktop contact details

---
 .../desktop_address_book.dart                 | 252 ++++++++----------
 .../desktop_address_book_scaffold.dart        | 111 ++++++++
 .../subwidgets/desktop_contact_details.dart   | 191 +++++++++++++
 lib/widgets/address_book_card.dart            |   9 +-
 4 files changed, 427 insertions(+), 136 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_book_scaffold.dart
 create mode 100644 lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart

diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index 51b075284..5e22a6089 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -5,7 +5,11 @@ import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/models/contact_address_entry.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_book_scaffold.dart';
+import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
+import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/providers/ui/address_book_providers/address_book_filter_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
@@ -19,13 +23,11 @@ import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-import '../../../providers/providers.dart';
-import '../../../providers/ui/address_book_providers/address_book_filter_provider.dart';
-
 class DesktopAddressBook extends ConsumerStatefulWidget {
   const DesktopAddressBook({Key? key}) : super(key: key);
 
@@ -42,6 +44,8 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
 
   String _searchTerm = "";
 
+  String? currentContactId;
+
   Future<void> selectCryptocurrency() async {
     await showDialog<dynamic>(
       context: context,
@@ -139,8 +143,9 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
             .where((e) => ref.watch(addressBookFilterProvider
                 .select((value) => value.coins.contains(e.coin))))
             .isNotEmpty)
-        .where((e) =>
-            ref.read(addressBookServiceProvider).matches(_searchTerm, e));
+        .where(
+            (e) => ref.read(addressBookServiceProvider).matches(_searchTerm, e))
+        .toList();
 
     final favorites = contacts
         .where((element) => element.addresses
@@ -150,7 +155,8 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
         .where((e) =>
             e.isFavorite &&
             ref.read(addressBookServiceProvider).matches(_searchTerm, e))
-        .where((element) => element.isFavorite);
+        .where((element) => element.isFavorite)
+        .toList();
 
     return DesktopScaffold(
       appBar: DesktopAppBar(
@@ -294,12 +300,56 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                   padding: const EdgeInsets.all(0),
                   child: Column(
                     children: [
-                      ...favorites.map(
-                        (e) => AddressBookCard(
-                          key: Key("favContactCard_${e.id}_key"),
-                          contactId: e.id,
+                      for (int i = 0; i < favorites.length; i++)
+                        Column(
+                          children: [
+                            if (i > 0)
+                              Container(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .background,
+                                height: 1,
+                              ),
+                            Padding(
+                              padding: const EdgeInsets.all(4),
+                              child: RoundedContainer(
+                                padding: const EdgeInsets.all(0),
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorDark
+                                    .withOpacity(
+                                      currentContactId == favorites[i].id
+                                          ? 0.08
+                                          : 0,
+                                    ),
+                                child: RawMaterialButton(
+                                  onPressed: () {
+                                    setState(() {
+                                      currentContactId = favorites[i].id;
+                                    });
+                                  },
+                                  padding: const EdgeInsets.symmetric(
+                                    horizontal: 20,
+                                    vertical: 16,
+                                  ),
+                                  materialTapTargetSize:
+                                      MaterialTapTargetSize.shrinkWrap,
+                                  shape: RoundedRectangleBorder(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                  ),
+                                  child: AddressBookCard(
+                                    key: Key(
+                                        "favContactCard_${favorites[i].id}_key"),
+                                    contactId: favorites[i].id,
+                                    desktopSendFrom: false,
+                                  ),
+                                ),
+                              ),
+                            ),
+                          ],
                         ),
-                      ),
                     ],
                   ),
                 ),
@@ -318,136 +368,70 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                   children: [
                     RoundedWhiteContainer(
                       padding: const EdgeInsets.all(0),
-                      child: Padding(
-                        padding: const EdgeInsets.all(8.0),
-                        child: Column(
-                          children: [
-                            ...allContacts.map(
-                              (e) => AddressBookCard(
-                                key: Key("desktopContactCard_${e.id}_key"),
-                                contactId: e.id,
-                              ),
+                      child: Column(
+                        children: [
+                          for (int i = 0; i < allContacts.length; i++)
+                            Column(
+                              children: [
+                                if (i > 0)
+                                  Container(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .background,
+                                    height: 1,
+                                  ),
+                                Padding(
+                                  padding: const EdgeInsets.all(4),
+                                  child: RoundedContainer(
+                                    padding: const EdgeInsets.all(0),
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark
+                                        .withOpacity(
+                                          currentContactId == allContacts[i].id
+                                              ? 0.08
+                                              : 0,
+                                        ),
+                                    child: RawMaterialButton(
+                                      onPressed: () {
+                                        setState(() {
+                                          currentContactId = allContacts[i].id;
+                                        });
+                                      },
+                                      padding: const EdgeInsets.symmetric(
+                                        horizontal: 20,
+                                        vertical: 16,
+                                      ),
+                                      materialTapTargetSize:
+                                          MaterialTapTargetSize.shrinkWrap,
+                                      shape: RoundedRectangleBorder(
+                                        borderRadius: BorderRadius.circular(
+                                          Constants.size.circularBorderRadius,
+                                        ),
+                                      ),
+                                      child: AddressBookCard(
+                                        key: Key(
+                                            "favContactCard_${allContacts[i].id}_key"),
+                                        contactId: allContacts[i].id,
+                                        desktopSendFrom: false,
+                                      ),
+                                    ),
+                                  ),
+                                ),
+                              ],
                             ),
-                          ],
-                        ),
+                        ],
                       ),
                     ),
                   ],
                 ),
-          details: Container(
-            color: Colors.purple,
-          ),
+          details: currentContactId == null
+              ? Container()
+              : DesktopContactDetails(
+                  contactId: currentContactId!,
+                ),
         ),
       ),
     );
   }
 }
-
-class DesktopAddressBookScaffold extends StatelessWidget {
-  const DesktopAddressBookScaffold({
-    Key? key,
-    required this.controlsLeft,
-    required this.controlsRight,
-    required this.filterItems,
-    required this.upperLabel,
-    required this.lowerLabel,
-    required this.favorites,
-    required this.all,
-    required this.details,
-  }) : super(key: key);
-
-  final Widget? controlsLeft;
-  final Widget? controlsRight;
-  final Widget? filterItems;
-  final Widget? upperLabel;
-  final Widget? lowerLabel;
-  final Widget? favorites;
-  final Widget? all;
-  final Widget? details;
-
-  static const double weirdRowHeight = 30;
-
-  @override
-  Widget build(BuildContext context) {
-    return Column(
-      children: [
-        Row(
-          mainAxisAlignment: MainAxisAlignment.end,
-          children: [
-            Expanded(
-              flex: 6,
-              child: controlsLeft ?? Container(),
-            ),
-            const SizedBox(
-              width: 20,
-            ),
-            Expanded(
-              flex: 5,
-              child: controlsRight ?? Container(),
-            ),
-          ],
-        ),
-        const SizedBox(
-          height: 20,
-        ),
-        Row(
-          children: [
-            Expanded(
-              child: filterItems ?? Container(),
-            ),
-          ],
-        ),
-        Expanded(
-          child: Row(
-            children: [
-              Expanded(
-                flex: 6,
-                child: LayoutBuilder(
-                  builder: (context, constraints) {
-                    return SingleChildScrollView(
-                      child: ConstrainedBox(
-                        constraints: BoxConstraints(
-                          minHeight: constraints.maxHeight,
-                        ),
-                        child: IntrinsicHeight(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              SizedBox(
-                                height: weirdRowHeight,
-                                child: upperLabel,
-                              ),
-                              favorites ?? Container(),
-                              lowerLabel ?? Container(),
-                              all ?? Container(),
-                            ],
-                          ),
-                        ),
-                      ),
-                    );
-                  },
-                ),
-              ),
-              const SizedBox(
-                width: 20,
-              ),
-              Expanded(
-                flex: 5,
-                child: Column(
-                  children: [
-                    const SizedBox(
-                      height: weirdRowHeight,
-                    ),
-                    Expanded(
-                      child: details ?? Container(),
-                    ),
-                  ],
-                ),
-              ),
-            ],
-          ),
-        )
-      ],
-    );
-  }
-}
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_book_scaffold.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_book_scaffold.dart
new file mode 100644
index 000000000..f32ea1f7f
--- /dev/null
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_book_scaffold.dart
@@ -0,0 +1,111 @@
+import 'package:flutter/widgets.dart';
+
+class DesktopAddressBookScaffold extends StatelessWidget {
+  const DesktopAddressBookScaffold({
+    Key? key,
+    required this.controlsLeft,
+    required this.controlsRight,
+    required this.filterItems,
+    required this.upperLabel,
+    required this.lowerLabel,
+    required this.favorites,
+    required this.all,
+    required this.details,
+  }) : super(key: key);
+
+  final Widget? controlsLeft;
+  final Widget? controlsRight;
+  final Widget? filterItems;
+  final Widget? upperLabel;
+  final Widget? lowerLabel;
+  final Widget? favorites;
+  final Widget? all;
+  final Widget? details;
+
+  static const double weirdRowHeight = 30;
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Row(
+          mainAxisAlignment: MainAxisAlignment.end,
+          children: [
+            Expanded(
+              flex: 6,
+              child: controlsLeft ?? Container(),
+            ),
+            const SizedBox(
+              width: 20,
+            ),
+            Expanded(
+              flex: 5,
+              child: controlsRight ?? Container(),
+            ),
+          ],
+        ),
+        const SizedBox(
+          height: 20,
+        ),
+        Row(
+          children: [
+            Expanded(
+              child: filterItems ?? Container(),
+            ),
+          ],
+        ),
+        Expanded(
+          child: Row(
+            children: [
+              Expanded(
+                flex: 6,
+                child: LayoutBuilder(
+                  builder: (context, constraints) {
+                    return SingleChildScrollView(
+                      primary: false,
+                      child: ConstrainedBox(
+                        constraints: BoxConstraints(
+                          minHeight: constraints.maxHeight,
+                        ),
+                        child: IntrinsicHeight(
+                          child: Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              SizedBox(
+                                height: weirdRowHeight,
+                                child: upperLabel,
+                              ),
+                              favorites ?? Container(),
+                              lowerLabel ?? Container(),
+                              all ?? Container(),
+                            ],
+                          ),
+                        ),
+                      ),
+                    );
+                  },
+                ),
+              ),
+              const SizedBox(
+                width: 20,
+              ),
+              Expanded(
+                flex: 5,
+                child: Column(
+                  children: [
+                    const SizedBox(
+                      height: weirdRowHeight,
+                    ),
+                    Expanded(
+                      child: details ?? Container(),
+                    ),
+                  ],
+                ),
+              ),
+            ],
+          ),
+        )
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
new file mode 100644
index 000000000..5184b2293
--- /dev/null
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
@@ -0,0 +1,191 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/models/contact_address_entry.dart';
+import 'package:stackwallet/providers/global/address_book_service_provider.dart';
+import 'package:stackwallet/utilities/assets.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';
+
+class DesktopContactDetails extends ConsumerStatefulWidget {
+  const DesktopContactDetails({
+    Key? key,
+    required this.contactId,
+  }) : super(key: key);
+
+  final String contactId;
+
+  @override
+  ConsumerState<DesktopContactDetails> createState() =>
+      _DesktopContactDetailsState();
+}
+
+class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
+  @override
+  Widget build(BuildContext context) {
+    final contact = ref.watch(addressBookServiceProvider
+        .select((value) => value.getContactById(widget.contactId)));
+
+    return Column(
+      children: [
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: [
+            Row(
+              children: [
+                Container(
+                  width: 32,
+                  height: 32,
+                  decoration: BoxDecoration(
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .textFieldDefaultBG,
+                    borderRadius: BorderRadius.circular(32),
+                  ),
+                  child: contact.id == "default"
+                      ? Center(
+                          child: SvgPicture.asset(
+                            Assets.svg.stackIcon(context),
+                            width: 20,
+                          ),
+                        )
+                      : contact.emojiChar != null
+                          ? Center(
+                              child: Text(contact.emojiChar!),
+                            )
+                          : Center(
+                              child: SvgPicture.asset(
+                                Assets.svg.user,
+                                width: 18,
+                              ),
+                            ),
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Text(
+                  contact.name,
+                  style: STextStyles.desktopTextSmall(context),
+                ),
+              ],
+            ),
+            SecondaryButton(
+              label: "Options",
+              onPressed: () {},
+            ),
+          ],
+        ),
+        const SizedBox(
+          height: 24,
+        ),
+        Expanded(
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Column(
+                      children: [
+                        Row(
+                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          children: [
+                            Text(
+                              "Addresses",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                  context),
+                            ),
+                            BlueTextButton(
+                              text: "Add new",
+                              onTap: () {},
+                            ),
+                          ],
+                        ),
+                        Column(
+                          mainAxisSize: MainAxisSize.min,
+                          children: [
+                            ...contact.addresses
+                                .map((e) => AddressCard(entry: e)),
+                          ],
+                        )
+                      ],
+                    ),
+                  ),
+                ),
+              );
+            },
+          ),
+        ),
+      ],
+    );
+  }
+}
+
+class AddressCard extends StatelessWidget {
+  const AddressCard({
+    Key? key,
+    required this.entry,
+  }) : super(key: key);
+
+  final ContactAddressEntry entry;
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      children: [
+        SvgPicture.asset(
+          Assets.svg.iconFor(
+            coin: entry.coin,
+          ),
+          height: 32,
+          width: 32,
+        ),
+        const SizedBox(
+          width: 16,
+        ),
+        Column(
+          mainAxisSize: MainAxisSize.min,
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            SelectableText(
+              "${entry.label} ${entry.coin.ticker}",
+              style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark,
+              ),
+            ),
+            const SizedBox(
+              height: 2,
+            ),
+            SelectableText(
+              entry.address,
+              style: STextStyles.desktopTextExtraExtraSmall(context),
+            ),
+            const SizedBox(
+              height: 8,
+            ),
+            Row(
+              children: [
+                BlueTextButton(
+                  text: "Copy",
+                  onTap: () {},
+                ),
+                const SizedBox(
+                  width: 16,
+                ),
+                BlueTextButton(
+                  text: "Edit",
+                  onTap: () {},
+                ),
+              ],
+            )
+          ],
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/widgets/address_book_card.dart b/lib/widgets/address_book_card.dart
index 329e35fdf..b79f89662 100644
--- a/lib/widgets/address_book_card.dart
+++ b/lib/widgets/address_book_card.dart
@@ -18,10 +18,12 @@ class AddressBookCard extends ConsumerStatefulWidget {
     Key? key,
     required this.contactId,
     this.indicatorDown,
+    this.desktopSendFrom = true,
   }) : super(key: key);
 
   final String contactId;
   final ExpandableState? indicatorDown;
+  final bool desktopSendFrom;
 
   @override
   ConsumerState<AddressBookCard> createState() => _AddressBookCardState();
@@ -30,10 +32,12 @@ class AddressBookCard extends ConsumerStatefulWidget {
 class _AddressBookCardState extends ConsumerState<AddressBookCard> {
   late final String contactId;
   late final bool isDesktop;
+  late final bool desktopSendFrom;
 
   @override
   void initState() {
     contactId = widget.contactId;
+    desktopSendFrom = widget.desktopSendFrom;
     isDesktop = Util.isDesktop;
     super.initState();
   }
@@ -107,6 +111,7 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
             const SizedBox(
               width: 16,
             ),
+          if (isDesktop && !desktopSendFrom) const Spacer(),
           if (isDesktop)
             Text(
               coinsString,
@@ -129,8 +134,8 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
                 ),
               ],
             ),
-          if (isDesktop) const Spacer(),
-          if (isDesktop)
+          if (isDesktop && desktopSendFrom) const Spacer(),
+          if (isDesktop && desktopSendFrom)
             SvgPicture.asset(
               widget.indicatorDown == ExpandableState.collapsed
                   ? Assets.svg.chevronDown

From 9063749eadcaf1ab414b37db7591d55049efcfe3 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 17 Nov 2022 10:42:11 -0700
Subject: [PATCH 299/426] anonymize button added to firo wallet

---
 .../wallet_view/desktop_wallet_view.dart      | 135 ++++++++++++++++++
 1 file changed, 135 insertions(+)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 81b531632..769f22157 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -1,5 +1,6 @@
 import 'dart:async';
 
+import 'package:decimal/decimal.dart';
 import 'package:event_bus/event_bus.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -15,6 +16,7 @@ import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_vie
 import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/ui/transaction_filter_provider.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/exchange/change_now/change_now_exchange.dart';
@@ -27,8 +29,11 @@ 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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/custom_loading_overlay.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/hover_text_field.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -165,6 +170,75 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
     }
   }
 
+  Future<void> attemptAnonymize() async {
+    final managerProvider =
+        ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
+
+    bool shouldPop = false;
+    unawaited(
+      showDialog(
+        context: context,
+        builder: (context) => WillPopScope(
+          child: const CustomLoadingOverlay(
+            message: "Anonymizing balance",
+            eventBus: null,
+          ),
+          onWillPop: () async => shouldPop,
+        ),
+      ),
+    );
+    final firoWallet = ref.read(managerProvider).wallet as FiroWallet;
+
+    final publicBalance = await firoWallet.availablePublicBalance();
+    if (publicBalance <= Decimal.zero) {
+      shouldPop = true;
+      if (mounted) {
+        Navigator.of(context).popUntil(
+          ModalRoute.withName(DesktopWalletView.routeName),
+        );
+        unawaited(
+          showFloatingFlushBar(
+            type: FlushBarType.info,
+            message: "No funds available to anonymize!",
+            context: context,
+          ),
+        );
+      }
+      return;
+    }
+
+    try {
+      await firoWallet.anonymizeAllPublicFunds();
+      shouldPop = true;
+      if (mounted) {
+        Navigator.of(context).popUntil(
+          ModalRoute.withName(DesktopWalletView.routeName),
+        );
+        unawaited(
+          showFloatingFlushBar(
+            type: FlushBarType.success,
+            message: "Anonymize transaction submitted",
+            context: context,
+          ),
+        );
+      }
+    } catch (e) {
+      shouldPop = true;
+      if (mounted) {
+        Navigator.of(context).popUntil(
+          ModalRoute.withName(DesktopWalletView.routeName),
+        );
+        await showDialog<dynamic>(
+          context: context,
+          builder: (_) => StackOkDialog(
+            title: "Anonymize all failed",
+            message: "Reason: $e",
+          ),
+        );
+      }
+    }
+  }
+
   @override
   void initState() {
     controller = TextEditingController();
@@ -333,6 +407,67 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                         : WalletSyncStatus.synced,
                   ),
                   const Spacer(),
+                  if (coin == Coin.firo) const SizedBox(width: 10),
+                  if (coin == Coin.firo)
+                    SecondaryButton(
+                      width: 180,
+                      desktopMed: true,
+                      label: "Anonymize funds",
+                      onPressed: () async {
+                        await showDialog<void>(
+                          context: context,
+                          barrierDismissible: false,
+                          builder: (context) => DesktopDialog(
+                            maxWidth: 500,
+                            maxHeight: 210,
+                            child: Padding(
+                              padding: const EdgeInsets.symmetric(
+                                  horizontal: 32, vertical: 20),
+                              child: Column(
+                                children: [
+                                  Text(
+                                    "Attention!",
+                                    style: STextStyles.desktopH2(context),
+                                  ),
+                                  const SizedBox(height: 16),
+                                  Text(
+                                    "You're about to anonymize all of your public funds.",
+                                    style:
+                                        STextStyles.desktopTextSmall(context),
+                                  ),
+                                  const SizedBox(height: 32),
+                                  Row(
+                                    mainAxisAlignment: MainAxisAlignment.center,
+                                    children: [
+                                      SecondaryButton(
+                                        width: 180,
+                                        desktopMed: true,
+                                        label: "Cancel",
+                                        onPressed: () {
+                                          Navigator.of(context).pop();
+                                        },
+                                      ),
+                                      const SizedBox(width: 20),
+                                      PrimaryButton(
+                                        width: 180,
+                                        desktopMed: true,
+                                        label: "Continue",
+                                        onPressed: () {
+                                          Navigator.of(context).pop();
+
+                                          unawaited(attemptAnonymize());
+                                        },
+                                      )
+                                    ],
+                                  ),
+                                ],
+                              ),
+                            ),
+                          ),
+                        );
+                      },
+                    ),
+                  if (coin == Coin.firo) const SizedBox(width: 16),
                   SecondaryButton(
                     width: 180,
                     desktopMed: true,

From 9e7c1ccf9dc20e08ac74120e7faf866e1db3f103 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 11:46:44 -0600
Subject: [PATCH 300/426] button size enum

---
 .../subviews/address_book_filter_view.dart    |  4 +-
 .../generate_receiving_uri_qr_code_view.dart  |  5 +-
 .../send_view/confirm_transaction_view.dart   |  4 +-
 .../building_transaction_dialog.dart          |  2 +-
 .../global_settings_view/currency_view.dart   |  4 +-
 .../add_edit_node_view.dart                   |  8 +-
 .../manage_nodes_views/node_details_view.dart |  4 +-
 .../create_backup_view.dart                   |  8 +-
 .../dialogs/cancel_stack_restore_dialog.dart  |  4 +-
 .../edit_auto_backup_view.dart                |  4 +-
 .../restore_from_file_view.dart               |  4 +-
 .../stack_restore_progress_view.dart          |  8 +-
 .../sub_widgets/confirm_full_rescan.dart      |  4 +-
 .../all_transactions_view.dart                |  2 +-
 .../transaction_search_filter_view.dart       |  4 +-
 .../desktop_address_book.dart                 |  4 +-
 .../wallet_view/desktop_wallet_view.dart      |  2 +-
 .../sub_widgets/desktop_auth_send.dart        |  4 +-
 .../sub_widgets/desktop_receive.dart          |  2 +-
 .../wallet_view/sub_widgets/desktop_send.dart | 10 +--
 .../backup_and_restore_settings.dart          | 14 +--
 .../create_auto_backup.dart                   |  7 +-
 .../enable_backup_dialog.dart                 |  4 +-
 .../currency_settings/currency_settings.dart  |  2 +-
 .../language_settings/language_settings.dart  |  2 +-
 .../home/settings_menu/security_settings.dart |  4 +-
 .../syncing_preferences_settings.dart         |  2 +-
 lib/widgets/desktop/custom_text_button.dart   | 10 +++
 lib/widgets/desktop/primary_button.dart       | 86 +++++++++++++++---
 lib/widgets/desktop/secondary_button.dart     | 89 ++++++++++++++++---
 30 files changed, 225 insertions(+), 86 deletions(-)

diff --git a/lib/pages/address_book_views/subviews/address_book_filter_view.dart b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
index df779331e..c129251d5 100644
--- a/lib/pages/address_book_views/subviews/address_book_filter_view.dart
+++ b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
@@ -159,7 +159,7 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
                   children: [
                     SecondaryButton(
                       width: 248,
-                      desktopMed: true,
+                      buttonHeight: ButtonHeight.l,
                       enabled: true,
                       label: "Cancel",
                       onPressed: () {
@@ -169,7 +169,7 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
                     // const SizedBox(width: 16),
                     PrimaryButton(
                       width: 248,
-                      desktopMed: true,
+                      buttonHeight: ButtonHeight.l,
                       enabled: true,
                       label: "Apply",
                       onPressed: () {
diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
index 981def830..05cedb148 100644
--- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
+++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
@@ -530,7 +530,7 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                       });
                     }
                   : onGeneratePressed,
-              desktopMed: true,
+              buttonHeight: ButtonHeight.l,
             ),
             if (isDesktop && didGenerate)
               Row(
@@ -586,7 +586,6 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                                 if (!isDesktop)
                                   SecondaryButton(
                                     width: 170,
-                                    desktopMed: true,
                                     onPressed: () async {
                                       await _capturePng(false);
                                     },
@@ -606,7 +605,7 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                                   ),
                                 PrimaryButton(
                                   width: 170,
-                                  desktopMed: true,
+                                  buttonHeight: ButtonHeight.l,
                                   onPressed: () async {
                                     // TODO: add save functionality instead of share
                                     // save works on linux at the moment
diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index 0f1692c08..8f7afb0bb 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -148,7 +148,7 @@ class _ConfirmTransactionViewState
                         const Spacer(),
                         Expanded(
                           child: PrimaryButton(
-                            desktopMed: true,
+                            buttonHeight: ButtonHeight.l,
                             label: "Ok",
                             onPressed: Navigator.of(context).pop,
                           ),
@@ -780,7 +780,7 @@ class _ConfirmTransactionViewState
                   : const EdgeInsets.all(0),
               child: PrimaryButton(
                 label: "Send",
-                desktopMed: true,
+                buttonHeight: ButtonHeight.l,
                 onPressed: () async {
                   final dynamic unlocked;
 
diff --git a/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart b/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
index 045218e54..1f6c95df6 100644
--- a/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
+++ b/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
@@ -77,7 +77,7 @@ class _RestoringDialogState extends State<BuildingTransactionDialog>
             height: 40,
           ),
           SecondaryButton(
-            desktopMed: true,
+            buttonHeight: ButtonHeight.l,
             label: "Cancel",
             onPressed: () {
               onCancel.call();
diff --git a/lib/pages/settings_views/global_settings_view/currency_view.dart b/lib/pages/settings_views/global_settings_view/currency_view.dart
index 4e8fd5f6e..dccf2d61b 100644
--- a/lib/pages/settings_views/global_settings_view/currency_view.dart
+++ b/lib/pages/settings_views/global_settings_view/currency_view.dart
@@ -189,7 +189,7 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
                     Expanded(
                       child: SecondaryButton(
                         label: "Cancel",
-                        desktopMed: true,
+                        buttonHeight: ButtonHeight.l,
                         onPressed: Navigator.of(context).pop,
                       ),
                     ),
@@ -199,7 +199,7 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
                     Expanded(
                       child: PrimaryButton(
                         label: "Save changes",
-                        desktopMed: true,
+                        buttonHeight: ButtonHeight.l,
                         onPressed: () {
                           ref.read(prefsChangeNotifierProvider).currency =
                               current;
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 890953caf..606c4481f 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -238,7 +238,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
                                 Expanded(
                                   child: SecondaryButton(
                                     label: "Cancel",
-                                    desktopMed: true,
+                                    buttonHeight: ButtonHeight.l,
                                     onPressed: () => Navigator.of(
                                       context,
                                       rootNavigator: true,
@@ -251,7 +251,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
                                 Expanded(
                                   child: PrimaryButton(
                                     label: "Save",
-                                    desktopMed: true,
+                                    buttonHeight: ButtonHeight.l,
                                     onPressed: () => Navigator.of(
                                       context,
                                       rootNavigator: true,
@@ -561,7 +561,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
                   child: SecondaryButton(
                     label: "Test connection",
                     enabled: testConnectionEnabled,
-                    desktopMed: true,
+                    buttonHeight: ButtonHeight.l,
                     onPressed: testConnectionEnabled
                         ? () async {
                             await _testConnection();
@@ -578,7 +578,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
                     child: PrimaryButton(
                       label: "Save",
                       enabled: saveEnabled,
-                      desktopMed: true,
+                      buttonHeight: ButtonHeight.l,
                       onPressed: saveEnabled ? attemptSave : null,
                     ),
                   ),
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index a80a64147..3d49ae6f7 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -349,7 +349,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
                 Expanded(
                   child: SecondaryButton(
                     label: "Test connection",
-                    desktopMed: true,
+                    buttonHeight: ButtonHeight.l,
                     onPressed: () async {
                       await _testConnection(ref, context);
                     },
@@ -364,7 +364,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
                     child: !nodeId.startsWith("default")
                         ? PrimaryButton(
                             label: _desktopReadOnly ? "Edit" : "Save",
-                            desktopMed: true,
+                            buttonHeight: ButtonHeight.l,
                             onPressed: () async {
                               final shouldSave = _desktopReadOnly == false;
                               setState(() {
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 02556beb9..0609e4b1b 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -562,7 +562,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                       Consumer(builder: (context, ref, __) {
                         return PrimaryButton(
                           width: 183,
-                          desktopMed: true,
+                          buttonHeight: ButtonHeight.l,
                           label: "Create backup",
                           enabled: shouldEnableCreate,
                           onPressed: !shouldEnableCreate
@@ -735,7 +735,9 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                                                             child:
                                                                 PrimaryButton(
                                                               label: "Ok",
-                                                              desktopMed: true,
+                                                              buttonHeight:
+                                                                  ButtonHeight
+                                                                      .l,
                                                               onPressed: () {
                                                                 int count = 0;
                                                                 Navigator.of(
@@ -778,7 +780,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                       ),
                       SecondaryButton(
                         width: 183,
-                        desktopMed: true,
+                        buttonHeight: ButtonHeight.l,
                         label: "Cancel",
                         onPressed: () {},
                       ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart
index a9f4e134d..905cdea72 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/dialogs/cancel_stack_restore_dialog.dart
@@ -85,7 +85,7 @@ class CancelStackRestoreDialog extends StatelessWidget {
                       children: [
                         SecondaryButton(
                           width: 248,
-                          desktopMed: true,
+                          buttonHeight: ButtonHeight.l,
                           enabled: true,
                           label: "Keep restoring",
                           onPressed: () {
@@ -95,7 +95,7 @@ class CancelStackRestoreDialog extends StatelessWidget {
                         const SizedBox(width: 20),
                         PrimaryButton(
                           width: 248,
-                          desktopMed: true,
+                          buttonHeight: ButtonHeight.l,
                           enabled: true,
                           label: "Cancel anyway",
                           onPressed: () {
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
index 76d280980..310be9f2b 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
@@ -754,7 +754,7 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
                 Expanded(
                   child: SecondaryButton(
                     label: "Cancel",
-                    desktopMed: true,
+                    buttonHeight: ButtonHeight.l,
                     onPressed: Navigator.of(context).pop,
                   ),
                 ),
@@ -764,7 +764,7 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
                 Expanded(
                   child: PrimaryButton(
                     label: "Save",
-                    desktopMed: true,
+                    buttonHeight: ButtonHeight.l,
                     enabled: shouldEnableCreate,
                     onPressed: onSavePressed,
                   ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index c5ccfa6b3..9be6af4cb 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -389,7 +389,7 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                       children: [
                         PrimaryButton(
                           width: 183,
-                          desktopMed: true,
+                          buttonHeight: ButtonHeight.l,
                           label: "Restore",
                           enabled: !(passwordController.text.isEmpty ||
                               fileLocationController.text.isEmpty),
@@ -566,7 +566,7 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                         ),
                         SecondaryButton(
                           width: 183,
-                          desktopMed: true,
+                          buttonHeight: ButtonHeight.l,
                           label: "Cancel",
                           onPressed: () {},
                         ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
index e34def23d..c7f53378d 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
@@ -108,7 +108,7 @@ class _StackRestoreProgressViewState
     //     children: [
     //       SecondaryButton(
     //         width: 248,
-    //         desktopMed: true,
+    //          buttonHeight: ButtonHeight.l,
     //         enabled: true,
     //         label: "Keep restoring",
     //         onPressed: () {
@@ -118,7 +118,7 @@ class _StackRestoreProgressViewState
     //       const SizedBox(width: 16),
     //       PrimaryButton(
     //         width: 248,
-    //         desktopMed: true,
+    //          buttonHeight: ButtonHeight.l,
     //         enabled: true,
     //         label: "Cancel anyway",
     //         onPressed: () {
@@ -681,7 +681,7 @@ class _StackRestoreProgressViewState
                           _success
                               ? PrimaryButton(
                                   width: 248,
-                                  desktopMed: true,
+                                  buttonHeight: ButtonHeight.l,
                                   enabled: true,
                                   label: "Done",
                                   onPressed: () async {
@@ -690,7 +690,7 @@ class _StackRestoreProgressViewState
                                 )
                               : SecondaryButton(
                                   width: 248,
-                                  desktopMed: true,
+                                  buttonHeight: ButtonHeight.l,
                                   enabled: true,
                                   label: "Cancel restore process",
                                   onPressed: () async {
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
index 950d8d79e..150af6ac5 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
@@ -58,7 +58,7 @@ class ConfirmFullRescanDialog extends StatelessWidget {
                     children: [
                       Expanded(
                         child: SecondaryButton(
-                          desktopMed: true,
+                          buttonHeight: ButtonHeight.l,
                           onPressed: Navigator.of(context).pop,
                           label: "Cancel",
                         ),
@@ -68,7 +68,7 @@ class ConfirmFullRescanDialog extends StatelessWidget {
                       ),
                       Expanded(
                         child: PrimaryButton(
-                          desktopMed: true,
+                          buttonHeight: ButtonHeight.l,
                           onPressed: () {
                             Navigator.of(context).pop();
                             onConfirm.call();
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 d41877a9a..95dcc8126 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -385,7 +385,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
                     ),
                   if (isDesktop)
                     SecondaryButton(
-                      desktopMed: isDesktop,
+                      buttonHeight: ButtonHeight.l,
                       width: 200,
                       label: "Filter",
                       icon: SvgPicture.asset(
diff --git a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
index abebb71e4..d135ea276 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
@@ -869,7 +869,7 @@ class _TransactionSearchViewState
             Expanded(
               child: SecondaryButton(
                 label: "Cancel",
-                desktopMed: isDesktop,
+                buttonHeight: ButtonHeight.l,
                 onPressed: () async {
                   if (!isDesktop) {
                     if (FocusScope.of(context).hasFocus) {
@@ -919,7 +919,7 @@ class _TransactionSearchViewState
             ),
             Expanded(
               child: PrimaryButton(
-                desktopMed: isDesktop,
+                buttonHeight: ButtonHeight.l,
                 onPressed: () async {
                   await _onApplyPressed();
                 },
diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index 5e22a6089..f028a3424 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -240,7 +240,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
               SecondaryButton(
                 width: 184,
                 label: "Filter",
-                desktopMed: true,
+                buttonHeight: ButtonHeight.l,
                 icon: SvgPicture.asset(
                   Assets.svg.filter,
                   color: Theme.of(context)
@@ -255,7 +255,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
               PrimaryButton(
                 width: 184,
                 label: "Add new",
-                desktopMed: true,
+                buttonHeight: ButtonHeight.l,
                 icon: SvgPicture.asset(
                   Assets.svg.circlePlus,
                   color: Theme.of(context)
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 769f22157..952194244 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -470,7 +470,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                   if (coin == Coin.firo) const SizedBox(width: 16),
                   SecondaryButton(
                     width: 180,
-                    desktopMed: true,
+                    buttonHeight: ButtonHeight.l,
                     onPressed: () {
                       _onExchangePressed(context);
                     },
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
index 566a82b35..9f863c8a4 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
@@ -142,7 +142,7 @@ class _DesktopAuthSendState extends ConsumerState<DesktopAuthSend> {
             Expanded(
               child: SecondaryButton(
                 label: "Cancel",
-                desktopMed: true,
+                buttonHeight: ButtonHeight.l,
                 onPressed: Navigator.of(context).pop,
               ),
             ),
@@ -153,7 +153,7 @@ class _DesktopAuthSendState extends ConsumerState<DesktopAuthSend> {
               child: PrimaryButton(
                 enabled: _confirmEnabled,
                 label: "Confirm",
-                desktopMed: true,
+                buttonHeight: ButtonHeight.l,
                 onPressed: () async {
                   // TODO show spinner while verifying passphrase
 
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
index 9a59c3ec1..3de4ed1e3 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
@@ -199,7 +199,7 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
           ),
         if (coin != Coin.epicCash)
           SecondaryButton(
-            desktopMed: true,
+            buttonHeight: ButtonHeight.l,
             onPressed: generateNewAddress,
             label: "Generate new address",
           ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index af2c2517a..336dd7b4e 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -145,7 +145,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                       right: 32,
                     ),
                     child: SecondaryButton(
-                      desktopMed: true,
+                      buttonHeight: ButtonHeight.l,
                       label: "Ok",
                       onPressed: () {
                         Navigator.of(context).pop();
@@ -232,7 +232,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                       children: [
                         Expanded(
                           child: SecondaryButton(
-                            desktopMed: true,
+                            buttonHeight: ButtonHeight.l,
                             label: "Cancel",
                             onPressed: () {
                               Navigator.of(context).pop(false);
@@ -244,7 +244,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                         ),
                         Expanded(
                           child: PrimaryButton(
-                            desktopMed: true,
+                            buttonHeight: ButtonHeight.l,
                             label: "Yes",
                             onPressed: () {
                               Navigator.of(context).pop(true);
@@ -399,7 +399,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                         ),
                         child: Expanded(
                           child: SecondaryButton(
-                            desktopMed: true,
+                            buttonHeight: ButtonHeight.l,
                             label: "Yes",
                             onPressed: () {
                               Navigator.of(
@@ -1385,7 +1385,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           height: 36,
         ),
         PrimaryButton(
-          desktopMed: true,
+          buttonHeight: ButtonHeight.l,
           label: "Preview send",
           enabled: ref.watch(previewTxButtonStateProvider.state).state,
           onPressed: ref.watch(previewTxButtonStateProvider.state).state
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 7d70d4d0f..37f3f35a6 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -240,7 +240,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                             children: [
                               Expanded(
                                 child: SecondaryButton(
-                                  desktopMed: true,
+                                  buttonHeight: ButtonHeight.l,
                                   label: "Cancel",
                                   onPressed: Navigator.of(context).pop,
                                 ),
@@ -248,7 +248,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                               const SizedBox(width: 16),
                               Expanded(
                                 child: PrimaryButton(
-                                  desktopMed: true,
+                                  buttonHeight: ButtonHeight.l,
                                   label: "Disable",
                                   onPressed: () {
                                     ref
@@ -422,7 +422,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                 padding: const EdgeInsets.all(10),
                                 child: !isEnabledAutoBackup
                                     ? PrimaryButton(
-                                        desktopMed: true,
+                                        buttonHeight: ButtonHeight.l,
                                         width: 200,
                                         label: "Enable auto backup",
                                         onPressed: () {
@@ -467,7 +467,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                           Row(
                                             children: [
                                               PrimaryButton(
-                                                desktopMed: true,
+                                                buttonHeight: ButtonHeight.l,
                                                 width: 190,
                                                 label: "Disable auto backup",
                                                 onPressed: () {
@@ -476,7 +476,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                               ),
                                               const SizedBox(width: 16),
                                               SecondaryButton(
-                                                desktopMed: true,
+                                                buttonHeight: ButtonHeight.l,
                                                 width: 190,
                                                 label: "Edit auto backup",
                                                 onPressed: () {
@@ -560,7 +560,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                         child: CreateBackupView(),
                                       )
                                     : PrimaryButton(
-                                        desktopMed: true,
+                                        buttonHeight: ButtonHeight.l,
                                         width: 200,
                                         label: "Create manual backup",
                                         onPressed: () {
@@ -642,7 +642,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                         child: RestoreFromFileView(),
                                       )
                                     : PrimaryButton(
-                                        desktopMed: true,
+                                        buttonHeight: ButtonHeight.l,
                                         width: 200,
                                         label: "Restore backup",
                                         onPressed: () {
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 663136dba..df80da732 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -556,7 +556,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                 Expanded(
                   child: SecondaryButton(
                     label: "Cancel",
-                    desktopMed: true,
+                    buttonHeight: ButtonHeight.l,
                     onPressed: Navigator.of(context).pop,
                   ),
                 ),
@@ -565,7 +565,7 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                 ),
                 Expanded(
                   child: PrimaryButton(
-                    desktopMed: true,
+                    buttonHeight: ButtonHeight.l,
                     label: "Enable Auto Backup",
                     enabled: shouldEnableCreate,
                     onPressed: !shouldEnableCreate
@@ -792,7 +792,8 @@ class _CreateAutoBackup extends ConsumerState<CreateAutoBackup> {
                                                   Expanded(
                                                     child: PrimaryButton(
                                                       label: "Ok",
-                                                      desktopMed: true,
+                                                      buttonHeight:
+                                                          ButtonHeight.l,
                                                       onPressed: () {
                                                         Navigator.of(context)
                                                             .pop();
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
index 6496253d5..df9f18b52 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/enable_backup_dialog.dart
@@ -59,7 +59,7 @@ class EnableBackupDialog extends StatelessWidget {
               children: [
                 Expanded(
                   child: SecondaryButton(
-                    desktopMed: true,
+                    buttonHeight: ButtonHeight.l,
                     label: "Cancel",
                     onPressed: () {
                       Navigator.of(context).pop();
@@ -71,7 +71,7 @@ class EnableBackupDialog extends StatelessWidget {
                 ),
                 Expanded(
                   child: PrimaryButton(
-                    desktopMed: true,
+                    buttonHeight: ButtonHeight.l,
                     label: "Continue",
                     onPressed: () {
                       Navigator.of(context).pop();
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index 4c4225ce4..0740157ad 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -108,7 +108,7 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
                       ),
                       child: PrimaryButton(
                         width: 210,
-                        desktopMed: true,
+                        buttonHeight: ButtonHeight.l,
                         enabled: true,
                         label: "Change currency",
                         onPressed: () {
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
index 08aeb9bc3..db636ba17 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
@@ -85,7 +85,7 @@ class _LanguageOptionSettings extends ConsumerState<LanguageOptionSettings> {
                       ),
                       child: PrimaryButton(
                         width: 210,
-                        desktopMed: true,
+                        buttonHeight: ButtonHeight.l,
                         enabled: true,
                         label: "Change language",
                         onPressed: () {
diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index 9f870440b..f2853e6f5 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -485,7 +485,7 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
                                   const SizedBox(height: 20),
                                   PrimaryButton(
                                     width: 160,
-                                    desktopMed: true,
+                                    buttonHeight: ButtonHeight.l,
                                     enabled: shouldEnableSave,
                                     label: "Save changes",
                                     onPressed: () async {
@@ -503,7 +503,7 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
                             )
                           : PrimaryButton(
                               width: 210,
-                              desktopMed: true,
+                              buttonHeight: ButtonHeight.l,
                               enabled: true,
                               label: "Set up new password",
                               onPressed: () {
diff --git a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
index 408b93e15..ae11f5582 100644
--- a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
@@ -83,7 +83,7 @@ class _SyncingPreferencesSettings
                       ),
                       child: PrimaryButton(
                         width: 210,
-                        desktopMed: true,
+                        buttonHeight: ButtonHeight.l,
                         enabled: true,
                         label: "Change preferences",
                         onPressed: () {},
diff --git a/lib/widgets/desktop/custom_text_button.dart b/lib/widgets/desktop/custom_text_button.dart
index b96a697b8..90b75c459 100644
--- a/lib/widgets/desktop/custom_text_button.dart
+++ b/lib/widgets/desktop/custom_text_button.dart
@@ -1,6 +1,16 @@
 import 'package:flutter/material.dart';
 import 'package:stackwallet/utilities/util.dart';
 
+enum ButtonHeight {
+  xxs,
+  xs,
+  s,
+  m,
+  l,
+  xl,
+  xxl,
+}
+
 class CustomTextButtonBase extends StatelessWidget {
   const CustomTextButtonBase({
     Key? key,
diff --git a/lib/widgets/desktop/primary_button.dart b/lib/widgets/desktop/primary_button.dart
index f3c900c34..134ff36c3 100644
--- a/lib/widgets/desktop/primary_button.dart
+++ b/lib/widgets/desktop/primary_button.dart
@@ -4,6 +4,8 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/desktop/custom_text_button.dart';
 
+export 'package:stackwallet/widgets/desktop/custom_text_button.dart';
+
 class PrimaryButton extends StatelessWidget {
   const PrimaryButton({
     Key? key,
@@ -13,7 +15,7 @@ class PrimaryButton extends StatelessWidget {
     this.icon,
     this.onPressed,
     this.enabled = true,
-    this.desktopMed = false,
+    this.buttonHeight,
   }) : super(key: key);
 
   final double? width;
@@ -22,23 +24,44 @@ class PrimaryButton extends StatelessWidget {
   final VoidCallback? onPressed;
   final bool enabled;
   final Widget? icon;
-  final bool desktopMed;
+  final ButtonHeight? buttonHeight;
 
   TextStyle getStyle(bool isDesktop, BuildContext context) {
     if (isDesktop) {
-      if (desktopMed) {
-        return STextStyles.desktopTextExtraSmall(context).copyWith(
-          color: enabled
-              ? Theme.of(context).extension<StackColors>()!.buttonTextPrimary
-              : Theme.of(context)
-                  .extension<StackColors>()!
-                  .buttonTextPrimaryDisabled,
-        );
-      } else {
+      if (buttonHeight == null) {
         return enabled
             ? STextStyles.desktopButtonEnabled(context)
             : STextStyles.desktopButtonDisabled(context);
       }
+
+      switch (buttonHeight!) {
+        case ButtonHeight.xxs:
+        case ButtonHeight.xs:
+        case ButtonHeight.s:
+          return STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+            color: enabled
+                ? Theme.of(context).extension<StackColors>()!.buttonTextPrimary
+                : Theme.of(context)
+                    .extension<StackColors>()!
+                    .buttonTextPrimaryDisabled,
+          );
+
+        case ButtonHeight.m:
+        case ButtonHeight.l:
+          return STextStyles.desktopTextExtraSmall(context).copyWith(
+            color: enabled
+                ? Theme.of(context).extension<StackColors>()!.buttonTextPrimary
+                : Theme.of(context)
+                    .extension<StackColors>()!
+                    .buttonTextPrimaryDisabled,
+          );
+
+        case ButtonHeight.xl:
+        case ButtonHeight.xxl:
+          return enabled
+              ? STextStyles.desktopButtonEnabled(context)
+              : STextStyles.desktopButtonDisabled(context);
+      }
     } else {
       return STextStyles.button(context).copyWith(
         color: enabled
@@ -50,12 +73,51 @@ class PrimaryButton extends StatelessWidget {
     }
   }
 
+  double? _getHeight() {
+    if (buttonHeight == null) {
+      return height;
+    }
+
+    if (Util.isDesktop) {
+      switch (buttonHeight!) {
+        case ButtonHeight.xxs:
+          return 28;
+        case ButtonHeight.xs:
+          return 32;
+        case ButtonHeight.s:
+          return 40;
+        case ButtonHeight.m:
+          return 48;
+        case ButtonHeight.l:
+          return 56;
+        case ButtonHeight.xl:
+          return 70;
+        case ButtonHeight.xxl:
+          return 96;
+      }
+    } else {
+      switch (buttonHeight!) {
+        case ButtonHeight.xxs:
+        case ButtonHeight.xs:
+        case ButtonHeight.s:
+        case ButtonHeight.m:
+          return 28;
+        case ButtonHeight.l:
+          return 30;
+        case ButtonHeight.xl:
+          return 46;
+        case ButtonHeight.xxl:
+          return 56;
+      }
+    }
+  }
+
   @override
   Widget build(BuildContext context) {
     final isDesktop = Util.isDesktop;
 
     return CustomTextButtonBase(
-      height: desktopMed ? 56 : height,
+      height: _getHeight(),
       width: width,
       textButton: TextButton(
         onPressed: enabled ? onPressed : null,
diff --git a/lib/widgets/desktop/secondary_button.dart b/lib/widgets/desktop/secondary_button.dart
index 8d5eae0ce..7cf8e9f72 100644
--- a/lib/widgets/desktop/secondary_button.dart
+++ b/lib/widgets/desktop/secondary_button.dart
@@ -4,6 +4,8 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/desktop/custom_text_button.dart';
 
+export 'package:stackwallet/widgets/desktop/custom_text_button.dart';
+
 class SecondaryButton extends StatelessWidget {
   const SecondaryButton({
     Key? key,
@@ -13,7 +15,7 @@ class SecondaryButton extends StatelessWidget {
     this.icon,
     this.onPressed,
     this.enabled = true,
-    this.desktopMed = false,
+    this.buttonHeight,
   }) : super(key: key);
 
   final double? width;
@@ -22,23 +24,47 @@ class SecondaryButton extends StatelessWidget {
   final VoidCallback? onPressed;
   final bool enabled;
   final Widget? icon;
-  final bool desktopMed;
+  final ButtonHeight? buttonHeight;
 
   TextStyle getStyle(bool isDesktop, BuildContext context) {
     if (isDesktop) {
-      if (desktopMed) {
-        return STextStyles.desktopTextExtraSmall(context).copyWith(
-          color: enabled
-              ? Theme.of(context).extension<StackColors>()!.buttonTextSecondary
-              : Theme.of(context)
-                  .extension<StackColors>()!
-                  .buttonTextSecondaryDisabled,
-        );
-      } else {
+      if (buttonHeight == null) {
         return enabled
             ? STextStyles.desktopButtonSecondaryEnabled(context)
             : STextStyles.desktopButtonSecondaryDisabled(context);
       }
+      switch (buttonHeight!) {
+        case ButtonHeight.xxs:
+        case ButtonHeight.xs:
+        case ButtonHeight.s:
+          return STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+            color: enabled
+                ? Theme.of(context)
+                    .extension<StackColors>()!
+                    .buttonTextSecondary
+                : Theme.of(context)
+                    .extension<StackColors>()!
+                    .buttonTextSecondaryDisabled,
+          );
+
+        case ButtonHeight.m:
+        case ButtonHeight.l:
+          return STextStyles.desktopTextExtraSmall(context).copyWith(
+            color: enabled
+                ? Theme.of(context)
+                    .extension<StackColors>()!
+                    .buttonTextSecondary
+                : Theme.of(context)
+                    .extension<StackColors>()!
+                    .buttonTextSecondaryDisabled,
+          );
+
+        case ButtonHeight.xl:
+        case ButtonHeight.xxl:
+          return enabled
+              ? STextStyles.desktopButtonSecondaryEnabled(context)
+              : STextStyles.desktopButtonSecondaryDisabled(context);
+      }
     } else {
       return STextStyles.button(context).copyWith(
         color: enabled
@@ -50,12 +76,51 @@ class SecondaryButton extends StatelessWidget {
     }
   }
 
+  double? _getHeight() {
+    if (buttonHeight == null) {
+      return height;
+    }
+
+    if (Util.isDesktop) {
+      switch (buttonHeight!) {
+        case ButtonHeight.xxs:
+          return 28;
+        case ButtonHeight.xs:
+          return 32;
+        case ButtonHeight.s:
+          return 40;
+        case ButtonHeight.m:
+          return 48;
+        case ButtonHeight.l:
+          return 56;
+        case ButtonHeight.xl:
+          return 70;
+        case ButtonHeight.xxl:
+          return 96;
+      }
+    } else {
+      switch (buttonHeight!) {
+        case ButtonHeight.xxs:
+        case ButtonHeight.xs:
+        case ButtonHeight.s:
+        case ButtonHeight.m:
+          return 28;
+        case ButtonHeight.l:
+          return 30;
+        case ButtonHeight.xl:
+          return 46;
+        case ButtonHeight.xxl:
+          return 56;
+      }
+    }
+  }
+
   @override
   Widget build(BuildContext context) {
     final isDesktop = Util.isDesktop;
 
     return CustomTextButtonBase(
-      height: desktopMed ? 56 : height,
+      height: _getHeight(),
       width: width,
       textButton: TextButton(
         onPressed: enabled ? onPressed : null,

From 1d238c29f09207b975968c27707df5097de218ac Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 12:01:52 -0600
Subject: [PATCH 301/426] WIP: centralize button heights

---
 .../create_backup_view.dart                   |   4 +-
 .../restore_from_file_view.dart               |   4 +-
 .../wallet_view/desktop_wallet_view.dart      |   6 +-
 .../advanced_settings/advanced_settings.dart  | 111 +++++-------------
 .../backup_and_restore_settings.dart          |  10 +-
 .../currency_settings/currency_settings.dart  |   2 +-
 .../language_settings/language_settings.dart  |   4 +-
 .../home/settings_menu/security_settings.dart |   2 +-
 .../syncing_preferences_settings.dart         |   2 +-
 lib/widgets/desktop/primary_button.dart       |   4 +-
 lib/widgets/desktop/secondary_button.dart     |   4 +-
 11 files changed, 52 insertions(+), 101 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index 0609e4b1b..a6241d25a 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -562,7 +562,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                       Consumer(builder: (context, ref, __) {
                         return PrimaryButton(
                           width: 183,
-                          buttonHeight: ButtonHeight.l,
+                          buttonHeight: ButtonHeight.m,
                           label: "Create backup",
                           enabled: shouldEnableCreate,
                           onPressed: !shouldEnableCreate
@@ -780,7 +780,7 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
                       ),
                       SecondaryButton(
                         width: 183,
-                        buttonHeight: ButtonHeight.l,
+                        buttonHeight: ButtonHeight.m,
                         label: "Cancel",
                         onPressed: () {},
                       ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index 9be6af4cb..d6571967d 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -389,7 +389,7 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                       children: [
                         PrimaryButton(
                           width: 183,
-                          buttonHeight: ButtonHeight.l,
+                          buttonHeight: ButtonHeight.m,
                           label: "Restore",
                           enabled: !(passwordController.text.isEmpty ||
                               fileLocationController.text.isEmpty),
@@ -566,7 +566,7 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
                         ),
                         SecondaryButton(
                           width: 183,
-                          buttonHeight: ButtonHeight.l,
+                          buttonHeight: ButtonHeight.m,
                           label: "Cancel",
                           onPressed: () {},
                         ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 952194244..d21a19aee 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -411,7 +411,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                   if (coin == Coin.firo)
                     SecondaryButton(
                       width: 180,
-                      desktopMed: true,
+                      buttonHeight: ButtonHeight.l,
                       label: "Anonymize funds",
                       onPressed: () async {
                         await showDialog<void>(
@@ -441,7 +441,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                                     children: [
                                       SecondaryButton(
                                         width: 180,
-                                        desktopMed: true,
+                                        buttonHeight: ButtonHeight.l,
                                         label: "Cancel",
                                         onPressed: () {
                                           Navigator.of(context).pop();
@@ -450,7 +450,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                                       const SizedBox(width: 20),
                                       PrimaryButton(
                                         width: 180,
-                                        desktopMed: true,
+                                        buttonHeight: ButtonHeight.l,
                                         label: "Continue",
                                         onPressed: () {
                                           Navigator.of(context).pop();
diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
index b4ff3fe6a..621683e65 100644
--- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
@@ -8,6 +8,7 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 import 'debug_info_dialog.dart';
@@ -143,7 +144,21 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
                                 ),
                               ],
                             ),
-                            const StackPrivacyButton(),
+                            PrimaryButton(
+                              label: "Change",
+                              buttonHeight: ButtonHeight.xs,
+                              width: 86,
+                              onPressed: () async {
+                                await showDialog<dynamic>(
+                                  context: context,
+                                  useSafeArea: false,
+                                  barrierDismissible: true,
+                                  builder: (context) {
+                                    return const StackPrivacyDialog();
+                                  },
+                                );
+                              },
+                            )
                           ],
                         ),
                       );
@@ -172,7 +187,21 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
                                     .textDark),
                         textAlign: TextAlign.left,
                       ),
-                      ShowLogsButton(),
+                      PrimaryButton(
+                        buttonHeight: ButtonHeight.xs,
+                        label: "Show logs",
+                        width: 101,
+                        onPressed: () async {
+                          await showDialog<dynamic>(
+                            context: context,
+                            useSafeArea: false,
+                            barrierDismissible: true,
+                            builder: (context) {
+                              return const DebugInfoDialog();
+                            },
+                          );
+                        },
+                      ),
                     ],
                   ),
                 ),
@@ -184,81 +213,3 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
     );
   }
 }
-
-class StackPrivacyButton extends ConsumerWidget {
-  const StackPrivacyButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    Future<void> changePrivacySettings() async {
-      await showDialog<dynamic>(
-        context: context,
-        useSafeArea: false,
-        barrierDismissible: true,
-        builder: (context) {
-          return StackPrivacyDialog();
-        },
-      );
-    }
-
-    return SizedBox(
-      width: 84,
-      height: 37,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {
-          // Navigator.of(context).pushNamed(
-          //   StackPrivacyCalls.routeName,
-          //   arguments: false,
-          // );
-          changePrivacySettings();
-        },
-        child: Text(
-          "Change",
-          style: STextStyles.desktopTextExtraExtraSmall(context)
-              .copyWith(color: Colors.white),
-        ),
-      ),
-    );
-  }
-}
-
-class ShowLogsButton extends ConsumerWidget {
-  const ShowLogsButton({
-    Key? key,
-  }) : super(key: key);
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    Future<void> viewDebugLogs() async {
-      await showDialog<dynamic>(
-        context: context,
-        useSafeArea: false,
-        barrierDismissible: true,
-        builder: (context) {
-          return const DebugInfoDialog();
-        },
-      );
-    }
-
-    return SizedBox(
-      width: 101,
-      height: 37,
-      child: TextButton(
-        style: Theme.of(context)
-            .extension<StackColors>()!
-            .getPrimaryEnabledButtonColor(context),
-        onPressed: () {
-          viewDebugLogs();
-        },
-        child: Text(
-          "Show logs",
-          style: STextStyles.desktopTextExtraExtraSmall(context)
-              .copyWith(color: Colors.white),
-        ),
-      ),
-    );
-  }
-}
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
index 37f3f35a6..c82b5f923 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart
@@ -422,7 +422,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                 padding: const EdgeInsets.all(10),
                                 child: !isEnabledAutoBackup
                                     ? PrimaryButton(
-                                        buttonHeight: ButtonHeight.l,
+                                        buttonHeight: ButtonHeight.m,
                                         width: 200,
                                         label: "Enable auto backup",
                                         onPressed: () {
@@ -467,7 +467,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                           Row(
                                             children: [
                                               PrimaryButton(
-                                                buttonHeight: ButtonHeight.l,
+                                                buttonHeight: ButtonHeight.m,
                                                 width: 190,
                                                 label: "Disable auto backup",
                                                 onPressed: () {
@@ -476,7 +476,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                               ),
                                               const SizedBox(width: 16),
                                               SecondaryButton(
-                                                buttonHeight: ButtonHeight.l,
+                                                buttonHeight: ButtonHeight.m,
                                                 width: 190,
                                                 label: "Edit auto backup",
                                                 onPressed: () {
@@ -560,7 +560,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                         child: CreateBackupView(),
                                       )
                                     : PrimaryButton(
-                                        buttonHeight: ButtonHeight.l,
+                                        buttonHeight: ButtonHeight.m,
                                         width: 200,
                                         label: "Create manual backup",
                                         onPressed: () {
@@ -642,7 +642,7 @@ class _BackupRestoreSettings extends ConsumerState<BackupRestoreSettings> {
                                         child: RestoreFromFileView(),
                                       )
                                     : PrimaryButton(
-                                        buttonHeight: ButtonHeight.l,
+                                        buttonHeight: ButtonHeight.m,
                                         width: 200,
                                         label: "Restore backup",
                                         onPressed: () {
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index 0740157ad..d9c20d8fa 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -108,7 +108,7 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
                       ),
                       child: PrimaryButton(
                         width: 210,
-                        buttonHeight: ButtonHeight.l,
+                        buttonHeight: ButtonHeight.m,
                         enabled: true,
                         label: "Change currency",
                         onPressed: () {
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
index db636ba17..acddcb055 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
@@ -80,12 +80,12 @@ class _LanguageOptionSettings extends ConsumerState<LanguageOptionSettings> {
                   crossAxisAlignment: CrossAxisAlignment.start,
                   children: [
                     Padding(
-                      padding: EdgeInsets.all(
+                      padding: const EdgeInsets.all(
                         10,
                       ),
                       child: PrimaryButton(
                         width: 210,
-                        buttonHeight: ButtonHeight.l,
+                        buttonHeight: ButtonHeight.m,
                         enabled: true,
                         label: "Change language",
                         onPressed: () {
diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index f2853e6f5..f6762afa1 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -503,7 +503,7 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
                             )
                           : PrimaryButton(
                               width: 210,
-                              buttonHeight: ButtonHeight.l,
+                              buttonHeight: ButtonHeight.m,
                               enabled: true,
                               label: "Set up new password",
                               onPressed: () {
diff --git a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
index ae11f5582..815e506db 100644
--- a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
@@ -83,7 +83,7 @@ class _SyncingPreferencesSettings
                       ),
                       child: PrimaryButton(
                         width: 210,
-                        buttonHeight: ButtonHeight.l,
+                        buttonHeight: ButtonHeight.m,
                         enabled: true,
                         label: "Change preferences",
                         onPressed: () {},
diff --git a/lib/widgets/desktop/primary_button.dart b/lib/widgets/desktop/primary_button.dart
index 134ff36c3..9441168e7 100644
--- a/lib/widgets/desktop/primary_button.dart
+++ b/lib/widgets/desktop/primary_button.dart
@@ -81,9 +81,9 @@ class PrimaryButton extends StatelessWidget {
     if (Util.isDesktop) {
       switch (buttonHeight!) {
         case ButtonHeight.xxs:
-          return 28;
-        case ButtonHeight.xs:
           return 32;
+        case ButtonHeight.xs:
+          return 37;
         case ButtonHeight.s:
           return 40;
         case ButtonHeight.m:
diff --git a/lib/widgets/desktop/secondary_button.dart b/lib/widgets/desktop/secondary_button.dart
index 7cf8e9f72..62bd900dd 100644
--- a/lib/widgets/desktop/secondary_button.dart
+++ b/lib/widgets/desktop/secondary_button.dart
@@ -84,9 +84,9 @@ class SecondaryButton extends StatelessWidget {
     if (Util.isDesktop) {
       switch (buttonHeight!) {
         case ButtonHeight.xxs:
-          return 28;
-        case ButtonHeight.xs:
           return 32;
+        case ButtonHeight.xs:
+          return 37;
         case ButtonHeight.s:
           return 40;
         case ButtonHeight.m:

From 95a9fade38c065fb0d578b8ea92f4c83ca6b1a1a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 12:17:55 -0600
Subject: [PATCH 302/426] desktop contact address details

---
 .../desktop_address_book.dart                 |   7 +-
 .../subwidgets/desktop_address_card.dart      |  75 ++++++++++++
 .../subwidgets/desktop_contact_details.dart   | 108 ++++++------------
 3 files changed, 116 insertions(+), 74 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart

diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index f028a3424..fd25617e7 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -427,8 +427,11 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                 ),
           details: currentContactId == null
               ? Container()
-              : DesktopContactDetails(
-                  contactId: currentContactId!,
+              : RoundedWhiteContainer(
+            padding: const EdgeInsets.all(24),
+                  child: DesktopContactDetails(
+                    contactId: currentContactId!,
+                  ),
                 ),
         ),
       ),
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
new file mode 100644
index 000000000..49b75a4a8
--- /dev/null
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
@@ -0,0 +1,75 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/models/contact_address_entry.dart';
+import 'package:stackwallet/utilities/assets.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';
+
+class DesktopAddressCard extends StatelessWidget {
+  const DesktopAddressCard({
+    Key? key,
+    required this.entry,
+  }) : super(key: key);
+
+  final ContactAddressEntry entry;
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        SvgPicture.asset(
+          Assets.svg.iconFor(
+            coin: entry.coin,
+          ),
+          height: 32,
+          width: 32,
+        ),
+        const SizedBox(
+          width: 16,
+        ),
+        Flexible(
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              SelectableText(
+                "${entry.label} (${entry.coin.ticker})",
+                style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                  color: Theme.of(context).extension<StackColors>()!.textDark,
+                ),
+              ),
+              const SizedBox(
+                height: 2,
+              ),
+              SelectableText(
+                entry.address,
+                style: STextStyles.desktopTextExtraExtraSmall(context),
+              ),
+              const SizedBox(
+                height: 8,
+              ),
+              Row(
+                children: [
+                  BlueTextButton(
+                    text: "Copy",
+                    onTap: () {},
+                  ),
+                  const SizedBox(
+                    width: 16,
+                  ),
+                  BlueTextButton(
+                    text: "Edit",
+                    onTap: () {},
+                  ),
+                ],
+              )
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
index 5184b2293..bc19fe3bd 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
@@ -1,14 +1,14 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
-import 'package:stackwallet/models/contact_address_entry.dart';
+import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/utilities/assets.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/rounded_white_container.dart';
 
 class DesktopContactDetails extends ConsumerStatefulWidget {
   const DesktopContactDetails({
@@ -74,6 +74,8 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
             ),
             SecondaryButton(
               label: "Options",
+              width: 86,
+              buttonHeight: ButtonHeight.xxs,
               onPressed: () {},
             ),
           ],
@@ -106,12 +108,38 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
                             ),
                           ],
                         ),
-                        Column(
-                          mainAxisSize: MainAxisSize.min,
-                          children: [
-                            ...contact.addresses
-                                .map((e) => AddressCard(entry: e)),
-                          ],
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        RoundedWhiteContainer(
+                          padding: const EdgeInsets.all(0),
+                          borderColor: Theme.of(context)
+                              .extension<StackColors>()!
+                              .background,
+                          child: Column(
+                            mainAxisSize: MainAxisSize.min,
+                            children: [
+                              for (int i = 0; i < contact.addresses.length; i++)
+                                Column(
+                                  mainAxisSize: MainAxisSize.min,
+                                  children: [
+                                    if (i > 0)
+                                      Container(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .background,
+                                        height: 1,
+                                      ),
+                                    Padding(
+                                      padding: const EdgeInsets.all(18),
+                                      child: DesktopAddressCard(
+                                        entry: contact.addresses[i],
+                                      ),
+                                    ),
+                                  ],
+                                ),
+                            ],
+                          ),
                         )
                       ],
                     ),
@@ -125,67 +153,3 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
     );
   }
 }
-
-class AddressCard extends StatelessWidget {
-  const AddressCard({
-    Key? key,
-    required this.entry,
-  }) : super(key: key);
-
-  final ContactAddressEntry entry;
-
-  @override
-  Widget build(BuildContext context) {
-    return Row(
-      children: [
-        SvgPicture.asset(
-          Assets.svg.iconFor(
-            coin: entry.coin,
-          ),
-          height: 32,
-          width: 32,
-        ),
-        const SizedBox(
-          width: 16,
-        ),
-        Column(
-          mainAxisSize: MainAxisSize.min,
-          crossAxisAlignment: CrossAxisAlignment.start,
-          children: [
-            SelectableText(
-              "${entry.label} ${entry.coin.ticker}",
-              style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
-                color: Theme.of(context).extension<StackColors>()!.textDark,
-              ),
-            ),
-            const SizedBox(
-              height: 2,
-            ),
-            SelectableText(
-              entry.address,
-              style: STextStyles.desktopTextExtraExtraSmall(context),
-            ),
-            const SizedBox(
-              height: 8,
-            ),
-            Row(
-              children: [
-                BlueTextButton(
-                  text: "Copy",
-                  onTap: () {},
-                ),
-                const SizedBox(
-                  width: 16,
-                ),
-                BlueTextButton(
-                  text: "Edit",
-                  onTap: () {},
-                ),
-              ],
-            )
-          ],
-        ),
-      ],
-    );
-  }
-}

From 682966dab83a391ef3224c67833cc0d333a0cba9 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 17 Nov 2022 14:08:06 -0700
Subject: [PATCH 303/426] desktop block explorer dialog

---
 .../transaction_details_view.dart             | 200 ++++++++++++------
 .../wallet_view/desktop_wallet_view.dart      |   4 +-
 2 files changed, 142 insertions(+), 62 deletions(-)

diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
index 1c2fb8e5d..dc4e41152 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -30,6 +30,8 @@ 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/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/copy_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/pencil_icon.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -154,60 +156,136 @@ class _TransactionDetailsViewState
 
   Future<bool> showExplorerWarning(String explorer) async {
     final bool? shouldContinue = await showDialog<bool>(
-      context: context,
-      barrierDismissible: false,
-      builder: (_) => StackDialog(
-        title: "Attention",
-        message:
-            "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
-        icon: Row(
-          children: [
-            Consumer(builder: (_, ref, __) {
-              return Checkbox(
-                value: ref.watch(prefsChangeNotifierProvider
-                    .select((value) => value.hideBlockExplorerWarning)),
-                onChanged: (value) {
-                  if (value is bool) {
-                    ref
-                        .read(prefsChangeNotifierProvider)
-                        .hideBlockExplorerWarning = value;
-                    setState(() {});
-                  }
+        context: context,
+        barrierDismissible: false,
+        builder: (_) {
+          if (!isDesktop) {
+            return StackDialog(
+              title: "Attention",
+              message:
+                  "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
+              icon: Row(
+                children: [
+                  Consumer(builder: (_, ref, __) {
+                    return Checkbox(
+                      value: ref.watch(prefsChangeNotifierProvider
+                          .select((value) => value.hideBlockExplorerWarning)),
+                      onChanged: (value) {
+                        if (value is bool) {
+                          ref
+                              .read(prefsChangeNotifierProvider)
+                              .hideBlockExplorerWarning = value;
+                          setState(() {});
+                        }
+                      },
+                    );
+                  }),
+                  Text(
+                    "Never show again",
+                    style: STextStyles.smallMed14(context),
+                  )
+                ],
+              ),
+              leftButton: TextButton(
+                onPressed: () {
+                  Navigator.of(context).pop(false);
                 },
-              );
-            }),
-            Text(
-              "Never show again",
-              style: STextStyles.smallMed14(context),
-            )
-          ],
-        ),
-        leftButton: TextButton(
-          onPressed: () {
-            Navigator.of(context).pop(false);
-          },
-          child: Text(
-            "Cancel",
-            style: STextStyles.button(context).copyWith(
-                color: Theme.of(context)
+                child: Text(
+                  "Cancel",
+                  style: STextStyles.button(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark),
+                ),
+              ),
+              rightButton: TextButton(
+                style: Theme.of(context)
                     .extension<StackColors>()!
-                    .accentColorDark),
-          ),
-        ),
-        rightButton: TextButton(
-          style: Theme.of(context)
-              .extension<StackColors>()!
-              .getPrimaryEnabledButtonColor(context),
-          onPressed: () {
-            Navigator.of(context).pop(true);
-          },
-          child: Text(
-            "Continue",
-            style: STextStyles.button(context),
-          ),
-        ),
-      ),
-    );
+                    .getPrimaryEnabledButtonColor(context),
+                onPressed: () {
+                  Navigator.of(context).pop(true);
+                },
+                child: Text(
+                  "Continue",
+                  style: STextStyles.button(context),
+                ),
+              ),
+            );
+          } else {
+            return DesktopDialog(
+              maxWidth: 550,
+              maxHeight: 300,
+              child: Padding(
+                padding:
+                    const EdgeInsets.symmetric(horizontal: 32, vertical: 20),
+                child: Column(
+                  children: [
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Text(
+                          "Attention",
+                          style: STextStyles.desktopH2(context),
+                        ),
+                        Row(
+                          children: [
+                            Consumer(builder: (_, ref, __) {
+                              return Checkbox(
+                                value: ref.watch(prefsChangeNotifierProvider
+                                    .select((value) =>
+                                        value.hideBlockExplorerWarning)),
+                                onChanged: (value) {
+                                  if (value is bool) {
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .hideBlockExplorerWarning = value;
+                                    setState(() {});
+                                  }
+                                },
+                              );
+                            }),
+                            Text(
+                              "Never show again",
+                              style: STextStyles.smallMed14(context),
+                            )
+                          ],
+                        ),
+                      ],
+                    ),
+                    const SizedBox(height: 16),
+                    Text(
+                      "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
+                      style: STextStyles.desktopTextSmall(context),
+                    ),
+                    const SizedBox(height: 35),
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        SecondaryButton(
+                          width: 200,
+                          buttonHeight: ButtonHeight.l,
+                          label: "Cancel",
+                          onPressed: () {
+                            Navigator.of(context).pop(false);
+                          },
+                        ),
+                        const SizedBox(width: 20),
+                        PrimaryButton(
+                          width: 200,
+                          buttonHeight: ButtonHeight.l,
+                          label: "Continue",
+                          onPressed: () {
+                            Navigator.of(context).pop(true);
+                          },
+                        ),
+                      ],
+                    ),
+                  ],
+                ),
+              ),
+            );
+          }
+        });
     return shouldContinue ?? false;
   }
 
@@ -995,15 +1073,17 @@ class _TransactionDetailsViewState
                                                     .externalApplication,
                                               );
                                             } catch (_) {
-                                              unawaited(showDialog<void>(
-                                                context: context,
-                                                builder: (_) => StackOkDialog(
-                                                  title:
-                                                      "Could not open in block explorer",
-                                                  message:
-                                                      "Failed to open \"${uri.toString()}\"",
+                                              unawaited(
+                                                showDialog<void>(
+                                                  context: context,
+                                                  builder: (_) => StackOkDialog(
+                                                    title:
+                                                        "Could not open in block explorer",
+                                                    message:
+                                                        "Failed to open \"${uri.toString()}\"",
+                                                  ),
                                                 ),
-                                              ));
+                                              );
                                             } finally {
                                               // Future<void>.delayed(
                                               //   const Duration(seconds: 1),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index d21a19aee..a7de8fdf4 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -440,7 +440,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                                     mainAxisAlignment: MainAxisAlignment.center,
                                     children: [
                                       SecondaryButton(
-                                        width: 180,
+                                        width: 200,
                                         buttonHeight: ButtonHeight.l,
                                         label: "Cancel",
                                         onPressed: () {
@@ -449,7 +449,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                                       ),
                                       const SizedBox(width: 20),
                                       PrimaryButton(
-                                        width: 180,
+                                        width: 200,
                                         buttonHeight: ButtonHeight.l,
                                         label: "Continue",
                                         onPressed: () {

From 11735cdaf7d8e5393687c2ec89893a72908d7d8a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 12:56:10 -0600
Subject: [PATCH 304/426] desktop emoji select

---
 .../subviews/add_address_book_entry_view.dart | 132 ++++--------
 lib/widgets/emoji_select_sheet.dart           | 188 ++++++++++--------
 2 files changed, 151 insertions(+), 169 deletions(-)

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 5835c80cd..0007f3d81 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
@@ -191,33 +191,33 @@ class _AddAddressBookEntryViewState
                           style: STextStyles.desktopH3(context),
                           textAlign: TextAlign.center,
                         ),
-                        const SizedBox(width: 10),
-                        AppBarIconButton(
-                          key:
-                              const Key("addAddressBookEntryFavoriteButtonKey"),
-                          size: 36,
-                          shadows: const [],
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .background,
-                          icon: SvgPicture.asset(
-                            Assets.svg.star,
-                            color: _isFavorite
-                                ? Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .favoriteStarActive
-                                : Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .favoriteStarInactive,
-                            width: 20,
-                            height: 20,
-                          ),
-                          onPressed: () {
-                            setState(() {
-                              _isFavorite = !_isFavorite;
-                            });
-                          },
-                        ),
+                        // const SizedBox(width: 10),
+                        // AppBarIconButton(
+                        //   key:
+                        //       const Key("addAddressBookEntryFavoriteButtonKey"),
+                        //   size: 36,
+                        //   shadows: const [],
+                        //   color: Theme.of(context)
+                        //       .extension<StackColors>()!
+                        //       .background,
+                        //   icon: SvgPicture.asset(
+                        //     Assets.svg.star,
+                        //     color: _isFavorite
+                        //         ? Theme.of(context)
+                        //             .extension<StackColors>()!
+                        //             .favoriteStarActive
+                        //         : Theme.of(context)
+                        //             .extension<StackColors>()!
+                        //             .favoriteStarInactive,
+                        //     width: 20,
+                        //     height: 20,
+                        //   ),
+                        //   onPressed: () {
+                        //     setState(() {
+                        //       _isFavorite = !_isFavorite;
+                        //     });
+                        //   },
+                        // ),
                       ],
                     ),
                   ),
@@ -225,10 +225,11 @@ class _AddAddressBookEntryViewState
                 ],
               ),
               Expanded(
-                  child: Padding(
-                padding: const EdgeInsets.symmetric(horizontal: 10),
-                child: child,
-              )),
+                child: Padding(
+                  padding: const EdgeInsets.symmetric(horizontal: 10),
+                  child: child,
+                ),
+              ),
             ],
           );
         },
@@ -292,66 +293,17 @@ class _AddAddressBookEntryViewState
                                           : showDialog<dynamic>(
                                               context: context,
                                               builder: (context) {
-                                                return DesktopDialog(
+                                                return const DesktopDialog(
                                                   maxHeight: 700,
-                                                  maxWidth: 700,
-                                                  child: Column(
-                                                    children: [
-                                                      Row(
-                                                        children: [
-                                                          Padding(
-                                                            padding:
-                                                                const EdgeInsets
-                                                                    .all(32),
-                                                            child: Text(
-                                                              "Select emoji",
-                                                              style: STextStyles
-                                                                  .desktopH3(
-                                                                      context),
-                                                              textAlign:
-                                                                  TextAlign
-                                                                      .center,
-                                                            ),
-                                                          ),
-                                                        ],
-                                                      ),
-                                                      Expanded(
-                                                        child: LayoutBuilder(
-                                                          builder: (context,
-                                                              constraints) {
-                                                            return SingleChildScrollView(
-                                                              scrollDirection:
-                                                                  Axis.vertical,
-                                                              child:
-                                                                  ConstrainedBox(
-                                                                constraints:
-                                                                    BoxConstraints(
-                                                                  minHeight:
-                                                                      constraints
-                                                                          .maxHeight,
-                                                                  minWidth:
-                                                                      constraints
-                                                                          .maxWidth,
-                                                                ),
-                                                                child:
-                                                                    IntrinsicHeight(
-                                                                  child: Column(
-                                                                    children: const [
-                                                                      Padding(
-                                                                        padding:
-                                                                            EdgeInsets.symmetric(horizontal: 32),
-                                                                        // child:
-                                                                        //     EmojiSelectSheet(),
-                                                                      ),
-                                                                    ],
-                                                                  ),
-                                                                ),
-                                                              ),
-                                                            );
-                                                          },
-                                                        ),
-                                                      ),
-                                                    ],
+                                                  maxWidth: 600,
+                                                  child: Padding(
+                                                    padding: EdgeInsets.only(
+                                                      left: 32,
+                                                      right: 20,
+                                                      top: 32,
+                                                      bottom: 32,
+                                                    ),
+                                                    child: EmojiSelectSheet(),
                                                   ),
                                                 );
                                               }).then((value) {
diff --git a/lib/widgets/emoji_select_sheet.dart b/lib/widgets/emoji_select_sheet.dart
index 85a90fec8..7bf02e967 100644
--- a/lib/widgets/emoji_select_sheet.dart
+++ b/lib/widgets/emoji_select_sheet.dart
@@ -4,6 +4,9 @@ import 'package:flutter_riverpod/flutter_riverpod.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/conditional_parent.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 
 class EmojiSelectSheet extends ConsumerWidget {
   const EmojiSelectSheet({
@@ -16,7 +19,9 @@ class EmojiSelectSheet extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final size = MediaQuery.of(context).size;
+    final isDesktop = Util.isDesktop;
+
+    final size = isDesktop ? const Size(600, 700) : MediaQuery.of(context).size;
     final double maxHeight = size.height * 0.60;
     final double availableWidth = size.width - (2 * horizontalPadding);
     final int emojisPerRow =
@@ -24,90 +29,115 @@ class EmojiSelectSheet extends ConsumerWidget {
 
     final itemCount = Emoji.all().length;
 
-    return Container(
-      decoration: BoxDecoration(
-        color: Theme.of(context).extension<StackColors>()!.popupBG,
-        borderRadius: const BorderRadius.vertical(
-          top: Radius.circular(20),
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Container(
+        decoration: BoxDecoration(
+          color: Theme.of(context).extension<StackColors>()!.popupBG,
+          borderRadius: const BorderRadius.vertical(
+            top: Radius.circular(20),
+          ),
+        ),
+        child: LimitedBox(
+          maxHeight: maxHeight,
+          child: Padding(
+            padding: EdgeInsets.only(
+              left: horizontalPadding,
+              right: horizontalPadding,
+              top: 10,
+              bottom: 0,
+            ),
+            child: child,
+          ),
         ),
       ),
-      child: LimitedBox(
-        maxHeight: maxHeight,
-        child: Padding(
-          padding: EdgeInsets.only(
-            left: horizontalPadding,
-            right: horizontalPadding,
-            top: 10,
-            bottom: 0,
-          ),
-          child: Column(
-            mainAxisSize: MainAxisSize.min,
-            crossAxisAlignment: CrossAxisAlignment.stretch,
-            children: [
-              Center(
-                child: Container(
-                  decoration: BoxDecoration(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .textFieldDefaultBG,
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
-                    ),
+      child: Column(
+        mainAxisSize: MainAxisSize.min,
+        crossAxisAlignment: CrossAxisAlignment.stretch,
+        children: [
+          if (!isDesktop)
+            Center(
+              child: Container(
+                decoration: BoxDecoration(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldDefaultBG,
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
                   ),
-                  width: 60,
-                  height: 4,
                 ),
+                width: 60,
+                height: 4,
               ),
-              const SizedBox(
-                height: 36,
-              ),
-              Text(
-                "Select emoji",
-                style: STextStyles.pageTitleH2(context),
-                textAlign: TextAlign.left,
-              ),
-              const SizedBox(
-                height: 16,
-              ),
-              Flexible(
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.center,
-                  children: [
-                    Flexible(
-                      child: GridView.builder(
-                        itemCount: itemCount,
-                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
-                          crossAxisCount: emojisPerRow,
-                        ),
-                        itemBuilder: (context, index) {
-                          final emoji = Emoji.all()[index];
-                          return GestureDetector(
-                            onTap: () {
-                              Navigator.of(context).pop(emoji);
-                            },
-                            child: Container(
-                              decoration: BoxDecoration(
-                                borderRadius: BorderRadius.circular(100),
-                                color: Colors.transparent,
-                              ),
-                              child: Padding(
-                                padding: const EdgeInsets.all(8.0),
-                                child: Text(emoji.char),
-                              ),
-                            ),
-                          );
-                        },
-                      ),
-                    )
-                  ],
-                ),
-              ),
-              const SizedBox(
-                height: 24,
-              ),
-            ],
+            ),
+          if (!isDesktop)
+            const SizedBox(
+              height: 36,
+            ),
+          Text(
+            "Select emoji",
+            style: isDesktop
+                ? STextStyles.desktopH3(context)
+                : STextStyles.pageTitleH2(context),
+            textAlign: TextAlign.left,
           ),
-        ),
+          SizedBox(
+            height: isDesktop ? 28 : 16,
+          ),
+          Flexible(
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                Flexible(
+                  child: GridView.builder(
+                    itemCount: itemCount,
+                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+                      crossAxisCount: emojisPerRow,
+                    ),
+                    itemBuilder: (context, index) {
+                      final emoji = Emoji.all()[index];
+                      return GestureDetector(
+                        onTap: () {
+                          Navigator.of(context).pop(emoji);
+                        },
+                        child: Container(
+                          decoration: BoxDecoration(
+                            borderRadius: BorderRadius.circular(100),
+                            color: Colors.transparent,
+                          ),
+                          child: Padding(
+                            padding: const EdgeInsets.all(8.0),
+                            child: Text(
+                              emoji.char,
+                              style: isDesktop
+                                  ? STextStyles.desktopTextSmall(context)
+                                  : null,
+                            ),
+                          ),
+                        ),
+                      );
+                    },
+                  ),
+                )
+              ],
+            ),
+          ),
+          SizedBox(
+            height: isDesktop ? 20 : 24,
+          ),
+          if (isDesktop)
+            Row(
+              mainAxisAlignment: MainAxisAlignment.end,
+              children: [
+                SecondaryButton(
+                  label: "Cancel",
+                  width: 248,
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: Navigator.of(context).pop,
+                ),
+              ],
+            ),
+        ],
       ),
     );
   }

From 134087bfc4c18c3482e49d6b1e7a16b9f0a78032 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 13:15:57 -0600
Subject: [PATCH 305/426] desktop add contact popup tweaks

---
 .../subviews/add_address_book_entry_view.dart | 375 ++++++------------
 .../new_contact_address_entry_form.dart       |   2 +-
 2 files changed, 121 insertions(+), 256 deletions(-)

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 0007f3d81..bb93c68d8 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
@@ -21,6 +21,8 @@ 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/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/emoji_select_sheet.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
@@ -191,33 +193,6 @@ class _AddAddressBookEntryViewState
                           style: STextStyles.desktopH3(context),
                           textAlign: TextAlign.center,
                         ),
-                        // const SizedBox(width: 10),
-                        // AppBarIconButton(
-                        //   key:
-                        //       const Key("addAddressBookEntryFavoriteButtonKey"),
-                        //   size: 36,
-                        //   shadows: const [],
-                        //   color: Theme.of(context)
-                        //       .extension<StackColors>()!
-                        //       .background,
-                        //   icon: SvgPicture.asset(
-                        //     Assets.svg.star,
-                        //     color: _isFavorite
-                        //         ? Theme.of(context)
-                        //             .extension<StackColors>()!
-                        //             .favoriteStarActive
-                        //         : Theme.of(context)
-                        //             .extension<StackColors>()!
-                        //             .favoriteStarInactive,
-                        //     width: 20,
-                        //     height: 20,
-                        //   ),
-                        //   onPressed: () {
-                        //     setState(() {
-                        //       _isFavorite = !_isFavorite;
-                        //     });
-                        //   },
-                        // ),
                       ],
                     ),
                   ),
@@ -226,7 +201,11 @@ class _AddAddressBookEntryViewState
               ),
               Expanded(
                 child: Padding(
-                  padding: const EdgeInsets.symmetric(horizontal: 10),
+                  padding: const EdgeInsets.only(
+                    left: 10,
+                    right: 10,
+                    bottom: 32,
+                  ),
                   child: child,
                 ),
               ),
@@ -239,16 +218,17 @@ class _AddAddressBookEntryViewState
               padding: const EdgeInsets.symmetric(horizontal: 12),
               child: SingleChildScrollView(
                 controller: scrollController,
-                padding: const EdgeInsets.only(
+                padding: EdgeInsets.only(
                   // top: 8,
                   left: 4,
                   right: 4,
-                  bottom: 16,
+                  bottom: isDesktop ? 0 : 16,
                 ),
                 child: ConstrainedBox(
                   constraints: BoxConstraints(
                     // subtract top and bottom padding set in parent
-                    minHeight: constraint.maxHeight - 16, // - 8,
+                    minHeight:
+                        constraint.maxHeight - (isDesktop ? 0 : 16), // - 8,
                   ),
                   child: IntrinsicHeight(
                     child: Column(
@@ -259,38 +239,21 @@ class _AddAddressBookEntryViewState
                                 mainAxisAlignment:
                                     MainAxisAlignment.spaceBetween,
                                 children: [
-                                  GestureDetector(
-                                    onTap: () {
-                                      if (_selectedEmoji != null) {
-                                        setState(() {
-                                          _selectedEmoji = null;
-                                        });
-                                        return;
-                                      }
+                                  SizedBox(
+                                    height: 56,
+                                    width: 56,
+                                    child: MouseRegion(
+                                      cursor: SystemMouseCursors.click,
+                                      child: GestureDetector(
+                                        onTap: () {
+                                          if (_selectedEmoji != null) {
+                                            setState(() {
+                                              _selectedEmoji = null;
+                                            });
+                                            return;
+                                          }
 
-                                      ///TODO if desktop make dialog
-                                      !isDesktop
-                                          ? showModalBottomSheet<dynamic>(
-                                              backgroundColor:
-                                                  Colors.transparent,
-                                              context: context,
-                                              shape:
-                                                  const RoundedRectangleBorder(
-                                                borderRadius:
-                                                    BorderRadius.vertical(
-                                                  top: Radius.circular(20),
-                                                ),
-                                              ),
-                                              builder: (_) =>
-                                                  const EmojiSelectSheet(),
-                                            ).then((value) {
-                                              if (value is Emoji) {
-                                                setState(() {
-                                                  _selectedEmoji = value;
-                                                });
-                                              }
-                                            })
-                                          : showDialog<dynamic>(
+                                          showDialog<dynamic>(
                                               context: context,
                                               builder: (context) {
                                                 return const DesktopDialog(
@@ -307,77 +270,80 @@ class _AddAddressBookEntryViewState
                                                   ),
                                                 );
                                               }).then((value) {
-                                              if (value is Emoji) {
-                                                setState(() {
-                                                  _selectedEmoji = value;
-                                                });
-                                              }
-                                            });
-                                    },
-                                    child: SizedBox(
-                                      height: 56,
-                                      width: 56,
-                                      child: Stack(
-                                        children: [
-                                          Container(
-                                            height: 56,
-                                            width: 56,
-                                            decoration: BoxDecoration(
-                                              borderRadius:
-                                                  BorderRadius.circular(24),
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textFieldActiveBG,
-                                            ),
-                                            child: Center(
-                                              child: _selectedEmoji == null
-                                                  ? SvgPicture.asset(
-                                                      Assets.svg.user,
-                                                      height: 30,
-                                                      width: 30,
-                                                    )
-                                                  : Text(
-                                                      _selectedEmoji!.char,
-                                                      style: STextStyles
-                                                          .pageTitleH1(context),
-                                                    ),
-                                            ),
-                                          ),
-                                          Align(
-                                            alignment: Alignment.bottomRight,
-                                            child: Container(
-                                              height: 14,
-                                              width: 14,
+                                            if (value is Emoji) {
+                                              setState(() {
+                                                _selectedEmoji = value;
+                                              });
+                                            }
+                                          });
+                                        },
+                                        child: Stack(
+                                          children: [
+                                            Container(
+                                              height: 56,
+                                              width: 56,
                                               decoration: BoxDecoration(
-                                                  borderRadius:
-                                                      BorderRadius.circular(14),
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .accentColorDark),
+                                                borderRadius:
+                                                    BorderRadius.circular(100),
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textFieldActiveBG,
+                                              ),
                                               child: Center(
                                                 child: _selectedEmoji == null
                                                     ? SvgPicture.asset(
-                                                        Assets.svg.plus,
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .textWhite,
-                                                        width: 12,
-                                                        height: 12,
+                                                        Assets.svg.user,
+                                                        height: 30,
+                                                        width: 30,
                                                       )
-                                                    : SvgPicture.asset(
-                                                        Assets.svg.thickX,
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .textWhite,
-                                                        width: 8,
-                                                        height: 8,
+                                                    : Text(
+                                                        _selectedEmoji!.char,
+                                                        style: STextStyles
+                                                            .pageTitleH1(
+                                                                context),
                                                       ),
                                               ),
                                             ),
-                                          )
-                                        ],
+                                            Align(
+                                              alignment: Alignment.bottomRight,
+                                              child: Container(
+                                                height: 14,
+                                                width: 14,
+                                                decoration: BoxDecoration(
+                                                    borderRadius:
+                                                        BorderRadius.circular(
+                                                            14),
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .accentColorDark),
+                                                child: Center(
+                                                  child: _selectedEmoji == null
+                                                      ? SvgPicture.asset(
+                                                          Assets.svg.plus,
+                                                          color: Theme.of(
+                                                                  context)
+                                                              .extension<
+                                                                  StackColors>()!
+                                                              .textWhite,
+                                                          width: 12,
+                                                          height: 12,
+                                                        )
+                                                      : SvgPicture.asset(
+                                                          Assets.svg.thickX,
+                                                          color: Theme.of(
+                                                                  context)
+                                                              .extension<
+                                                                  StackColors>()!
+                                                              .textWhite,
+                                                          width: 8,
+                                                          height: 8,
+                                                        ),
+                                                ),
+                                              ),
+                                            )
+                                          ],
+                                        ),
                                       ),
                                     ),
                                   ),
@@ -453,100 +419,23 @@ class _AddAddressBookEntryViewState
                                         return;
                                       }
 
-                                      ///TODO if desktop make dialog
-                                      !isDesktop
-                                          ? showModalBottomSheet<dynamic>(
-                                              backgroundColor:
-                                                  Colors.transparent,
-                                              context: context,
-                                              shape:
-                                                  const RoundedRectangleBorder(
-                                                borderRadius:
-                                                    BorderRadius.vertical(
-                                                  top: Radius.circular(20),
-                                                ),
-                                              ),
-                                              builder: (_) =>
-                                                  const EmojiSelectSheet(),
-                                            ).then((value) {
-                                              if (value is Emoji) {
-                                                setState(() {
-                                                  _selectedEmoji = value;
-                                                });
-                                              }
-                                            })
-                                          : showDialog<dynamic>(
-                                              context: context,
-                                              builder: (context) {
-                                                return DesktopDialog(
-                                                  maxHeight: 700,
-                                                  maxWidth: 700,
-                                                  child: Column(
-                                                    children: [
-                                                      Row(
-                                                        children: [
-                                                          Padding(
-                                                            padding:
-                                                                const EdgeInsets
-                                                                    .all(32),
-                                                            child: Text(
-                                                              "Select emoji",
-                                                              style: STextStyles
-                                                                  .desktopH3(
-                                                                      context),
-                                                              textAlign:
-                                                                  TextAlign
-                                                                      .center,
-                                                            ),
-                                                          ),
-                                                        ],
-                                                      ),
-                                                      Expanded(
-                                                        child: LayoutBuilder(
-                                                          builder: (context,
-                                                              constraints) {
-                                                            return SingleChildScrollView(
-                                                              scrollDirection:
-                                                                  Axis.vertical,
-                                                              child:
-                                                                  ConstrainedBox(
-                                                                constraints:
-                                                                    BoxConstraints(
-                                                                  minHeight:
-                                                                      constraints
-                                                                          .maxHeight,
-                                                                  minWidth:
-                                                                      constraints
-                                                                          .maxWidth,
-                                                                ),
-                                                                child:
-                                                                    IntrinsicHeight(
-                                                                  child: Column(
-                                                                    children: const [
-                                                                      Padding(
-                                                                        padding:
-                                                                            EdgeInsets.symmetric(horizontal: 32),
-                                                                        // child:
-                                                                        //     EmojiSelectSheet(),
-                                                                      ),
-                                                                    ],
-                                                                  ),
-                                                                ),
-                                                              ),
-                                                            );
-                                                          },
-                                                        ),
-                                                      ),
-                                                    ],
-                                                  ),
-                                                );
-                                              }).then((value) {
-                                              if (value is Emoji) {
-                                                setState(() {
-                                                  _selectedEmoji = value;
-                                                });
-                                              }
-                                            });
+                                      showModalBottomSheet<dynamic>(
+                                        backgroundColor: Colors.transparent,
+                                        context: context,
+                                        shape: const RoundedRectangleBorder(
+                                          borderRadius: BorderRadius.vertical(
+                                            top: Radius.circular(20),
+                                          ),
+                                        ),
+                                        builder: (_) =>
+                                            const EmojiSelectSheet(),
+                                      ).then((value) {
+                                        if (value is Emoji) {
+                                          setState(() {
+                                            _selectedEmoji = value;
+                                          });
+                                        }
+                                      });
                                     },
                                     child: SizedBox(
                                       height: 48,
@@ -734,22 +623,16 @@ class _AddAddressBookEntryViewState
                         Row(
                           children: [
                             Expanded(
-                              child: TextButton(
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getSecondaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Cancel",
-                                  style: STextStyles.button(context).copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .accentColorDark),
-                                ),
+                              child: SecondaryButton(
+                                label: "Cancel",
+                                buttonHeight: isDesktop ? ButtonHeight.m : null,
                                 onPressed: () async {
-                                  if (FocusScope.of(context).hasFocus) {
+                                  if (!isDesktop &&
+                                      FocusScope.of(context).hasFocus) {
                                     FocusScope.of(context).unfocus();
                                     await Future<void>.delayed(
-                                        const Duration(milliseconds: 75));
+                                      const Duration(milliseconds: 75),
+                                    );
                                   }
                                   if (mounted) {
                                     Navigator.of(context).pop();
@@ -776,16 +659,11 @@ class _AddAddressBookEntryViewState
                                   bool shouldEnableSave =
                                       validForms && nameExists;
 
-                                  return TextButton(
-                                    style: shouldEnableSave
-                                        ? Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .getPrimaryEnabledButtonColor(
-                                                context)
-                                        : Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .getPrimaryDisabledButtonColor(
-                                                context),
+                                  return PrimaryButton(
+                                    label: "Save",
+                                    buttonHeight:
+                                        isDesktop ? ButtonHeight.m : null,
+                                    enabled: shouldEnableSave,
                                     onPressed: shouldEnableSave
                                         ? () async {
                                             if (FocusScope.of(context)
@@ -827,19 +705,6 @@ class _AddAddressBookEntryViewState
                                             }
                                           }
                                         : null,
-                                    child: Text(
-                                      "Save",
-                                      style:
-                                          STextStyles.button(context).copyWith(
-                                        color: shouldEnableSave
-                                            ? Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .buttonTextPrimary
-                                            : Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .buttonTextPrimaryDisabled,
-                                      ),
-                                    ),
                                   );
                                 },
                               ),
diff --git a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
index b6cf0aad4..f49547858 100644
--- a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
+++ b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
@@ -253,7 +253,7 @@ class _NewContactAddressEntryFormState
                         },
                         child: const ClipboardIcon(),
                       ),
-                    if (ref.watch(addressEntryDataProvider(widget.id)
+                    if (!Util.isDesktop && ref.watch(addressEntryDataProvider(widget.id)
                             .select((value) => value.address)) ==
                         null)
                       TextFieldIconButton(

From 0503999fa708aa0b7ab38d39c044d87435e045de Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 15:24:28 -0600
Subject: [PATCH 306/426] WIP coin dropdown

---
 .../new_contact_address_entry_form.dart       | 245 ++++++++++++------
 1 file changed, 172 insertions(+), 73 deletions(-)

diff --git a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
index f49547858..25cff073b 100644
--- a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
+++ b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
@@ -1,8 +1,10 @@
+import 'package:dropdown_button2/dropdown_button2.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/coin_select_sheet.dart';
+import 'package:stackwallet/providers/providers.dart';
 // import 'package:stackwallet/providers/global/should_show_lockscreen_on_resume_state_provider.dart';
 import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
 import 'package:stackwallet/utilities/address_utils.dart';
@@ -47,6 +49,8 @@ class _NewContactAddressEntryFormState
   late final FocusNode addressLabelFocusNode;
   late final FocusNode addressFocusNode;
 
+  List<Coin> coins = [];
+
   @override
   void initState() {
     addressLabelController = TextEditingController()
@@ -55,6 +59,7 @@ class _NewContactAddressEntryFormState
       ..text = ref.read(addressEntryDataProvider(widget.id)).address ?? "";
     addressLabelFocusNode = FocusNode();
     addressFocusNode = FocusNode();
+    coins = [...Coin.values];
     super.initState();
   }
 
@@ -70,86 +75,179 @@ class _NewContactAddressEntryFormState
   @override
   Widget build(BuildContext context) {
     final isDesktop = Util.isDesktop;
+    bool showTestNet = ref.watch(
+      prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
+    );
+    if (isDesktop) {
+      coins = [...Coin.values];
+
+      coins.remove(Coin.firoTestNet);
+      if (showTestNet) {
+        coins = coins.sublist(0, coins.length - kTestNetCoinCount);
+      }
+    }
+
     return Column(
       children: [
-        TextField(
-          autocorrect: Util.isDesktop ? false : true,
-          enableSuggestions: Util.isDesktop ? false : true,
-          readOnly: true,
-          style: STextStyles.field(context),
-          decoration: InputDecoration(
-            hintText: "Select cryptocurrency",
-            hintStyle: STextStyles.fieldLabel(context),
-            prefixIcon: Center(
-              child: Padding(
-                padding: const EdgeInsets.symmetric(horizontal: 12),
-                child: RawMaterialButton(
-                  splashColor:
-                      Theme.of(context).extension<StackColors>()!.highlight,
-                  shape: RoundedRectangleBorder(
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
+        if (isDesktop)
+          DropdownButtonHideUnderline(
+            child: DropdownButton2<Coin>(
+              hint: Text(
+                "Select cryptocurrency",
+                style: STextStyles.fieldLabel(context),
+              ),
+              offset: const Offset(0, -10),
+              isExpanded: true,
+              dropdownElevation: 0,
+              value: ref.watch(addressEntryDataProvider(widget.id)
+                  .select((value) => value.coin)),
+              onChanged: (value) {
+                if (value is Coin) {
+                  ref.read(addressEntryDataProvider(widget.id)).coin = value;
+                }
+              },
+              icon: SvgPicture.asset(
+                Assets.svg.chevronDown,
+                width: 10,
+                height: 5,
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
+              ),
+              buttonPadding: const EdgeInsets.symmetric(
+                horizontal: 16,
+                vertical: 4,
+              ),
+              buttonDecoration: BoxDecoration(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultBG,
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
+              ),
+              dropdownDecoration: BoxDecoration(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .textFieldDefaultBG,
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
+              ),
+              items: [
+                ...coins.map(
+                  (coin) => DropdownMenuItem<Coin>(
+                    value: coin,
+                    child: Padding(
+                      padding: const EdgeInsets.symmetric(vertical: 4),
+                      child: Row(
+                        children: [
+                          SvgPicture.asset(
+                            Assets.svg.iconFor(coin: coin),
+                            height: 24,
+                            width: 24,
+                          ),
+                          const SizedBox(
+                            width: 12,
+                          ),
+                          Text(
+                            coin.prettyName,
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context)
+                                    .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark,
+                            ),
+                          ),
+                        ],
+                      ),
                     ),
                   ),
-                  onPressed: () {
-                    showModalBottomSheet<dynamic>(
-                      backgroundColor: Colors.transparent,
-                      context: context,
-                      builder: (_) => const CoinSelectSheet(),
-                    ).then((value) {
-                      if (value is Coin) {
-                        ref.read(addressEntryDataProvider(widget.id)).coin =
-                            value;
-                      }
-                    });
-                  },
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      ref.watch(addressEntryDataProvider(widget.id)
-                                  .select((value) => value.coin)) ==
-                              null
-                          ? Text(
-                              "Select cryptocurrency",
-                              style: STextStyles.fieldLabel(context),
-                            )
-                          : Row(
-                              children: [
-                                SvgPicture.asset(
-                                  Assets.svg.iconFor(
-                                      coin: ref.watch(
-                                          addressEntryDataProvider(widget.id)
-                                              .select((value) => value.coin))!),
-                                  height: 20,
-                                  width: 20,
-                                ),
-                                const SizedBox(
-                                  width: 12,
-                                ),
-                                Text(
-                                  ref
-                                      .watch(addressEntryDataProvider(widget.id)
-                                          .select((value) => value.coin))!
-                                      .prettyName,
-                                  style: STextStyles.itemSubtitle12(context),
-                                ),
-                              ],
-                            ),
-                      SvgPicture.asset(
-                        Assets.svg.chevronDown,
-                        width: 8,
-                        height: 4,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textSubtitle2,
+                ),
+              ],
+            ),
+          ),
+        if (!isDesktop)
+          TextField(
+            autocorrect: Util.isDesktop ? false : true,
+            enableSuggestions: Util.isDesktop ? false : true,
+            readOnly: true,
+            style: STextStyles.field(context),
+            decoration: InputDecoration(
+              hintText: "Select cryptocurrency",
+              hintStyle: STextStyles.fieldLabel(context),
+              prefixIcon: Center(
+                child: Padding(
+                  padding: const EdgeInsets.symmetric(horizontal: 12),
+                  child: RawMaterialButton(
+                    splashColor:
+                        Theme.of(context).extension<StackColors>()!.highlight,
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
                       ),
-                    ],
+                    ),
+                    onPressed: () {
+                      showModalBottomSheet<dynamic>(
+                        backgroundColor: Colors.transparent,
+                        context: context,
+                        builder: (_) => const CoinSelectSheet(),
+                      ).then((value) {
+                        if (value is Coin) {
+                          ref.read(addressEntryDataProvider(widget.id)).coin =
+                              value;
+                        }
+                      });
+                    },
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        ref.watch(addressEntryDataProvider(widget.id)
+                                    .select((value) => value.coin)) ==
+                                null
+                            ? Text(
+                                "Select cryptocurrency",
+                                style: STextStyles.fieldLabel(context),
+                              )
+                            : Row(
+                                children: [
+                                  SvgPicture.asset(
+                                    Assets.svg.iconFor(
+                                        coin: ref.watch(
+                                            addressEntryDataProvider(widget.id)
+                                                .select(
+                                                    (value) => value.coin))!),
+                                    height: 20,
+                                    width: 20,
+                                  ),
+                                  const SizedBox(
+                                    width: 12,
+                                  ),
+                                  Text(
+                                    ref
+                                        .watch(
+                                            addressEntryDataProvider(widget.id)
+                                                .select((value) => value.coin))!
+                                        .prettyName,
+                                    style: STextStyles.itemSubtitle12(context),
+                                  ),
+                                ],
+                              ),
+                        if (!isDesktop)
+                          SvgPicture.asset(
+                            Assets.svg.chevronDown,
+                            width: 8,
+                            height: 4,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textSubtitle2,
+                          ),
+                      ],
+                    ),
                   ),
                 ),
               ),
             ),
           ),
-        ),
         const SizedBox(
           height: 8,
         ),
@@ -253,9 +351,10 @@ class _NewContactAddressEntryFormState
                         },
                         child: const ClipboardIcon(),
                       ),
-                    if (!Util.isDesktop && ref.watch(addressEntryDataProvider(widget.id)
-                            .select((value) => value.address)) ==
-                        null)
+                    if (!Util.isDesktop &&
+                        ref.watch(addressEntryDataProvider(widget.id)
+                                .select((value) => value.address)) ==
+                            null)
                       TextFieldIconButton(
                         key: const Key("addAddressBookEntryScanQrButtonKey"),
                         onTap: () async {

From 8799a9cfa2a993379e34a91cef9427b4fe272740 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 15:34:48 -0600
Subject: [PATCH 307/426] my stack contact tweaks

---
 .../subviews/add_address_book_entry_view.dart  |  2 +-
 .../subwidgets/desktop_address_card.dart       | 18 +++++++++++-------
 .../subwidgets/desktop_contact_details.dart    | 11 +++++++----
 3 files changed, 19 insertions(+), 12 deletions(-)

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 bb93c68d8..2759e9cb1 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
@@ -559,7 +559,7 @@ class _AddAddressBookEntryViewState
                                   ),
                                 ],
                               ),
-                        if (!isDesktop) const SizedBox(height: 8),
+                        const SizedBox(height: 8),
                         if (forms.length <= 1)
                           const SizedBox(
                             height: 8,
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
index 49b75a4a8..405b9107c 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
@@ -11,9 +11,11 @@ class DesktopAddressCard extends StatelessWidget {
   const DesktopAddressCard({
     Key? key,
     required this.entry,
+    required this.contactId,
   }) : super(key: key);
 
   final ContactAddressEntry entry;
+  final String contactId;
 
   @override
   Widget build(BuildContext context) {
@@ -57,13 +59,15 @@ class DesktopAddressCard extends StatelessWidget {
                     text: "Copy",
                     onTap: () {},
                   ),
-                  const SizedBox(
-                    width: 16,
-                  ),
-                  BlueTextButton(
-                    text: "Edit",
-                    onTap: () {},
-                  ),
+                  if (contactId != "default")
+                    const SizedBox(
+                      width: 16,
+                    ),
+                  if (contactId != "default")
+                    BlueTextButton(
+                      text: "Edit",
+                      onTap: () {},
+                    ),
                 ],
               )
             ],
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
index bc19fe3bd..ada330a14 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
@@ -40,16 +40,18 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
                   width: 32,
                   height: 32,
                   decoration: BoxDecoration(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .textFieldDefaultBG,
+                    color: contact.id == "default"
+                        ? Colors.transparent
+                        : Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
                     borderRadius: BorderRadius.circular(32),
                   ),
                   child: contact.id == "default"
                       ? Center(
                           child: SvgPicture.asset(
                             Assets.svg.stackIcon(context),
-                            width: 20,
+                            width: 32,
                           ),
                         )
                       : contact.emojiChar != null
@@ -134,6 +136,7 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
                                       padding: const EdgeInsets.all(18),
                                       child: DesktopAddressCard(
                                         entry: contact.addresses[i],
+                                        contactId: contact.id,
                                       ),
                                     ),
                                   ],

From 51c98f90e94d9bbdeb8fe75828ec8f3a848ece29 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 16:01:11 -0600
Subject: [PATCH 308/426] contact tx history

---
 .../desktop_address_book.dart                 |   7 +-
 .../desktop_address_book_scaffold.dart        |   3 +-
 .../subwidgets/desktop_address_card.dart      |  18 +-
 .../subwidgets/desktop_contact_details.dart   | 334 ++++++++++++------
 4 files changed, 248 insertions(+), 114 deletions(-)

diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index fd25617e7..f028a3424 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -427,11 +427,8 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
                 ),
           details: currentContactId == null
               ? Container()
-              : RoundedWhiteContainer(
-            padding: const EdgeInsets.all(24),
-                  child: DesktopContactDetails(
-                    contactId: currentContactId!,
-                  ),
+              : DesktopContactDetails(
+                  contactId: currentContactId!,
                 ),
         ),
       ),
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_book_scaffold.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_book_scaffold.dart
index f32ea1f7f..36e44e6d4 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_book_scaffold.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_book_scaffold.dart
@@ -56,6 +56,7 @@ class DesktopAddressBookScaffold extends StatelessWidget {
         ),
         Expanded(
           child: Row(
+            crossAxisAlignment: CrossAxisAlignment.start,
             children: [
               Expanded(
                 flex: 6,
@@ -96,7 +97,7 @@ class DesktopAddressBookScaffold extends StatelessWidget {
                     const SizedBox(
                       height: weirdRowHeight,
                     ),
-                    Expanded(
+                    Flexible(
                       child: details ?? Container(),
                     ),
                   ],
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
index 405b9107c..f00e0c137 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
@@ -1,8 +1,12 @@
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/models/contact_address_entry.dart';
+import 'package:stackwallet/notifications/show_flush_bar.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/enums/flush_bar_type.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';
@@ -12,10 +16,12 @@ class DesktopAddressCard extends StatelessWidget {
     Key? key,
     required this.entry,
     required this.contactId,
+    this.clipboard = const ClipboardWrapper(),
   }) : super(key: key);
 
   final ContactAddressEntry entry;
   final String contactId;
+  final ClipboardInterface clipboard;
 
   @override
   Widget build(BuildContext context) {
@@ -57,7 +63,17 @@ class DesktopAddressCard extends StatelessWidget {
                 children: [
                   BlueTextButton(
                     text: "Copy",
-                    onTap: () {},
+                    onTap: () {
+                      clipboard.setData(
+                        ClipboardData(text: entry.address),
+                      );
+                      showFloatingFlushBar(
+                        type: FlushBarType.info,
+                        message: "Copied to clipboard",
+                        iconAsset: Assets.svg.copy,
+                        context: context,
+                      );
+                    },
                   ),
                   if (contactId != "default")
                     const SizedBox(
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
index ada330a14..53597826c 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
@@ -1,14 +1,21 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/models/contact.dart';
+import 'package:stackwallet/models/paymint/transactions_model.dart';
 import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/utilities/assets.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/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/transaction_card.dart';
+import 'package:tuple/tuple.dart';
 
 class DesktopContactDetails extends ConsumerStatefulWidget {
   const DesktopContactDetails({
@@ -24,132 +31,245 @@ class DesktopContactDetails extends ConsumerStatefulWidget {
 }
 
 class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
+  List<Tuple2<String, Transaction>> _cachedTransactions = [];
+
+  bool _contactHasAddress(String address, Contact contact) {
+    for (final entry in contact.addresses) {
+      if (entry.address == address) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  Future<List<Tuple2<String, Transaction>>> _filteredTransactionsByContact(
+    List<Manager> managers,
+  ) async {
+    final contact =
+        ref.read(addressBookServiceProvider).getContactById(widget.contactId);
+
+    // TODO: optimise
+
+    List<Tuple2<String, Transaction>> result = [];
+    for (final manager in managers) {
+      final transactions = (await manager.transactionData)
+          .getAllTransactions()
+          .values
+          .toList()
+          .where((e) => _contactHasAddress(e.address, contact));
+
+      for (final tx in transactions) {
+        result.add(Tuple2(manager.walletId, tx));
+      }
+    }
+    // sort by date
+    result.sort((a, b) => b.item2.timestamp - a.item2.timestamp);
+
+    return result;
+  }
+
   @override
   Widget build(BuildContext context) {
     final contact = ref.watch(addressBookServiceProvider
         .select((value) => value.getContactById(widget.contactId)));
 
-    return Column(
+    return Row(
+      crossAxisAlignment: CrossAxisAlignment.start,
       children: [
-        Row(
-          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-          children: [
-            Row(
-              children: [
-                Container(
-                  width: 32,
-                  height: 32,
-                  decoration: BoxDecoration(
-                    color: contact.id == "default"
-                        ? Colors.transparent
-                        : Theme.of(context)
-                            .extension<StackColors>()!
-                            .textFieldDefaultBG,
-                    borderRadius: BorderRadius.circular(32),
-                  ),
-                  child: contact.id == "default"
-                      ? Center(
-                          child: SvgPicture.asset(
-                            Assets.svg.stackIcon(context),
-                            width: 32,
-                          ),
-                        )
-                      : contact.emojiChar != null
-                          ? Center(
-                              child: Text(contact.emojiChar!),
-                            )
-                          : Center(
-                              child: SvgPicture.asset(
-                                Assets.svg.user,
-                                width: 18,
-                              ),
-                            ),
-                ),
-                const SizedBox(
-                  width: 16,
-                ),
-                Text(
-                  contact.name,
-                  style: STextStyles.desktopTextSmall(context),
-                ),
-              ],
-            ),
-            SecondaryButton(
-              label: "Options",
-              width: 86,
-              buttonHeight: ButtonHeight.xxs,
-              onPressed: () {},
-            ),
-          ],
-        ),
-        const SizedBox(
-          height: 24,
-        ),
         Expanded(
-          child: LayoutBuilder(
-            builder: (context, constraints) {
-              return SingleChildScrollView(
-                child: ConstrainedBox(
-                  constraints: BoxConstraints(
-                    minHeight: constraints.maxHeight,
-                  ),
-                  child: IntrinsicHeight(
-                    child: Column(
+          child: RoundedWhiteContainer(
+            padding: const EdgeInsets.all(24),
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Row(
                       children: [
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: [
-                            Text(
-                              "Addresses",
-                              style: STextStyles.desktopTextExtraExtraSmall(
-                                  context),
-                            ),
-                            BlueTextButton(
-                              text: "Add new",
-                              onTap: () {},
-                            ),
-                          ],
+                        Container(
+                          width: 32,
+                          height: 32,
+                          decoration: BoxDecoration(
+                            color: contact.id == "default"
+                                ? Colors.transparent
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textFieldDefaultBG,
+                            borderRadius: BorderRadius.circular(32),
+                          ),
+                          child: contact.id == "default"
+                              ? Center(
+                                  child: SvgPicture.asset(
+                                    Assets.svg.stackIcon(context),
+                                    width: 32,
+                                  ),
+                                )
+                              : contact.emojiChar != null
+                                  ? Center(
+                                      child: Text(contact.emojiChar!),
+                                    )
+                                  : Center(
+                                      child: SvgPicture.asset(
+                                        Assets.svg.user,
+                                        width: 18,
+                                      ),
+                                    ),
                         ),
                         const SizedBox(
-                          height: 12,
+                          width: 16,
                         ),
-                        RoundedWhiteContainer(
-                          padding: const EdgeInsets.all(0),
-                          borderColor: Theme.of(context)
-                              .extension<StackColors>()!
-                              .background,
-                          child: Column(
-                            mainAxisSize: MainAxisSize.min,
-                            children: [
-                              for (int i = 0; i < contact.addresses.length; i++)
-                                Column(
+                        Text(
+                          contact.name,
+                          style: STextStyles.desktopTextSmall(context),
+                        ),
+                      ],
+                    ),
+                    SecondaryButton(
+                      label: "Options",
+                      width: 86,
+                      buttonHeight: ButtonHeight.xxs,
+                      onPressed: () {},
+                    ),
+                  ],
+                ),
+                const SizedBox(
+                  height: 24,
+                ),
+                Flexible(
+                  child: ListView(
+                    primary: false,
+                    shrinkWrap: true,
+                    // child: Column(
+                    //   crossAxisAlignment: CrossAxisAlignment.start,
+                    //   mainAxisSize: MainAxisSize.min,
+                    children: [
+                      Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Text(
+                            "Addresses",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context),
+                          ),
+                          BlueTextButton(
+                            text: "Add new",
+                            onTap: () {},
+                          ),
+                        ],
+                      ),
+                      const SizedBox(
+                        height: 12,
+                      ),
+                      RoundedWhiteContainer(
+                        padding: const EdgeInsets.all(0),
+                        borderColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .background,
+                        child: Column(
+                          mainAxisSize: MainAxisSize.min,
+                          children: [
+                            for (int i = 0; i < contact.addresses.length; i++)
+                              Column(
+                                mainAxisSize: MainAxisSize.min,
+                                children: [
+                                  if (i > 0)
+                                    Container(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .background,
+                                      height: 1,
+                                    ),
+                                  Padding(
+                                    padding: const EdgeInsets.all(18),
+                                    child: DesktopAddressCard(
+                                      entry: contact.addresses[i],
+                                      contactId: contact.id,
+                                    ),
+                                  ),
+                                ],
+                              ),
+                          ],
+                        ),
+                      ),
+                      Text(
+                        "Transaction history",
+                        style: STextStyles.desktopTextExtraExtraSmall(context),
+                      ),
+                      FutureBuilder(
+                        future: _filteredTransactionsByContact(
+                            ref.watch(walletsChangeNotifierProvider).managers),
+                        builder: (_,
+                            AsyncSnapshot<List<Tuple2<String, Transaction>>>
+                                snapshot) {
+                          if (snapshot.connectionState ==
+                                  ConnectionState.done &&
+                              snapshot.hasData) {
+                            _cachedTransactions = snapshot.data!;
+
+                            if (_cachedTransactions.isNotEmpty) {
+                              return RoundedWhiteContainer(
+                                padding: const EdgeInsets.all(0),
+                                borderColor: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .background,
+                                child: Column(
                                   mainAxisSize: MainAxisSize.min,
                                   children: [
-                                    if (i > 0)
-                                      Container(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .background,
-                                        height: 1,
-                                      ),
-                                    Padding(
-                                      padding: const EdgeInsets.all(18),
-                                      child: DesktopAddressCard(
-                                        entry: contact.addresses[i],
-                                        contactId: contact.id,
+                                    ..._cachedTransactions.map(
+                                      (e) => TransactionCard(
+                                        key: Key(
+                                            "contactDetailsTransaction_${e.item1}_${e.item2.txid}_cardKey"),
+                                        transaction: e.item2,
+                                        walletId: e.item1,
                                       ),
                                     ),
                                   ],
                                 ),
-                            ],
-                          ),
-                        )
-                      ],
-                    ),
+                              );
+                            } else {
+                              return RoundedWhiteContainer(
+                                child: Center(
+                                  child: Text(
+                                    "No transactions found",
+                                    style: STextStyles.itemSubtitle(context),
+                                  ),
+                                ),
+                              );
+                            }
+                          } else {
+                            // TODO: proper loading animation
+                            if (_cachedTransactions.isEmpty) {
+                              return const LoadingIndicator();
+                            } else {
+                              return RoundedWhiteContainer(
+                                padding: const EdgeInsets.all(0),
+                                borderColor: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .background,
+                                child: Column(
+                                  mainAxisSize: MainAxisSize.min,
+                                  children: [
+                                    ..._cachedTransactions.map(
+                                      (e) => TransactionCard(
+                                        key: Key(
+                                            "contactDetailsTransaction_${e.item1}_${e.item2.txid}_cardKey"),
+                                        transaction: e.item2,
+                                        walletId: e.item1,
+                                      ),
+                                    ),
+                                  ],
+                                ),
+                              );
+                            }
+                          }
+                        },
+                      ),
+                    ],
                   ),
                 ),
-              );
-            },
+              ],
+            ),
           ),
         ),
       ],

From 494849364317cb55e46e8c7e40d786dc37ede959 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 16:18:00 -0600
Subject: [PATCH 309/426] contact tx history

---
 .../subwidgets/desktop_contact_details.dart         | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
index 53597826c..fb094d766 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
@@ -192,9 +192,16 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
                           ],
                         ),
                       ),
-                      Text(
-                        "Transaction history",
-                        style: STextStyles.desktopTextExtraExtraSmall(context),
+                      Padding(
+                        padding: const EdgeInsets.only(
+                          top: 20,
+                          bottom: 12,
+                        ),
+                        child: Text(
+                          "Transaction history",
+                          style:
+                              STextStyles.desktopTextExtraExtraSmall(context),
+                        ),
                       ),
                       FutureBuilder(
                         future: _filteredTransactionsByContact(

From 318758f76850a471ce0dbfc0a1ecd6a190fb4e4a Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 17 Nov 2022 16:55:34 -0700
Subject: [PATCH 310/426] copy receive address has pointer finger cursor

---
 .../sub_widgets/desktop_receive.dart          | 142 +++++++++---------
 1 file changed, 73 insertions(+), 69 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
index 3de4ed1e3..1dd2e607e 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
@@ -117,78 +117,82 @@ class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
     return Column(
       crossAxisAlignment: CrossAxisAlignment.stretch,
       children: [
-        GestureDetector(
-          onTap: () {
-            clipboard.setData(
-              ClipboardData(text: receivingAddress),
-            );
-            showFloatingFlushBar(
-              type: FlushBarType.info,
-              message: "Copied to clipboard",
-              iconAsset: Assets.svg.copy,
-              context: context,
-            );
-          },
-          child: Container(
-            decoration: BoxDecoration(
-              border: Border.all(
-                color: Theme.of(context).extension<StackColors>()!.background,
-                width: 2,
+        MouseRegion(
+          cursor: SystemMouseCursors.click,
+          child: GestureDetector(
+            onTap: () {
+              clipboard.setData(
+                ClipboardData(text: receivingAddress),
+              );
+              showFloatingFlushBar(
+                type: FlushBarType.info,
+                message: "Copied to clipboard",
+                iconAsset: Assets.svg.copy,
+                context: context,
+              );
+            },
+            child: Container(
+              decoration: BoxDecoration(
+                border: Border.all(
+                  color: Theme.of(context).extension<StackColors>()!.background,
+                  width: 2,
+                ),
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
               ),
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-            ),
-            child: RoundedWhiteContainer(
-              child: Column(
-                children: [
-                  Row(
-                    children: [
-                      Text(
-                        "Your ${coin.ticker} address",
-                        style: STextStyles.itemSubtitle(context),
-                      ),
-                      const Spacer(),
-                      Row(
-                        children: [
-                          SvgPicture.asset(
-                            Assets.svg.copy,
-                            width: 15,
-                            height: 15,
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .infoItemIcons,
-                          ),
-                          const SizedBox(
-                            width: 4,
-                          ),
-                          Text(
-                            "Copy",
-                            style: STextStyles.link2(context),
-                          ),
-                        ],
-                      ),
-                    ],
-                  ),
-                  const SizedBox(
-                    height: 8,
-                  ),
-                  Row(
-                    children: [
-                      Expanded(
-                        child: Text(
-                          receivingAddress,
-                          style: STextStyles.desktopTextExtraExtraSmall(context)
-                              .copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark,
+              child: RoundedWhiteContainer(
+                child: Column(
+                  children: [
+                    Row(
+                      children: [
+                        Text(
+                          "Your ${coin.ticker} address",
+                          style: STextStyles.itemSubtitle(context),
+                        ),
+                        const Spacer(),
+                        Row(
+                          children: [
+                            SvgPicture.asset(
+                              Assets.svg.copy,
+                              width: 15,
+                              height: 15,
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .infoItemIcons,
+                            ),
+                            const SizedBox(
+                              width: 4,
+                            ),
+                            Text(
+                              "Copy",
+                              style: STextStyles.link2(context),
+                            ),
+                          ],
+                        ),
+                      ],
+                    ),
+                    const SizedBox(
+                      height: 8,
+                    ),
+                    Row(
+                      children: [
+                        Expanded(
+                          child: Text(
+                            receivingAddress,
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context)
+                                    .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark,
+                            ),
                           ),
                         ),
-                      ),
-                    ],
-                  ),
-                ],
+                      ],
+                    ),
+                  ],
+                ),
               ),
             ),
           ),

From cd19d776ae04631571a8d64b008d3cf52746d331 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 16:47:50 -0600
Subject: [PATCH 311/426] desktop edit contact address entry

---
 .../subviews/edit_contact_address_view.dart   | 433 +++++++++---------
 .../subwidgets/desktop_address_card.dart      |  62 ++-
 2 files changed, 268 insertions(+), 227 deletions(-)

diff --git a/lib/pages/address_book_views/subviews/edit_contact_address_view.dart b/lib/pages/address_book_views/subviews/edit_contact_address_view.dart
index 618a41982..f0143d39d 100644
--- a/lib/pages/address_book_views/subviews/edit_contact_address_view.dart
+++ b/lib/pages/address_book_views/subviews/edit_contact_address_view.dart
@@ -12,7 +12,11 @@ import 'package:stackwallet/utilities/barcode_scanner_interface.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/utilities/util.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 
 class EditContactAddressView extends ConsumerStatefulWidget {
   const EditContactAddressView({
@@ -44,6 +48,42 @@ class _EditContactAddressViewState
   late final BarcodeScannerInterface barcodeScanner;
   late final ClipboardInterface clipboard;
 
+  Future<void> save(Contact contact) async {
+    if (FocusScope.of(context).hasFocus) {
+      FocusScope.of(context).unfocus();
+      await Future<void>.delayed(
+        const Duration(milliseconds: 75),
+      );
+    }
+    List<ContactAddressEntry> entries = contact.addresses.toList();
+
+    final entry = entries.firstWhere(
+      (e) =>
+          e.label == addressEntry.label &&
+          e.address == addressEntry.address &&
+          e.coin == addressEntry.coin,
+    );
+
+    final index = entries.indexOf(entry);
+    entries.remove(entry);
+
+    ContactAddressEntry editedEntry =
+        ref.read(addressEntryDataProvider(0)).buildAddressEntry();
+
+    entries.insert(index, editedEntry);
+
+    Contact editedContact = contact.copyWith(addresses: entries);
+
+    if (await ref.read(addressBookServiceProvider).editContact(editedContact)) {
+      if (mounted) {
+        Navigator.of(context).pop();
+      }
+      // TODO show success notification
+    } else {
+      // TODO show error notification
+    }
+  }
+
   @override
   void initState() {
     contactId = widget.contactId;
@@ -59,236 +99,181 @@ class _EditContactAddressViewState
     final contact = ref.watch(addressBookServiceProvider
         .select((value) => value.getContactById(contactId)));
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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();
-            }
-          },
+    final bool isDesktop = Util.isDesktop;
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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 address",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Edit address",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (context, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      children: [
-                        Row(
-                          children: [
-                            Container(
-                              height: 48,
-                              width: 48,
-                              decoration: BoxDecoration(
-                                borderRadius: BorderRadius.circular(24),
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textFieldActiveBG,
-                              ),
-                              child: Center(
-                                child: contact.emojiChar == null
-                                    ? SvgPicture.asset(
-                                        Assets.svg.user,
-                                        height: 24,
-                                        width: 24,
-                                      )
-                                    : Text(
-                                        contact.emojiChar!,
-                                        style: STextStyles.pageTitleH1(context),
-                                      ),
-                              ),
-                            ),
-                            const SizedBox(
-                              width: 16,
-                            ),
-                            Expanded(
-                              child: FittedBox(
-                                fit: BoxFit.scaleDown,
-                                child: Text(
-                                  contact.name,
-                                  style: STextStyles.pageTitleH2(context),
-                                ),
-                              ),
-                            ),
-                          ],
-                        ),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        NewContactAddressEntryForm(
-                          id: 0,
-                          barcodeScanner: barcodeScanner,
-                          clipboard: clipboard,
-                        ),
-                        const SizedBox(
-                          height: 24,
-                        ),
-                        GestureDetector(
-                          onTap: () async {
-                            // delete address
-                            final _addresses = contact.addresses;
-                            final entry = _addresses.firstWhere(
-                              (e) =>
-                                  e.label == addressEntry.label &&
-                                  e.address == addressEntry.address &&
-                                  e.coin == addressEntry.coin,
-                            );
-
-                            _addresses.remove(entry);
-                            Contact editedContact =
-                                contact.copyWith(addresses: _addresses);
-                            if (await ref
-                                .read(addressBookServiceProvider)
-                                .editContact(editedContact)) {
-                              Navigator.of(context).pop();
-                              // TODO show success notification
-                            } else {
-                              // TODO show error notification
-                            }
-                          },
-                          child: Text(
-                            "Delete address",
-                            style: STextStyles.link(context),
-                          ),
-                        ),
-                        const Spacer(),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        Row(
-                          children: [
-                            Expanded(
-                              child: TextButton(
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getSecondaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Cancel",
-                                  style: STextStyles.button(context).copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .accentColorDark),
-                                ),
-                                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();
-                                  }
-                                },
-                              ),
-                            ),
-                            const SizedBox(
-                              width: 16,
-                            ),
-                            Expanded(
-                              child: Builder(
-                                builder: (context) {
-                                  bool shouldEnableSave =
-                                      ref.watch(validContactStateProvider([0]));
-
-                                  return TextButton(
-                                    style: shouldEnableSave
-                                        ? Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .getPrimaryEnabledButtonColor(
-                                                context)
-                                        : Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .getPrimaryDisabledButtonColor(
-                                                context),
-                                    onPressed: shouldEnableSave
-                                        ? () async {
-                                            if (FocusScope.of(context)
-                                                .hasFocus) {
-                                              FocusScope.of(context).unfocus();
-                                              await Future<void>.delayed(
-                                                const Duration(
-                                                    milliseconds: 75),
-                                              );
-                                            }
-                                            List<ContactAddressEntry> entries =
-                                                contact.addresses.toList();
-
-                                            final entry = entries.firstWhere(
-                                              (e) =>
-                                                  e.label ==
-                                                      addressEntry.label &&
-                                                  e.address ==
-                                                      addressEntry.address &&
-                                                  e.coin == addressEntry.coin,
-                                            );
-
-                                            final index =
-                                                entries.indexOf(entry);
-                                            entries.remove(entry);
-
-                                            ContactAddressEntry editedEntry = ref
-                                                .read(
-                                                    addressEntryDataProvider(0))
-                                                .buildAddressEntry();
-
-                                            entries.insert(index, editedEntry);
-
-                                            Contact editedContact = contact
-                                                .copyWith(addresses: entries);
-
-                                            if (await ref
-                                                .read(
-                                                    addressBookServiceProvider)
-                                                .editContact(editedContact)) {
-                                              if (mounted) {
-                                                Navigator.of(context).pop();
-                                              }
-                                              // TODO show success notification
-                                            } else {
-                                              // TODO show error notification
-                                            }
-                                          }
-                                        : null,
-                                    child: Text(
-                                      "Save",
-                                      style: STextStyles.button(context),
-                                    ),
-                                  );
-                                },
-                              ),
-                            ),
-                          ],
-                        ),
-                      ],
+        body: LayoutBuilder(
+          builder: (context, constraints) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: child,
                     ),
                   ),
                 ),
               ),
+            );
+          },
+        ),
+      ),
+      child: Column(
+        children: [
+          Row(
+            children: [
+              Container(
+                height: 48,
+                width: 48,
+                decoration: BoxDecoration(
+                  borderRadius: BorderRadius.circular(24),
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldActiveBG,
+                ),
+                child: Center(
+                  child: contact.emojiChar == null
+                      ? SvgPicture.asset(
+                          Assets.svg.user,
+                          height: 24,
+                          width: 24,
+                        )
+                      : Text(
+                          contact.emojiChar!,
+                          style: STextStyles.pageTitleH1(context),
+                        ),
+                ),
+              ),
+              const SizedBox(
+                width: 16,
+              ),
+              if (isDesktop)
+                Text(
+                  contact.name,
+                  style: STextStyles.pageTitleH2(context),
+                ),
+              if (!isDesktop)
+                Expanded(
+                  child: FittedBox(
+                    fit: BoxFit.scaleDown,
+                    child: Text(
+                      contact.name,
+                      style: STextStyles.pageTitleH2(context),
+                    ),
+                  ),
+                ),
+            ],
+          ),
+          const SizedBox(
+            height: 16,
+          ),
+          NewContactAddressEntryForm(
+            id: 0,
+            barcodeScanner: barcodeScanner,
+            clipboard: clipboard,
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          ConditionalParent(
+            condition: isDesktop,
+            builder: (child) => MouseRegion(
+              cursor: SystemMouseCursors.click,
+              child: child,
             ),
-          );
-        },
+            child: GestureDetector(
+              onTap: () async {
+                // delete address
+                final _addresses = contact.addresses;
+                final entry = _addresses.firstWhere(
+                  (e) =>
+                      e.label == addressEntry.label &&
+                      e.address == addressEntry.address &&
+                      e.coin == addressEntry.coin,
+                );
+
+                _addresses.remove(entry);
+                Contact editedContact = contact.copyWith(addresses: _addresses);
+                if (await ref
+                    .read(addressBookServiceProvider)
+                    .editContact(editedContact)) {
+                  Navigator.of(context).pop();
+                  // TODO show success notification
+                } else {
+                  // TODO show error notification
+                }
+              },
+              child: Text(
+                "Delete address",
+                style: STextStyles.link(context),
+              ),
+            ),
+          ),
+          const Spacer(),
+          const SizedBox(
+            height: 16,
+          ),
+          Row(
+            children: [
+              Expanded(
+                child: SecondaryButton(
+                  label: "Cancel",
+                  buttonHeight: isDesktop ? ButtonHeight.l : null,
+                  onPressed: () async {
+                    if (!isDesktop && FocusScope.of(context).hasFocus) {
+                      FocusScope.of(context).unfocus();
+                      await Future<void>.delayed(
+                          const Duration(milliseconds: 75));
+                    }
+                    if (mounted) {
+                      Navigator.of(context).pop();
+                    }
+                  },
+                ),
+              ),
+              const SizedBox(
+                width: 16,
+              ),
+              Expanded(
+                child: PrimaryButton(
+                  label: "Save",
+                  enabled: ref.watch(validContactStateProvider([0])),
+                  onPressed: () => save(contact),
+                  buttonHeight: isDesktop ? ButtonHeight.l : null,
+                ),
+              ),
+            ],
+          ),
+        ],
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
index f00e0c137..713c9e965 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
@@ -1,15 +1,20 @@
 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/contact_address_entry.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/pages/address_book_views/subviews/edit_contact_address_view.dart';
+import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.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/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+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/desktop/desktop_dialog.dart';
 
 class DesktopAddressCard extends StatelessWidget {
   const DesktopAddressCard({
@@ -80,9 +85,60 @@ class DesktopAddressCard extends StatelessWidget {
                       width: 16,
                     ),
                   if (contactId != "default")
-                    BlueTextButton(
-                      text: "Edit",
-                      onTap: () {},
+                    Consumer(
+                      builder: (context, ref, child) {
+                        return BlueTextButton(
+                          text: "Edit",
+                          onTap: () async {
+                            ref.read(addressEntryDataProvider(0)).address =
+                                entry.address;
+                            ref.read(addressEntryDataProvider(0)).addressLabel =
+                                entry.label;
+                            ref.read(addressEntryDataProvider(0)).coin =
+                                entry.coin;
+
+                            await showDialog<void>(
+                              context: context,
+                              builder: (context) => DesktopDialog(
+                                maxWidth: 580,
+                                maxHeight: 566,
+                                child: Column(
+                                  children: [
+                                    Row(
+                                      children: [
+                                        const SizedBox(
+                                          width: 8,
+                                        ),
+                                        const AppBarBackButton(
+                                          isCompact: true,
+                                        ),
+                                        Text(
+                                          "Edit address",
+                                          style: STextStyles.desktopH3(context),
+                                        ),
+                                      ],
+                                    ),
+                                    Expanded(
+                                      child: Padding(
+                                        padding: const EdgeInsets.only(
+                                          top: 20,
+                                          left: 32,
+                                          right: 32,
+                                          bottom: 32,
+                                        ),
+                                        child: EditContactAddressView(
+                                          contactId: contactId,
+                                          addressEntry: entry,
+                                        ),
+                                      ),
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            );
+                          },
+                        );
+                      },
                     ),
                 ],
               )

From df64e48e1ef2985cc58363bf844c288bd71ebd5a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 17:00:06 -0600
Subject: [PATCH 312/426] desktop add new contact address entry

---
 .../add_new_contact_address_view.dart         | 342 +++++++++---------
 .../subwidgets/desktop_address_card.dart      |   2 +
 .../subwidgets/desktop_contact_details.dart   |  49 ++-
 3 files changed, 213 insertions(+), 180 deletions(-)

diff --git a/lib/pages/address_book_views/subviews/add_new_contact_address_view.dart b/lib/pages/address_book_views/subviews/add_new_contact_address_view.dart
index e5dbaa7b9..dc25c3dc1 100644
--- a/lib/pages/address_book_views/subviews/add_new_contact_address_view.dart
+++ b/lib/pages/address_book_views/subviews/add_new_contact_address_view.dart
@@ -12,7 +12,11 @@ import 'package:stackwallet/utilities/barcode_scanner_interface.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/utilities/util.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 
 class AddNewContactAddressView extends ConsumerStatefulWidget {
   const AddNewContactAddressView({
@@ -55,190 +59,170 @@ class _AddNewContactAddressViewState
     final contact = ref.watch(addressBookServiceProvider
         .select((value) => value.getContactById(contactId)));
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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();
-            }
-          },
+    final isDesktop = Util.isDesktop;
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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(
+            "Add new address",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Add new address",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (context, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      children: [
-                        Row(
-                          children: [
-                            Container(
-                              height: 48,
-                              width: 48,
-                              decoration: BoxDecoration(
-                                borderRadius: BorderRadius.circular(24),
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textFieldActiveBG,
-                              ),
-                              child: Center(
-                                child: contact.emojiChar == null
-                                    ? SvgPicture.asset(
-                                        Assets.svg.user,
-                                        height: 24,
-                                        width: 24,
-                                      )
-                                    : Text(
-                                        contact.emojiChar!,
-                                        style: STextStyles.pageTitleH1(context),
-                                      ),
-                              ),
-                            ),
-                            const SizedBox(
-                              width: 16,
-                            ),
-                            Expanded(
-                              child: FittedBox(
-                                fit: BoxFit.scaleDown,
-                                child: Text(
-                                  contact.name,
-                                  style: STextStyles.pageTitleH2(context),
-                                ),
-                              ),
-                            ),
-                          ],
-                        ),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        NewContactAddressEntryForm(
-                          id: 0,
-                          barcodeScanner: barcodeScanner,
-                          clipboard: clipboard,
-                        ),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        const Spacer(),
-                        Row(
-                          children: [
-                            Expanded(
-                              child: TextButton(
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getSecondaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Cancel",
-                                  style: STextStyles.button(context).copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .accentColorDark),
-                                ),
-                                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();
-                                  }
-                                },
-                              ),
-                            ),
-                            const SizedBox(
-                              width: 16,
-                            ),
-                            Expanded(
-                              child: Builder(
-                                builder: (context) {
-                                  bool shouldEnableSave =
-                                      ref.watch(validContactStateProvider([0]));
-
-                                  return TextButton(
-                                    style: shouldEnableSave
-                                        ? Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .getPrimaryEnabledButtonColor(
-                                                context)
-                                        : Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .getPrimaryDisabledButtonColor(
-                                                context),
-                                    onPressed: shouldEnableSave
-                                        ? () async {
-                                            if (FocusScope.of(context)
-                                                .hasFocus) {
-                                              FocusScope.of(context).unfocus();
-                                              await Future<void>.delayed(
-                                                const Duration(
-                                                    milliseconds: 75),
-                                              );
-                                            }
-                                            List<ContactAddressEntry> entries =
-                                                contact.addresses;
-
-                                            entries.add(ref
-                                                .read(
-                                                    addressEntryDataProvider(0))
-                                                .buildAddressEntry());
-
-                                            Contact editedContact = contact
-                                                .copyWith(addresses: entries);
-
-                                            if (await ref
-                                                .read(
-                                                    addressBookServiceProvider)
-                                                .editContact(editedContact)) {
-                                              if (mounted) {
-                                                Navigator.of(context).pop();
-                                              }
-                                              // TODO show success notification
-                                            } else {
-                                              // TODO show error notification
-                                            }
-                                          }
-                                        : null,
-                                    child: Text(
-                                      "Save",
-                                      style: STextStyles.button(context),
-                                    ),
-                                  );
-                                },
-                              ),
-                            ),
-                          ],
-                        )
-                      ],
+        body: LayoutBuilder(
+          builder: (context, constraints) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: child,
                     ),
                   ),
                 ),
               ),
-            ),
-          );
-        },
+            );
+          },
+        ),
+      ),
+      child: Column(
+        children: [
+          Row(
+            children: [
+              Container(
+                height: 48,
+                width: 48,
+                decoration: BoxDecoration(
+                  borderRadius: BorderRadius.circular(24),
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldActiveBG,
+                ),
+                child: Center(
+                  child: contact.emojiChar == null
+                      ? SvgPicture.asset(
+                          Assets.svg.user,
+                          height: 24,
+                          width: 24,
+                        )
+                      : Text(
+                          contact.emojiChar!,
+                          style: STextStyles.pageTitleH1(context),
+                        ),
+                ),
+              ),
+              const SizedBox(
+                width: 16,
+              ),
+              if (isDesktop)
+                Text(
+                  contact.name,
+                  style: STextStyles.pageTitleH2(context),
+                ),
+              if (!isDesktop)
+                Expanded(
+                  child: FittedBox(
+                    fit: BoxFit.scaleDown,
+                    child: Text(
+                      contact.name,
+                      style: STextStyles.pageTitleH2(context),
+                    ),
+                  ),
+                ),
+            ],
+          ),
+          const SizedBox(
+            height: 16,
+          ),
+          NewContactAddressEntryForm(
+            id: 0,
+            barcodeScanner: barcodeScanner,
+            clipboard: clipboard,
+          ),
+          const SizedBox(
+            height: 16,
+          ),
+          const Spacer(),
+          Row(
+            children: [
+              Expanded(
+                child: SecondaryButton(
+                  label: "Cancel",
+                  buttonHeight: isDesktop ? ButtonHeight.l : null,
+                  onPressed: () async {
+                    if (!isDesktop && FocusScope.of(context).hasFocus) {
+                      FocusScope.of(context).unfocus();
+                      await Future<void>.delayed(
+                          const Duration(milliseconds: 75));
+                    }
+                    if (mounted) {
+                      Navigator.of(context).pop();
+                    }
+                  },
+                ),
+              ),
+              const SizedBox(
+                width: 16,
+              ),
+              Expanded(
+                child: PrimaryButton(
+                  label: "Save",
+                  enabled: ref.watch(validContactStateProvider([0])),
+                  buttonHeight: isDesktop ? ButtonHeight.l : null,
+                  onPressed: () async {
+                    if (FocusScope.of(context).hasFocus) {
+                      FocusScope.of(context).unfocus();
+                      await Future<void>.delayed(
+                        const Duration(milliseconds: 75),
+                      );
+                    }
+                    List<ContactAddressEntry> entries = contact.addresses;
+
+                    entries.add(ref
+                        .read(addressEntryDataProvider(0))
+                        .buildAddressEntry());
+
+                    Contact editedContact =
+                        contact.copyWith(addresses: entries);
+
+                    if (await ref
+                        .read(addressBookServiceProvider)
+                        .editContact(editedContact)) {
+                      if (mounted) {
+                        Navigator.of(context).pop();
+                      }
+                      // TODO show success notification
+                    } else {
+                      // TODO show error notification
+                    }
+                  },
+                ),
+              ),
+            ],
+          )
+        ],
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
index 713c9e965..4d58dc474 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart
@@ -90,6 +90,8 @@ class DesktopAddressCard extends StatelessWidget {
                         return BlueTextButton(
                           text: "Edit",
                           onTap: () async {
+                            ref.refresh(
+                                addressEntryDataProviderFamilyRefresher);
                             ref.read(addressEntryDataProvider(0)).address =
                                 entry.address;
                             ref.read(addressEntryDataProvider(0)).addressLabel =
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
index fb094d766..1c27b6836 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
@@ -3,14 +3,18 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/models/paymint/transactions_model.dart';
+import 'package:stackwallet/pages/address_book_views/subviews/add_new_contact_address_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+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/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -154,7 +158,50 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
                           ),
                           BlueTextButton(
                             text: "Add new",
-                            onTap: () {},
+                            onTap: () async {
+                              ref.refresh(
+                                  addressEntryDataProviderFamilyRefresher);
+
+                              await showDialog<void>(
+                                context: context,
+                                builder: (context) => DesktopDialog(
+                                  maxWidth: 580,
+                                  maxHeight: 566,
+                                  child: Column(
+                                    children: [
+                                      Row(
+                                        children: [
+                                          const SizedBox(
+                                            width: 8,
+                                          ),
+                                          const AppBarBackButton(
+                                            isCompact: true,
+                                          ),
+                                          Text(
+                                            "Add new address",
+                                            style:
+                                                STextStyles.desktopH3(context),
+                                          ),
+                                        ],
+                                      ),
+                                      Expanded(
+                                        child: Padding(
+                                          padding: const EdgeInsets.only(
+                                            top: 20,
+                                            left: 32,
+                                            right: 32,
+                                            bottom: 32,
+                                          ),
+                                          child: AddNewContactAddressView(
+                                            contactId: widget.contactId,
+                                          ),
+                                        ),
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              );
+                            },
                           ),
                         ],
                       ),

From e70f5b0709eea46f42cfd4ed8dd9f7ba2aa24b20 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 18:14:30 -0600
Subject: [PATCH 313/426] WIP desktop contact options context popup menu

---
 .../subwidgets/desktop_contact_details.dart   | 262 +++++++++++++++++-
 1 file changed, 260 insertions(+), 2 deletions(-)

diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
index 1c27b6836..2cd20a839 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
@@ -131,9 +131,19 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
                     ),
                     SecondaryButton(
                       label: "Options",
-                      width: 86,
+                      width: 96,
                       buttonHeight: ButtonHeight.xxs,
-                      onPressed: () {},
+                      onPressed: () async {
+                        await showDialog<void>(
+                          context: context,
+                          barrierColor: Colors.transparent,
+                          builder: (context) {
+                            return DesktopContactOptionsMenuPopup(
+                              contactId: contact.id,
+                            );
+                          },
+                        );
+                      },
                     ),
                   ],
                 ),
@@ -330,3 +340,251 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
     );
   }
 }
+
+class DesktopContactOptionsMenuPopup extends ConsumerStatefulWidget {
+  const DesktopContactOptionsMenuPopup({Key? key, required this.contactId})
+      : super(key: key);
+
+  final String contactId;
+
+  @override
+  ConsumerState<DesktopContactOptionsMenuPopup> createState() =>
+      _DesktopContactOptionsMenuPopupState();
+}
+
+class _DesktopContactOptionsMenuPopupState
+    extends ConsumerState<DesktopContactOptionsMenuPopup> {
+  bool hoveredOnStar = false;
+  bool hoveredOnPencil = false;
+  bool hoveredOnTrash = false;
+
+  @override
+  Widget build(BuildContext context) {
+    return Stack(
+      children: [
+        Positioned(
+          top: 210,
+          left: MediaQuery.of(context).size.width - 280,
+          child: Container(
+            width: 270,
+            decoration: BoxDecoration(
+              color: Theme.of(context).extension<StackColors>()!.popupBG,
+              borderRadius: BorderRadius.circular(
+                20,
+              ),
+              boxShadow: [
+                Theme.of(context).extension<StackColors>()!.standardBoxShadow,
+              ],
+            ),
+            child: Padding(
+              padding: const EdgeInsets.all(16),
+              child: Column(
+                children: [
+                  MouseRegion(
+                    onEnter: (_) {
+                      setState(() {
+                        hoveredOnStar = true;
+                      });
+                    },
+                    onExit: (_) {
+                      setState(() {
+                        hoveredOnStar = false;
+                      });
+                    },
+                    child: RawMaterialButton(
+                      hoverColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldDefaultBG,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          1000,
+                        ),
+                      ),
+                      onPressed: () {
+                        final contact =
+                            ref.read(addressBookServiceProvider).getContactById(
+                                  widget.contactId,
+                                );
+                        ref.read(addressBookServiceProvider).editContact(
+                              contact.copyWith(
+                                isFavorite: !contact.isFavorite,
+                              ),
+                            );
+                      },
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 25,
+                          vertical: 16,
+                        ),
+                        child: Row(
+                          children: [
+                            SvgPicture.asset(
+                              Assets.svg.star,
+                              width: 24,
+                              height: 22,
+                              color: hoveredOnStar
+                                  ? Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark
+                                  : Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textFieldDefaultSearchIconLeft,
+                            ),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                            Text(
+                              ref.watch(addressBookServiceProvider.select(
+                                      (value) => value
+                                          .getContactById(widget.contactId)
+                                          .isFavorite))
+                                  ? "Remove from favorites"
+                                  : "Add to favorites",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                      context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              ),
+                            )
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 2,
+                  ),
+                  MouseRegion(
+                    onEnter: (_) {
+                      setState(() {
+                        hoveredOnPencil = true;
+                      });
+                    },
+                    onExit: (_) {
+                      setState(() {
+                        hoveredOnPencil = false;
+                      });
+                    },
+                    child: RawMaterialButton(
+                      hoverColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldDefaultBG,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          1000,
+                        ),
+                      ),
+                      onPressed: () {
+                        print("should go to edit");
+                      },
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 25,
+                          vertical: 16,
+                        ),
+                        child: Row(
+                          children: [
+                            SvgPicture.asset(
+                              Assets.svg.pencil,
+                              width: 24,
+                              height: 22,
+                              color: hoveredOnPencil
+                                  ? Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark
+                                  : Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textFieldDefaultSearchIconLeft,
+                            ),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                            Text(
+                              "Edit contact",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                      context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              ),
+                            )
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 2,
+                  ),
+                  MouseRegion(
+                    onEnter: (_) {
+                      setState(() {
+                        hoveredOnTrash = true;
+                      });
+                    },
+                    onExit: (_) {
+                      setState(() {
+                        hoveredOnTrash = false;
+                      });
+                    },
+                    child: RawMaterialButton(
+                      hoverColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldDefaultBG,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          1000,
+                        ),
+                      ),
+                      onPressed: () {
+                        print("should delete contact");
+                      },
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 25,
+                          vertical: 16,
+                        ),
+                        child: Row(
+                          children: [
+                            SvgPicture.asset(
+                              Assets.svg.trash,
+                              width: 24,
+                              height: 22,
+                              color: hoveredOnTrash
+                                  ? Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark
+                                  : Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textFieldDefaultSearchIconLeft,
+                            ),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                            Text(
+                              "Delete contact",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                      context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              ),
+                            )
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                ],
+              ),
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}

From 38251dc5edb0d5e2f6a771e53deb98aa0e96a68e Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 18:21:04 -0600
Subject: [PATCH 314/426] textStyles prep for ocean theme

---
 lib/utilities/text_styles.dart       | 54 ++++++++++++++++++++++++++++
 lib/utilities/theme/color_theme.dart |  1 +
 2 files changed, 55 insertions(+)

diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart
index 63aa19afb..db4764459 100644
--- a/lib/utilities/text_styles.dart
+++ b/lib/utilities/text_styles.dart
@@ -15,6 +15,7 @@ class STextStyles {
           fontWeight: FontWeight.w600,
           fontSize: 20,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -32,6 +33,7 @@ class STextStyles {
           fontWeight: FontWeight.w600,
           fontSize: 18,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -49,6 +51,7 @@ class STextStyles {
           fontWeight: FontWeight.w600,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -66,6 +69,7 @@ class STextStyles {
           fontWeight: FontWeight.w600,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -83,6 +87,7 @@ class STextStyles {
           fontWeight: FontWeight.w400,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -100,6 +105,7 @@ class STextStyles {
           fontWeight: FontWeight.w400,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -117,6 +123,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -134,6 +141,7 @@ class STextStyles {
           fontWeight: FontWeight.w600,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -151,6 +159,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimary,
@@ -168,6 +177,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -185,6 +195,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark3,
@@ -202,6 +213,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark3,
@@ -219,6 +231,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 12,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle1,
@@ -237,6 +250,7 @@ class STextStyles {
           fontSize: 14,
           height: 14 / 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textFieldActiveSearchIconRight,
@@ -255,6 +269,7 @@ class STextStyles {
           fontWeight: FontWeight.w700,
           fontSize: 12,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle1,
@@ -272,6 +287,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).infoItemLabel,
@@ -289,6 +305,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -306,6 +323,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -324,6 +342,7 @@ class STextStyles {
           fontSize: 14,
           height: 1.5,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle2,
@@ -343,6 +362,7 @@ class STextStyles {
           fontSize: 14,
           height: 1.5,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -361,6 +381,7 @@ class STextStyles {
           fontWeight: FontWeight.w400,
           fontSize: 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -378,6 +399,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).accentColorRed,
@@ -395,6 +417,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).infoItemIcons,
@@ -412,6 +435,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 12,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).accentColorBlue,
@@ -429,6 +453,7 @@ class STextStyles {
           fontWeight: FontWeight.w600,
           fontSize: 12,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -446,6 +471,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 12,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -463,6 +489,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 12,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -480,6 +507,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 10,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textError,
@@ -497,6 +525,7 @@ class STextStyles {
           fontWeight: FontWeight.w500,
           fontSize: 10,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle1,
@@ -517,6 +546,7 @@ class STextStyles {
           fontSize: 40,
           height: 40 / 40,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -536,6 +566,7 @@ class STextStyles {
           fontSize: 32,
           height: 32 / 32,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -555,6 +586,7 @@ class STextStyles {
           fontSize: 24,
           height: 24 / 24,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -574,6 +606,7 @@ class STextStyles {
           fontSize: 20,
           height: 30 / 20,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -593,6 +626,7 @@ class STextStyles {
           fontSize: 20,
           height: 30 / 20,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -612,6 +646,7 @@ class STextStyles {
           fontSize: 20,
           height: 28 / 20,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -631,6 +666,7 @@ class STextStyles {
           fontSize: 24,
           height: 33 / 24,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -650,6 +686,7 @@ class STextStyles {
           fontSize: 20,
           height: 26 / 20,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimary,
@@ -669,6 +706,7 @@ class STextStyles {
           fontSize: 20,
           height: 26 / 20,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimaryDisabled,
@@ -688,6 +726,7 @@ class STextStyles {
           fontSize: 20,
           height: 26 / 20,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextSecondary,
@@ -707,6 +746,7 @@ class STextStyles {
           fontSize: 20,
           height: 26 / 20,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextSecondaryDisabled,
@@ -726,6 +766,7 @@ class STextStyles {
           fontSize: 18,
           height: 27 / 18,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimaryDisabled,
@@ -745,6 +786,7 @@ class STextStyles {
           fontSize: 16,
           height: 24 / 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimaryDisabled,
@@ -764,6 +806,7 @@ class STextStyles {
           fontSize: 14,
           height: 21 / 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle1,
@@ -783,6 +826,7 @@ class STextStyles {
           fontSize: 14,
           height: 21 / 14,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -802,6 +846,7 @@ class STextStyles {
           fontSize: 16,
           height: 24 / 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextSecondary,
@@ -821,6 +866,7 @@ class STextStyles {
           fontSize: 20,
           height: 30 / 20,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle2,
@@ -840,6 +886,7 @@ class STextStyles {
           fontSize: 16,
           height: 20.8 / 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark.withOpacity(0.8),
@@ -859,6 +906,7 @@ class STextStyles {
           fontSize: 16,
           height: 20.8 / 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -878,6 +926,7 @@ class STextStyles {
           fontSize: 16,
           height: 20.8 / 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark.withOpacity(0.5),
@@ -897,6 +946,7 @@ class STextStyles {
           fontSize: 16,
           height: 20.8 / 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -915,6 +965,7 @@ class STextStyles {
           fontWeight: FontWeight.w600,
           fontSize: 8,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.roboto(
           color: _theme(context).textDark,
@@ -932,6 +983,7 @@ class STextStyles {
           fontWeight: FontWeight.w400,
           fontSize: 26,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.roboto(
           color: _theme(context).numberTextDefault,
@@ -950,6 +1002,7 @@ class STextStyles {
           fontWeight: FontWeight.w400,
           fontSize: 12,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           letterSpacing: 0.5,
@@ -969,6 +1022,7 @@ class STextStyles {
           fontWeight: FontWeight.w600,
           fontSize: 16,
         );
+      case ThemeType.oceanBreeze:
       case ThemeType.dark:
         return GoogleFonts.inter(
           letterSpacing: 0.5,
diff --git a/lib/utilities/theme/color_theme.dart b/lib/utilities/theme/color_theme.dart
index 49fd41a6e..852e2f586 100644
--- a/lib/utilities/theme/color_theme.dart
+++ b/lib/utilities/theme/color_theme.dart
@@ -5,6 +5,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 enum ThemeType {
   light,
   dark,
+  oceanBreeze,
 }
 
 abstract class StackColorTheme {

From 390c3f186ff8266479a38ce90684840b0f554042 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 18:49:56 -0600
Subject: [PATCH 315/426] temporarily disable in wallet exchange button

---
 .../wallet_view/desktop_wallet_view.dart      | 60 +++++++++----------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index a7de8fdf4..d08864eee 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -467,36 +467,36 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                         );
                       },
                     ),
-                  if (coin == Coin.firo) const SizedBox(width: 16),
-                  SecondaryButton(
-                    width: 180,
-                    buttonHeight: ButtonHeight.l,
-                    onPressed: () {
-                      _onExchangePressed(context);
-                    },
-                    label: "Exchange",
-                    icon: Container(
-                      width: 24,
-                      height: 24,
-                      decoration: BoxDecoration(
-                        borderRadius: BorderRadius.circular(24),
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .buttonBackPrimary
-                            .withOpacity(0.2),
-                      ),
-                      child: Center(
-                        child: SvgPicture.asset(
-                          Assets.svg.arrowRotate2,
-                          width: 14,
-                          height: 14,
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .buttonTextSecondary,
-                        ),
-                      ),
-                    ),
-                  ),
+                  // if (coin == Coin.firo) const SizedBox(width: 16),
+                  // SecondaryButton(
+                  //   width: 180,
+                  //   buttonHeight: ButtonHeight.l,
+                  //   onPressed: () {
+                  //     _onExchangePressed(context);
+                  //   },
+                  //   label: "Exchange",
+                  //   icon: Container(
+                  //     width: 24,
+                  //     height: 24,
+                  //     decoration: BoxDecoration(
+                  //       borderRadius: BorderRadius.circular(24),
+                  //       color: Theme.of(context)
+                  //           .extension<StackColors>()!
+                  //           .buttonBackPrimary
+                  //           .withOpacity(0.2),
+                  //     ),
+                  //     child: Center(
+                  //       child: SvgPicture.asset(
+                  //         Assets.svg.arrowRotate2,
+                  //         width: 14,
+                  //         height: 14,
+                  //         color: Theme.of(context)
+                  //             .extension<StackColors>()!
+                  //             .buttonTextSecondary,
+                  //       ),
+                  //     ),
+                  //   ),
+                  // ),
                 ],
               ),
             ),

From 4eed147f10f978125f7ebaf1b57b7410732fe287 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 17 Nov 2022 19:23:15 -0600
Subject: [PATCH 316/426] update main to check for ocean breeze theme

---
 lib/main.dart | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/main.dart b/lib/main.dart
index b1f917f58..42b4ee718 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -301,6 +301,9 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
       case "dark":
         themeType = ThemeType.dark;
         break;
+      case "oceanBreeze":
+        themeType = ThemeType.oceanBreeze;
+        break;
       case "light":
       default:
         themeType = ThemeType.light;

From 2137cffd8459b750c9bd7b056eb46c93e0f60418 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 17 Nov 2022 20:04:02 -0700
Subject: [PATCH 317/426] ocean breeze theme colors added

---
 .../appearance_settings_view.dart             |   5 +-
 lib/utilities/text_styles.dart                | 296 +++++++++++++++++
 lib/utilities/theme/ocean_breeze_colors.dart  | 306 ++++++++++++++++++
 3 files changed, 606 insertions(+), 1 deletion(-)
 create mode 100644 lib/utilities/theme/ocean_breeze_colors.dart

diff --git a/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart b/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart
index b0cf35a84..3a1b842f6 100644
--- a/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart
+++ b/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart
@@ -141,7 +141,10 @@ class AppearanceSettingsView extends ConsumerWidget {
                                             key: "colorScheme",
                                             value: (newValue
                                                     ? ThemeType.dark
-                                                    : ThemeType.light)
+                                                    : (newValue
+                                                        ? ThemeType.light
+                                                        : ThemeType
+                                                            .oceanBreeze))
                                                 .name,
                                           );
                                           ref
diff --git a/lib/utilities/text_styles.dart b/lib/utilities/text_styles.dart
index db4764459..c9dd15e1d 100644
--- a/lib/utilities/text_styles.dart
+++ b/lib/utilities/text_styles.dart
@@ -16,6 +16,11 @@ class STextStyles {
           fontSize: 20,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 20,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -34,6 +39,11 @@ class STextStyles {
           fontSize: 18,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 18,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -52,6 +62,11 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -70,6 +85,11 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -88,6 +108,11 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w400,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -106,6 +131,11 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w400,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -124,6 +154,11 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -142,6 +177,11 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -160,6 +200,11 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).buttonTextPrimary,
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimary,
@@ -178,6 +223,11 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -196,6 +246,11 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark3,
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark3,
@@ -214,6 +269,11 @@ class STextStyles {
           fontSize: 14,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark3,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark3,
@@ -232,6 +292,11 @@ class STextStyles {
           fontSize: 12,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textSubtitle1,
+          fontWeight: FontWeight.w500,
+          fontSize: 12,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle1,
@@ -251,6 +316,12 @@ class STextStyles {
           height: 14 / 14,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textFieldActiveSearchIconRight,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+          height: 14 / 14,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textFieldActiveSearchIconRight,
@@ -270,6 +341,11 @@ class STextStyles {
           fontSize: 12,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textSubtitle1,
+          fontWeight: FontWeight.w700,
+          fontSize: 12,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle1,
@@ -288,6 +364,11 @@ class STextStyles {
           fontSize: 14,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).infoItemLabel,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).infoItemLabel,
@@ -306,6 +387,11 @@ class STextStyles {
           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,
@@ -324,6 +410,11 @@ class STextStyles {
           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,
@@ -343,6 +434,12 @@ class STextStyles {
           height: 1.5,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textSubtitle2,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+          height: 1.5,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle2,
@@ -363,6 +460,12 @@ class STextStyles {
           height: 1.5,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+          height: 1.5,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -382,6 +485,11 @@ class STextStyles {
           fontSize: 14,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w400,
+          fontSize: 14,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -400,6 +508,11 @@ class STextStyles {
           fontSize: 14,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).accentColorRed,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).accentColorRed,
@@ -418,6 +531,11 @@ class STextStyles {
           fontSize: 14,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).infoItemIcons,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).infoItemIcons,
@@ -436,6 +554,11 @@ class STextStyles {
           fontSize: 12,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).accentColorBlue,
+          fontWeight: FontWeight.w500,
+          fontSize: 12,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).accentColorBlue,
@@ -454,6 +577,11 @@ class STextStyles {
           fontSize: 12,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 12,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -472,6 +600,11 @@ class STextStyles {
           fontSize: 12,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w500,
+          fontSize: 12,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -490,6 +623,11 @@ class STextStyles {
           fontSize: 12,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w500,
+          fontSize: 12,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -508,6 +646,11 @@ class STextStyles {
           fontSize: 10,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textError,
+          fontWeight: FontWeight.w500,
+          fontSize: 10,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textError,
@@ -526,6 +669,11 @@ class STextStyles {
           fontSize: 10,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textSubtitle1,
+          fontWeight: FontWeight.w500,
+          fontSize: 10,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle1,
@@ -547,6 +695,12 @@ class STextStyles {
           height: 40 / 40,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 40,
+          height: 40 / 40,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -567,6 +721,12 @@ class STextStyles {
           height: 32 / 32,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 32,
+          height: 32 / 32,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -587,6 +747,12 @@ class STextStyles {
           height: 24 / 24,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 24,
+          height: 24 / 24,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -607,6 +773,12 @@ class STextStyles {
           height: 30 / 20,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w500,
+          fontSize: 20,
+          height: 30 / 20,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -627,6 +799,12 @@ class STextStyles {
           height: 30 / 20,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w400,
+          fontSize: 20,
+          height: 30 / 20,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -647,6 +825,12 @@ class STextStyles {
           height: 28 / 20,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w400,
+          fontSize: 20,
+          height: 28 / 20,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -667,6 +851,12 @@ class STextStyles {
           height: 33 / 24,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w400,
+          fontSize: 24,
+          height: 33 / 24,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -687,6 +877,12 @@ class STextStyles {
           height: 26 / 20,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).buttonTextPrimary,
+          fontWeight: FontWeight.w500,
+          fontSize: 20,
+          height: 26 / 20,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimary,
@@ -707,6 +903,12 @@ class STextStyles {
           height: 26 / 20,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).buttonTextPrimaryDisabled,
+          fontWeight: FontWeight.w500,
+          fontSize: 20,
+          height: 26 / 20,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimaryDisabled,
@@ -727,6 +929,12 @@ class STextStyles {
           height: 26 / 20,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).buttonTextSecondary,
+          fontWeight: FontWeight.w500,
+          fontSize: 20,
+          height: 26 / 20,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextSecondary,
@@ -747,6 +955,12 @@ class STextStyles {
           height: 26 / 20,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).buttonTextSecondaryDisabled,
+          fontWeight: FontWeight.w500,
+          fontSize: 20,
+          height: 26 / 20,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextSecondaryDisabled,
@@ -767,6 +981,12 @@ class STextStyles {
           height: 27 / 18,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w500,
+          fontSize: 18,
+          height: 27 / 18,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimaryDisabled,
@@ -787,6 +1007,12 @@ class STextStyles {
           height: 24 / 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).buttonTextPrimaryDisabled,
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+          height: 24 / 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextPrimaryDisabled,
@@ -807,6 +1033,12 @@ class STextStyles {
           height: 21 / 14,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textSubtitle1,
+          fontWeight: FontWeight.w500,
+          fontSize: 14,
+          height: 21 / 14,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle1,
@@ -827,6 +1059,12 @@ class STextStyles {
           height: 21 / 14,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 14,
+          height: 21 / 14,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -847,6 +1085,12 @@ class STextStyles {
           height: 24 / 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).buttonTextSecondary,
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+          height: 24 / 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).buttonTextSecondary,
@@ -867,6 +1111,12 @@ class STextStyles {
           height: 30 / 20,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textSubtitle2,
+          fontWeight: FontWeight.w500,
+          fontSize: 20,
+          height: 30 / 20,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textSubtitle2,
@@ -887,6 +1137,12 @@ class STextStyles {
           height: 20.8 / 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark.withOpacity(0.8),
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+          height: 20.8 / 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark.withOpacity(0.8),
@@ -907,6 +1163,12 @@ class STextStyles {
           height: 20.8 / 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+          height: 20.8 / 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -927,6 +1189,12 @@ class STextStyles {
           height: 20.8 / 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark.withOpacity(0.5),
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+          height: 20.8 / 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark.withOpacity(0.5),
@@ -947,6 +1215,12 @@ class STextStyles {
           height: 20.8 / 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w500,
+          fontSize: 16,
+          height: 20.8 / 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           color: _theme(context).textDark,
@@ -966,6 +1240,11 @@ class STextStyles {
           fontSize: 8,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.roboto(
+          color: _theme(context).textDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 8,
+        );
       case ThemeType.dark:
         return GoogleFonts.roboto(
           color: _theme(context).textDark,
@@ -984,6 +1263,11 @@ class STextStyles {
           fontSize: 26,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.roboto(
+          color: _theme(context).numberTextDefault,
+          fontWeight: FontWeight.w400,
+          fontSize: 26,
+        );
       case ThemeType.dark:
         return GoogleFonts.roboto(
           color: _theme(context).numberTextDefault,
@@ -1003,6 +1287,12 @@ class STextStyles {
           fontSize: 12,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          letterSpacing: 0.5,
+          color: _theme(context).accentColorDark,
+          fontWeight: FontWeight.w400,
+          fontSize: 12,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           letterSpacing: 0.5,
@@ -1023,6 +1313,12 @@ class STextStyles {
           fontSize: 16,
         );
       case ThemeType.oceanBreeze:
+        return GoogleFonts.inter(
+          letterSpacing: 0.5,
+          color: _theme(context).accentColorDark,
+          fontWeight: FontWeight.w600,
+          fontSize: 16,
+        );
       case ThemeType.dark:
         return GoogleFonts.inter(
           letterSpacing: 0.5,
diff --git a/lib/utilities/theme/ocean_breeze_colors.dart b/lib/utilities/theme/ocean_breeze_colors.dart
new file mode 100644
index 000000000..ff2f4e85e
--- /dev/null
+++ b/lib/utilities/theme/ocean_breeze_colors.dart
@@ -0,0 +1,306 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/theme/color_theme.dart';
+
+class OceanBreezeColors extends StackColorTheme {
+  @override
+  ThemeType get themeType => ThemeType.oceanBreeze;
+
+  @override
+  Color get background => const Color(0xFFF3F7FA);
+  @override
+  Color get overlay => const Color(0xFF111215);
+
+  @override
+  Color get accentColorBlue => const Color(0xFF077CBE);
+  @override
+  Color get accentColorGreen => const Color(0xFF00A591);
+  @override
+  Color get accentColorYellow => const Color(0xFFF4C517);
+  @override
+  Color get accentColorRed => const Color(0xFFD1382D);
+  @override
+  Color get accentColorOrange => const Color(0xFFFF985F);
+  @override
+  Color get accentColorDark => const Color(0xFF232323);
+
+  @override
+  Color get shadow => const Color(0xFF388192);
+
+  @override
+  Color get textDark => const Color(0xFF232323);
+  @override
+  Color get textDark2 => const Color(0xFF333333);
+  @override
+  Color get textDark3 => const Color(0xFF696B6C);
+  @override
+  Color get textSubtitle1 => const Color(0xFF7E8284);
+  @override
+  Color get textSubtitle2 => const Color(0xFF919393);
+  @override
+  Color get textSubtitle3 => const Color(0xFFB0B2B2);
+  @override
+  Color get textSubtitle4 => const Color(0xFFD1D3D3);
+  @override
+  Color get textSubtitle5 => const Color(0xFFDEDFE1);
+  @override
+  Color get textSubtitle6 => const Color(0xFFF1F1F1);
+  @override
+  Color get textWhite => const Color(0xFFFFFFFF);
+  @override
+  Color get textFavoriteCard => const Color(0xFF232323);
+  @override
+  Color get textError => const Color(0xFF8D0006);
+
+  // button background
+  @override
+  Color get buttonBackPrimary => const Color(0xFF227386);
+  @override
+  Color get buttonBackSecondary => const Color(0xFFC2DAE2);
+  @override
+  Color get buttonBackPrimaryDisabled => const Color(0xFFBDD5DB);
+  @override
+  Color get buttonBackSecondaryDisabled => const Color(0xFFBDBDBD);
+  @override
+  Color get buttonBackBorder => const Color(0xFF227386);
+  @override
+  Color get buttonBackBorderDisabled => const Color(0xFFBDD5DB);
+
+  @override
+  Color get numberBackDefault => const Color(0xFFFFFFFF);
+  @override
+  Color get numpadBackDefault => const Color(0xFF227386);
+  @override
+  Color get bottomNavBack => const Color(0xFFFFFFFF);
+
+  // button text/element
+  @override
+  Color get buttonTextPrimary => const Color(0xFFFFFFFF);
+  @override
+  Color get buttonTextSecondary => const Color(0xFF232323);
+  @override
+  Color get buttonTextPrimaryDisabled => const Color(0xFFFFFFFF);
+  @override
+  Color get buttonTextSecondaryDisabled => const Color(0xFFBDD5DB);
+  @override
+  Color get buttonTextBorder => const Color(0xFF227386);
+  @override
+  Color get buttonTextDisabled => const Color(0xFFFFFFFF);
+  @override
+  Color get buttonTextBorderless => const Color(0xFF056EC6);
+  @override
+  Color get buttonTextBorderlessDisabled => const Color(0xFFB6B6B6);
+  @override
+  Color get numberTextDefault => const Color(0xFF232323);
+  @override
+  Color get numpadTextDefault => const Color(0xFFFFFFFF);
+  @override
+  Color get bottomNavText => const Color(0xFF232323);
+
+  // switch
+  @override
+  Color get switchBGOn => const Color(0xFF056EC6);
+  @override
+  Color get switchBGOff => const Color(0xFFCCDBF9);
+  @override
+  Color get switchBGDisabled => const Color(0xFFC5C6C9);
+  @override
+  Color get switchCircleOn => const Color(0xFFDAE2FF);
+  @override
+  Color get switchCircleOff => const Color(0xFFFBFCFF);
+  @override
+  Color get switchCircleDisabled => const Color(0xFFFBFCFF);
+
+  // step indicator background
+  @override
+  Color get stepIndicatorBGCheck => const Color(0xFFCDD9FF);
+  @override
+  Color get stepIndicatorBGNumber => const Color(0xFFCDD9FF);
+  @override
+  Color get stepIndicatorBGInactive => const Color(0xFFA6C7D1);
+  @override
+  Color get stepIndicatorBGLines => const Color(0xFF90B8DC);
+  @override
+  Color get stepIndicatorBGLinesInactive => const Color(0xFFBCD4EA);
+  @override
+  Color get stepIndicatorIconText => const Color(0xFF005BAF);
+  @override
+  Color get stepIndicatorIconNumber => const Color(0xFF005BAF);
+  @override
+  Color get stepIndicatorIconInactive => const Color(0xFFD4DFFF);
+
+  // checkbox
+  @override
+  Color get checkboxBGChecked => const Color(0xFF056EC6);
+  @override
+  Color get checkboxBorderEmpty => const Color(0xFF8C8F90);
+  @override
+  Color get checkboxBGDisabled => const Color(0xFFB0C9ED);
+  @override
+  Color get checkboxIconChecked => const Color(0xFFFFFFFF);
+  @override
+  Color get checkboxIconDisabled => const Color(0xFFFFFFFF);
+  @override
+  Color get checkboxTextLabel => const Color(0xFF232323);
+
+  // snack bar
+  @override
+  Color get snackBarBackSuccess => const Color(0xFFADD6D2);
+  @override
+  Color get snackBarBackError => const Color(0xFFF6C7C3);
+  @override
+  Color get snackBarBackInfo => const Color(0xFFCCD7FF);
+  @override
+  Color get snackBarTextSuccess => const Color(0xFF075547);
+  @override
+  Color get snackBarTextError => const Color(0xFF8D0006);
+  @override
+  Color get snackBarTextInfo => const Color(0xFF002569);
+
+  // icons
+  @override
+  Color get bottomNavIconBack => const Color(0xFFA7C7CF);
+  @override
+  Color get bottomNavIconIcon => const Color(0xFF227386);
+
+  @override
+  Color get topNavIconPrimary => const Color(0xFF227386);
+  @override
+  Color get topNavIconGreen => const Color(0xFF00A591);
+  @override
+  Color get topNavIconYellow => const Color(0xFFFDD33A);
+  @override
+  Color get topNavIconRed => const Color(0xFFEA4649);
+
+  @override
+  Color get settingsIconBack => const Color(0xFFE0E3E3);
+  @override
+  Color get settingsIconIcon => const Color(0xFF232323);
+  @override
+  Color get settingsIconBack2 => const Color(0xFF80D2C8);
+  @override
+  Color get settingsIconElement => const Color(0xFF00A591);
+
+  // text field
+  @override
+  Color get textFieldActiveBG => const Color(0xFFD3E3E7);
+  @override
+  Color get textFieldDefaultBG => const Color(0xFFD8E7EB);
+  @override
+  Color get textFieldErrorBG => const Color(0xFFF6C7C3);
+  @override
+  Color get textFieldSuccessBG => const Color(0xFFADD6D2);
+
+  @override
+  Color get textFieldActiveSearchIconLeft => const Color(0xFF86898C);
+  @override
+  Color get textFieldDefaultSearchIconLeft => const Color(0xFF86898C);
+  @override
+  Color get textFieldErrorSearchIconLeft => const Color(0xFF8D0006);
+  @override
+  Color get textFieldSuccessSearchIconLeft => const Color(0xFF006C4D);
+
+  @override
+  Color get textFieldActiveText => const Color(0xFF232323);
+  @override
+  Color get textFieldDefaultText => const Color(0xFF86898C);
+  @override
+  Color get textFieldErrorText => const Color(0xFF000000);
+  @override
+  Color get textFieldSuccessText => const Color(0xFF000000);
+
+  @override
+  Color get textFieldActiveLabel => const Color(0xFF86898C);
+  @override
+  Color get textFieldErrorLabel => const Color(0xFF8D0006);
+  @override
+  Color get textFieldSuccessLabel => const Color(0xFF077C6E);
+
+  @override
+  Color get textFieldActiveSearchIconRight => const Color(0xFF388192);
+  @override
+  Color get textFieldDefaultSearchIconRight => const Color(0xFF388192);
+  @override
+  Color get textFieldErrorSearchIconRight => const Color(0xFF8D0006);
+  @override
+  Color get textFieldSuccessSearchIconRight => const Color(0xFF077C6E);
+
+  // settings item level2
+  @override
+  Color get settingsItem2ActiveBG => const Color(0xFFFFFFFF);
+  @override
+  Color get settingsItem2ActiveText => const Color(0xFF232323);
+  @override
+  Color get settingsItem2ActiveSub => const Color(0xFF8C8F90);
+
+  // radio buttons
+  @override
+  Color get radioButtonIconBorder => const Color(0xFF056EC6);
+  @override
+  Color get radioButtonIconBorderDisabled => const Color(0xFF8C8D97);
+  @override
+  Color get radioButtonBorderEnabled => const Color(0xFF056EC6);
+  @override
+  Color get radioButtonBorderDisabled => const Color(0xFF8C8D97);
+  @override
+  Color get radioButtonIconCircle => const Color(0xFF056EC6);
+  @override
+  Color get radioButtonIconEnabled => const Color(0xFF056EC6);
+  @override
+  Color get radioButtonTextEnabled => const Color(0xFF42444B);
+  @override
+  Color get radioButtonTextDisabled => const Color(0xFF42444B);
+  @override
+  Color get radioButtonLabelEnabled => const Color(0xFF8C8F90);
+  @override
+  Color get radioButtonLabelDisabled => const Color(0xFF8C8F90);
+
+  // info text
+  @override
+  Color get infoItemBG => const Color(0xFFFFFFFF);
+  @override
+  Color get infoItemLabel => const Color(0xFF838788);
+  @override
+  Color get infoItemText => const Color(0xFF232323);
+  @override
+  Color get infoItemIcons => const Color(0xFF056EC6);
+
+  // popup
+  @override
+  Color get popupBG => const Color(0xFFFFFFFF);
+
+  // currency list
+  @override
+  Color get currencyListItemBG => const Color(0xFFF0F5F7);
+
+  // bottom nav
+  @override
+  Color get stackWalletBG => const Color(0xFFFFFFFF);
+  @override
+  Color get stackWalletMid => const Color(0xFFFFFFFF);
+  @override
+  Color get stackWalletBottom => const Color(0xFF232323);
+  @override
+  Color get bottomNavShadow => const Color(0xFF388192);
+
+  @override
+  Color get favoriteStarActive => const Color(0xFFF4C517);
+  @override
+  Color get favoriteStarInactive => const Color(0xFFB0B2B2);
+
+  @override
+  Color get splash => const Color(0xFF8E9192);
+  @override
+  Color get highlight => const Color(0xFFA9ACAC);
+  @override
+  Color get warningForeground => const Color(0xFF232323);
+  @override
+  Color get warningBackground => const Color(0xFFF6C7C3);
+  @override
+  Color get loadingOverlayTextColor => const Color(0xFFF7F7F7);
+  @override
+  Color get myStackContactIconBG => const Color(0xFFD8E7EB);
+  @override
+  Color get textConfirmTotalAmount => const Color(0xFF232323);
+  @override
+  Color get textSelectedWordTableItem => const Color(0xFF232323);
+}

From 02dadd432ca70d30197ca510474b8ee4bb29ba1b Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Thu, 17 Nov 2022 20:05:29 -0700
Subject: [PATCH 318/426] ocean breeze added

---
 lib/main.dart | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/main.dart b/lib/main.dart
index 42b4ee718..2d1bab160 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -57,6 +57,7 @@ import 'package:stackwallet/utilities/stack_file_system.dart';
 import 'package:stackwallet/utilities/theme/color_theme.dart';
 import 'package:stackwallet/utilities/theme/dark_colors.dart';
 import 'package:stackwallet/utilities/theme/light_colors.dart';
+import 'package:stackwallet/utilities/theme/ocean_breeze_colors.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:window_size/window_size.dart';
@@ -317,8 +318,11 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
 
     WidgetsBinding.instance.addPostFrameCallback((_) async {
       ref.read(colorThemeProvider.state).state =
-          StackColors.fromStackColorTheme(
-              themeType == ThemeType.dark ? DarkColors() : LightColors());
+          StackColors.fromStackColorTheme(themeType == ThemeType.dark
+              ? DarkColors()
+              : (themeType == ThemeType.light
+                  ? LightColors()
+                  : OceanBreezeColors()));
 
       if (Platform.isAndroid) {
         // fetch open file if it exists

From 17e4976a899b3a0f5ceecd20edf10d1495a0568c Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 09:07:11 -0600
Subject: [PATCH 319/426] include flushbartype in flushbar import

---
 lib/notifications/show_flush_bar.dart | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/notifications/show_flush_bar.dart b/lib/notifications/show_flush_bar.dart
index 5320c8a9d..47cea682a 100644
--- a/lib/notifications/show_flush_bar.dart
+++ b/lib/notifications/show_flush_bar.dart
@@ -6,6 +6,8 @@ import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
+export 'package:stackwallet/utilities/enums/flush_bar_type.dart';
+
 Future<dynamic> showFloatingFlushBar({
   required FlushBarType type,
   required String message,

From aa966a106dd3c603da01bf3d24b3f6358441399c Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 09:07:31 -0600
Subject: [PATCH 320/426] add delete contact functionality for desktop

---
 .../subwidgets/desktop_contact_details.dart   | 382 ++++++++++++------
 lib/widgets/address_book_card.dart            |  13 +-
 2 files changed, 260 insertions(+), 135 deletions(-)

diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
index 2cd20a839..96eed4835 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/models/paymint/transactions_model.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/add_new_contact_address_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
@@ -15,6 +16,8 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 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/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -74,8 +77,16 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
 
   @override
   Widget build(BuildContext context) {
-    final contact = ref.watch(addressBookServiceProvider
-        .select((value) => value.getContactById(widget.contactId)));
+    // provider hack to prevent trying to update widget with deleted contact
+    Contact? _contact;
+    try {
+      _contact = ref.watch(addressBookServiceProvider
+          .select((value) => value.getContactById(widget.contactId)));
+    } catch (_) {
+      return Container();
+    }
+
+    final contact = _contact!;
 
     return Row(
       crossAxisAlignment: CrossAxisAlignment.start,
@@ -129,22 +140,23 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
                         ),
                       ],
                     ),
-                    SecondaryButton(
-                      label: "Options",
-                      width: 96,
-                      buttonHeight: ButtonHeight.xxs,
-                      onPressed: () async {
-                        await showDialog<void>(
-                          context: context,
-                          barrierColor: Colors.transparent,
-                          builder: (context) {
-                            return DesktopContactOptionsMenuPopup(
-                              contactId: contact.id,
-                            );
-                          },
-                        );
-                      },
-                    ),
+                    if (widget.contactId != "default")
+                      SecondaryButton(
+                        label: "Options",
+                        width: 96,
+                        buttonHeight: ButtonHeight.xxs,
+                        onPressed: () async {
+                          await showDialog<void>(
+                            context: context,
+                            barrierColor: Colors.transparent,
+                            builder: (context) {
+                              return DesktopContactOptionsMenuPopup(
+                                contactId: contact.id,
+                              );
+                            },
+                          );
+                        },
+                      ),
                   ],
                 ),
                 const SizedBox(
@@ -453,132 +465,238 @@ class _DesktopContactOptionsMenuPopupState
                       ),
                     ),
                   ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  MouseRegion(
-                    onEnter: (_) {
-                      setState(() {
-                        hoveredOnPencil = true;
-                      });
-                    },
-                    onExit: (_) {
-                      setState(() {
-                        hoveredOnPencil = false;
-                      });
-                    },
-                    child: RawMaterialButton(
-                      hoverColor: Theme.of(context)
-                          .extension<StackColors>()!
-                          .textFieldDefaultBG,
-                      shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(
-                          1000,
-                        ),
-                      ),
-                      onPressed: () {
-                        print("should go to edit");
+                  if (widget.contactId != "default")
+                    const SizedBox(
+                      height: 2,
+                    ),
+                  if (widget.contactId != "default")
+                    MouseRegion(
+                      onEnter: (_) {
+                        setState(() {
+                          hoveredOnPencil = true;
+                        });
                       },
-                      child: Padding(
-                        padding: const EdgeInsets.symmetric(
-                          horizontal: 25,
-                          vertical: 16,
+                      onExit: (_) {
+                        setState(() {
+                          hoveredOnPencil = false;
+                        });
+                      },
+                      child: RawMaterialButton(
+                        hoverColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
+                        shape: RoundedRectangleBorder(
+                          borderRadius: BorderRadius.circular(
+                            1000,
+                          ),
                         ),
-                        child: Row(
-                          children: [
-                            SvgPicture.asset(
-                              Assets.svg.pencil,
-                              width: 24,
-                              height: 22,
-                              color: hoveredOnPencil
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textFieldDefaultSearchIconLeft,
-                            ),
-                            const SizedBox(
-                              width: 12,
-                            ),
-                            Text(
-                              "Edit contact",
-                              style: STextStyles.desktopTextExtraExtraSmall(
-                                      context)
-                                  .copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textDark,
+                        onPressed: () {
+                          print("should go to edit");
+                        },
+                        child: Padding(
+                          padding: const EdgeInsets.symmetric(
+                            horizontal: 25,
+                            vertical: 16,
+                          ),
+                          child: Row(
+                            children: [
+                              SvgPicture.asset(
+                                Assets.svg.pencil,
+                                width: 24,
+                                height: 22,
+                                color: hoveredOnPencil
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textFieldDefaultSearchIconLeft,
                               ),
-                            )
-                          ],
+                              const SizedBox(
+                                width: 12,
+                              ),
+                              Text(
+                                "Edit contact",
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                        context)
+                                    .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark,
+                                ),
+                              )
+                            ],
+                          ),
                         ),
                       ),
                     ),
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  MouseRegion(
-                    onEnter: (_) {
-                      setState(() {
-                        hoveredOnTrash = true;
-                      });
-                    },
-                    onExit: (_) {
-                      setState(() {
-                        hoveredOnTrash = false;
-                      });
-                    },
-                    child: RawMaterialButton(
-                      hoverColor: Theme.of(context)
-                          .extension<StackColors>()!
-                          .textFieldDefaultBG,
-                      shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(
-                          1000,
-                        ),
-                      ),
-                      onPressed: () {
-                        print("should delete contact");
+                  if (widget.contactId != "default")
+                    const SizedBox(
+                      height: 2,
+                    ),
+                  if (widget.contactId != "default")
+                    MouseRegion(
+                      onEnter: (_) {
+                        setState(() {
+                          hoveredOnTrash = true;
+                        });
                       },
-                      child: Padding(
-                        padding: const EdgeInsets.symmetric(
-                          horizontal: 25,
-                          vertical: 16,
+                      onExit: (_) {
+                        setState(() {
+                          hoveredOnTrash = false;
+                        });
+                      },
+                      child: RawMaterialButton(
+                        hoverColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
+                        shape: RoundedRectangleBorder(
+                          borderRadius: BorderRadius.circular(
+                            1000,
+                          ),
                         ),
-                        child: Row(
-                          children: [
-                            SvgPicture.asset(
-                              Assets.svg.trash,
-                              width: 24,
-                              height: 22,
-                              color: hoveredOnTrash
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textFieldDefaultSearchIconLeft,
-                            ),
-                            const SizedBox(
-                              width: 12,
-                            ),
-                            Text(
-                              "Delete contact",
-                              style: STextStyles.desktopTextExtraExtraSmall(
-                                      context)
-                                  .copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textDark,
+                        onPressed: () {
+                          final contact = ref
+                              .read(addressBookServiceProvider)
+                              .getContactById(widget.contactId);
+
+                          // pop context menu
+                          Navigator.of(context).pop();
+
+                          showDialog<dynamic>(
+                            context: context,
+                            useSafeArea: true,
+                            barrierDismissible: true,
+                            builder: (_) => DesktopDialog(
+                              maxWidth: 500,
+                              maxHeight: 300,
+                              child: Column(
+                                children: [
+                                  Row(
+                                    mainAxisAlignment:
+                                        MainAxisAlignment.spaceBetween,
+                                    children: [
+                                      Padding(
+                                        padding: const EdgeInsets.only(
+                                          left: 32,
+                                        ),
+                                        child: Text(
+                                          "Delete ${contact.name}?",
+                                          style: STextStyles.desktopH3(context),
+                                        ),
+                                      ),
+                                      const DesktopDialogCloseButton(),
+                                    ],
+                                  ),
+                                  Expanded(
+                                    child: Padding(
+                                      padding: const EdgeInsets.only(
+                                        left: 32,
+                                        right: 32,
+                                        bottom: 32,
+                                      ),
+                                      child: Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          const Spacer(
+                                            flex: 1,
+                                          ),
+                                          Text(
+                                            "Contact will be deleted permanently!",
+                                            style: STextStyles.desktopTextSmall(
+                                                context),
+                                          ),
+                                          const Spacer(
+                                            flex: 2,
+                                          ),
+                                          Row(
+                                            children: [
+                                              Expanded(
+                                                child: SecondaryButton(
+                                                  label: "Cancel",
+                                                  onPressed:
+                                                      Navigator.of(context).pop,
+                                                  buttonHeight: ButtonHeight.l,
+                                                ),
+                                              ),
+                                              const SizedBox(
+                                                width: 16,
+                                              ),
+                                              Expanded(
+                                                child: Consumer(
+                                                  builder: (context, ref, __) =>
+                                                      PrimaryButton(
+                                                    label: "Delete",
+                                                    buttonHeight:
+                                                        ButtonHeight.l,
+                                                    onPressed: () {
+                                                      ref
+                                                          .read(
+                                                              addressBookServiceProvider)
+                                                          .removeContact(
+                                                              contact.id);
+                                                      Navigator.of(context)
+                                                          .pop();
+                                                      showFloatingFlushBar(
+                                                        type: FlushBarType
+                                                            .success,
+                                                        message:
+                                                            "${contact.name} deleted",
+                                                        context: context,
+                                                      );
+                                                    },
+                                                  ),
+                                                ),
+                                              ),
+                                            ],
+                                          )
+                                        ],
+                                      ),
+                                    ),
+                                  ),
+                                ],
                               ),
-                            )
-                          ],
+                            ),
+                          );
+                        },
+                        child: Padding(
+                          padding: const EdgeInsets.symmetric(
+                            horizontal: 25,
+                            vertical: 16,
+                          ),
+                          child: Row(
+                            children: [
+                              SvgPicture.asset(
+                                Assets.svg.trash,
+                                width: 24,
+                                height: 22,
+                                color: hoveredOnTrash
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textFieldDefaultSearchIconLeft,
+                              ),
+                              const SizedBox(
+                                width: 12,
+                              ),
+                              Text(
+                                "Delete contact",
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                        context)
+                                    .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark,
+                                ),
+                              )
+                            ],
+                          ),
                         ),
                       ),
                     ),
-                  ),
                 ],
               ),
             ),
diff --git a/lib/widgets/address_book_card.dart b/lib/widgets/address_book_card.dart
index b79f89662..dfa655f86 100644
--- a/lib/widgets/address_book_card.dart
+++ b/lib/widgets/address_book_card.dart
@@ -1,6 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
@@ -44,10 +45,16 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
 
   @override
   Widget build(BuildContext context) {
-    // final isTiny = SizingUtilities.isTinyWidth(context);
+    // provider hack to prevent trying to update widget with deleted contact
+    Contact? _contact;
+    try {
+      _contact = ref.watch(addressBookServiceProvider
+          .select((value) => value.getContactById(contactId)));
+    } catch (_) {
+      return Container();
+    }
 
-    final contact = ref.watch(addressBookServiceProvider
-        .select((value) => value.getContactById(contactId)));
+    final contact = _contact!;
 
     final List<Coin> coins = [];
     for (var element in contact.addresses) {

From 07f229f2a0089a8a566ea846fa1e1d00b0fcc181 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 09:19:48 -0600
Subject: [PATCH 321/426] refactor popup

---
 .../subwidgets/desktop_contact_details.dart   | 358 +----------------
 .../desktop_contact_options_menu_popup.dart   | 366 ++++++++++++++++++
 2 files changed, 367 insertions(+), 357 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_options_menu_popup.dart

diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
index 96eed4835..62cd993af 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_details.dart
@@ -3,9 +3,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/models/contact.dart';
 import 'package:stackwallet/models/paymint/transactions_model.dart';
-import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/add_new_contact_address_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_address_card.dart';
+import 'package:stackwallet/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_options_menu_popup.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
@@ -16,8 +16,6 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 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/desktop/desktop_dialog.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
-import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -352,357 +350,3 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
     );
   }
 }
-
-class DesktopContactOptionsMenuPopup extends ConsumerStatefulWidget {
-  const DesktopContactOptionsMenuPopup({Key? key, required this.contactId})
-      : super(key: key);
-
-  final String contactId;
-
-  @override
-  ConsumerState<DesktopContactOptionsMenuPopup> createState() =>
-      _DesktopContactOptionsMenuPopupState();
-}
-
-class _DesktopContactOptionsMenuPopupState
-    extends ConsumerState<DesktopContactOptionsMenuPopup> {
-  bool hoveredOnStar = false;
-  bool hoveredOnPencil = false;
-  bool hoveredOnTrash = false;
-
-  @override
-  Widget build(BuildContext context) {
-    return Stack(
-      children: [
-        Positioned(
-          top: 210,
-          left: MediaQuery.of(context).size.width - 280,
-          child: Container(
-            width: 270,
-            decoration: BoxDecoration(
-              color: Theme.of(context).extension<StackColors>()!.popupBG,
-              borderRadius: BorderRadius.circular(
-                20,
-              ),
-              boxShadow: [
-                Theme.of(context).extension<StackColors>()!.standardBoxShadow,
-              ],
-            ),
-            child: Padding(
-              padding: const EdgeInsets.all(16),
-              child: Column(
-                children: [
-                  MouseRegion(
-                    onEnter: (_) {
-                      setState(() {
-                        hoveredOnStar = true;
-                      });
-                    },
-                    onExit: (_) {
-                      setState(() {
-                        hoveredOnStar = false;
-                      });
-                    },
-                    child: RawMaterialButton(
-                      hoverColor: Theme.of(context)
-                          .extension<StackColors>()!
-                          .textFieldDefaultBG,
-                      shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(
-                          1000,
-                        ),
-                      ),
-                      onPressed: () {
-                        final contact =
-                            ref.read(addressBookServiceProvider).getContactById(
-                                  widget.contactId,
-                                );
-                        ref.read(addressBookServiceProvider).editContact(
-                              contact.copyWith(
-                                isFavorite: !contact.isFavorite,
-                              ),
-                            );
-                      },
-                      child: Padding(
-                        padding: const EdgeInsets.symmetric(
-                          horizontal: 25,
-                          vertical: 16,
-                        ),
-                        child: Row(
-                          children: [
-                            SvgPicture.asset(
-                              Assets.svg.star,
-                              width: 24,
-                              height: 22,
-                              color: hoveredOnStar
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textFieldDefaultSearchIconLeft,
-                            ),
-                            const SizedBox(
-                              width: 12,
-                            ),
-                            Text(
-                              ref.watch(addressBookServiceProvider.select(
-                                      (value) => value
-                                          .getContactById(widget.contactId)
-                                          .isFavorite))
-                                  ? "Remove from favorites"
-                                  : "Add to favorites",
-                              style: STextStyles.desktopTextExtraExtraSmall(
-                                      context)
-                                  .copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textDark,
-                              ),
-                            )
-                          ],
-                        ),
-                      ),
-                    ),
-                  ),
-                  if (widget.contactId != "default")
-                    const SizedBox(
-                      height: 2,
-                    ),
-                  if (widget.contactId != "default")
-                    MouseRegion(
-                      onEnter: (_) {
-                        setState(() {
-                          hoveredOnPencil = true;
-                        });
-                      },
-                      onExit: (_) {
-                        setState(() {
-                          hoveredOnPencil = false;
-                        });
-                      },
-                      child: RawMaterialButton(
-                        hoverColor: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textFieldDefaultBG,
-                        shape: RoundedRectangleBorder(
-                          borderRadius: BorderRadius.circular(
-                            1000,
-                          ),
-                        ),
-                        onPressed: () {
-                          print("should go to edit");
-                        },
-                        child: Padding(
-                          padding: const EdgeInsets.symmetric(
-                            horizontal: 25,
-                            vertical: 16,
-                          ),
-                          child: Row(
-                            children: [
-                              SvgPicture.asset(
-                                Assets.svg.pencil,
-                                width: 24,
-                                height: 22,
-                                color: hoveredOnPencil
-                                    ? Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textDark
-                                    : Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textFieldDefaultSearchIconLeft,
-                              ),
-                              const SizedBox(
-                                width: 12,
-                              ),
-                              Text(
-                                "Edit contact",
-                                style: STextStyles.desktopTextExtraExtraSmall(
-                                        context)
-                                    .copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark,
-                                ),
-                              )
-                            ],
-                          ),
-                        ),
-                      ),
-                    ),
-                  if (widget.contactId != "default")
-                    const SizedBox(
-                      height: 2,
-                    ),
-                  if (widget.contactId != "default")
-                    MouseRegion(
-                      onEnter: (_) {
-                        setState(() {
-                          hoveredOnTrash = true;
-                        });
-                      },
-                      onExit: (_) {
-                        setState(() {
-                          hoveredOnTrash = false;
-                        });
-                      },
-                      child: RawMaterialButton(
-                        hoverColor: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textFieldDefaultBG,
-                        shape: RoundedRectangleBorder(
-                          borderRadius: BorderRadius.circular(
-                            1000,
-                          ),
-                        ),
-                        onPressed: () {
-                          final contact = ref
-                              .read(addressBookServiceProvider)
-                              .getContactById(widget.contactId);
-
-                          // pop context menu
-                          Navigator.of(context).pop();
-
-                          showDialog<dynamic>(
-                            context: context,
-                            useSafeArea: true,
-                            barrierDismissible: true,
-                            builder: (_) => DesktopDialog(
-                              maxWidth: 500,
-                              maxHeight: 300,
-                              child: Column(
-                                children: [
-                                  Row(
-                                    mainAxisAlignment:
-                                        MainAxisAlignment.spaceBetween,
-                                    children: [
-                                      Padding(
-                                        padding: const EdgeInsets.only(
-                                          left: 32,
-                                        ),
-                                        child: Text(
-                                          "Delete ${contact.name}?",
-                                          style: STextStyles.desktopH3(context),
-                                        ),
-                                      ),
-                                      const DesktopDialogCloseButton(),
-                                    ],
-                                  ),
-                                  Expanded(
-                                    child: Padding(
-                                      padding: const EdgeInsets.only(
-                                        left: 32,
-                                        right: 32,
-                                        bottom: 32,
-                                      ),
-                                      child: Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
-                                        children: [
-                                          const Spacer(
-                                            flex: 1,
-                                          ),
-                                          Text(
-                                            "Contact will be deleted permanently!",
-                                            style: STextStyles.desktopTextSmall(
-                                                context),
-                                          ),
-                                          const Spacer(
-                                            flex: 2,
-                                          ),
-                                          Row(
-                                            children: [
-                                              Expanded(
-                                                child: SecondaryButton(
-                                                  label: "Cancel",
-                                                  onPressed:
-                                                      Navigator.of(context).pop,
-                                                  buttonHeight: ButtonHeight.l,
-                                                ),
-                                              ),
-                                              const SizedBox(
-                                                width: 16,
-                                              ),
-                                              Expanded(
-                                                child: Consumer(
-                                                  builder: (context, ref, __) =>
-                                                      PrimaryButton(
-                                                    label: "Delete",
-                                                    buttonHeight:
-                                                        ButtonHeight.l,
-                                                    onPressed: () {
-                                                      ref
-                                                          .read(
-                                                              addressBookServiceProvider)
-                                                          .removeContact(
-                                                              contact.id);
-                                                      Navigator.of(context)
-                                                          .pop();
-                                                      showFloatingFlushBar(
-                                                        type: FlushBarType
-                                                            .success,
-                                                        message:
-                                                            "${contact.name} deleted",
-                                                        context: context,
-                                                      );
-                                                    },
-                                                  ),
-                                                ),
-                                              ),
-                                            ],
-                                          )
-                                        ],
-                                      ),
-                                    ),
-                                  ),
-                                ],
-                              ),
-                            ),
-                          );
-                        },
-                        child: Padding(
-                          padding: const EdgeInsets.symmetric(
-                            horizontal: 25,
-                            vertical: 16,
-                          ),
-                          child: Row(
-                            children: [
-                              SvgPicture.asset(
-                                Assets.svg.trash,
-                                width: 24,
-                                height: 22,
-                                color: hoveredOnTrash
-                                    ? Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textDark
-                                    : Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textFieldDefaultSearchIconLeft,
-                              ),
-                              const SizedBox(
-                                width: 12,
-                              ),
-                              Text(
-                                "Delete contact",
-                                style: STextStyles.desktopTextExtraExtraSmall(
-                                        context)
-                                    .copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark,
-                                ),
-                              )
-                            ],
-                          ),
-                        ),
-                      ),
-                    ),
-                ],
-              ),
-            ),
-          ),
-        ),
-      ],
-    );
-  }
-}
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_options_menu_popup.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_options_menu_popup.dart
new file mode 100644
index 000000000..88bd6abf0
--- /dev/null
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_options_menu_popup.dart
@@ -0,0 +1,366 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/providers/global/address_book_service_provider.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+class DesktopContactOptionsMenuPopup extends ConsumerStatefulWidget {
+  const DesktopContactOptionsMenuPopup({Key? key, required this.contactId})
+      : super(key: key);
+
+  final String contactId;
+
+  @override
+  ConsumerState<DesktopContactOptionsMenuPopup> createState() =>
+      _DesktopContactOptionsMenuPopupState();
+}
+
+class _DesktopContactOptionsMenuPopupState
+    extends ConsumerState<DesktopContactOptionsMenuPopup> {
+  bool hoveredOnStar = false;
+  bool hoveredOnPencil = false;
+  bool hoveredOnTrash = false;
+
+  @override
+  Widget build(BuildContext context) {
+    return Stack(
+      children: [
+        Positioned(
+          top: 210,
+          left: MediaQuery.of(context).size.width - 280,
+          child: Container(
+            width: 270,
+            decoration: BoxDecoration(
+              color: Theme.of(context).extension<StackColors>()!.popupBG,
+              borderRadius: BorderRadius.circular(
+                20,
+              ),
+              boxShadow: [
+                Theme.of(context).extension<StackColors>()!.standardBoxShadow,
+              ],
+            ),
+            child: Padding(
+              padding: const EdgeInsets.all(16),
+              child: Column(
+                children: [
+                  MouseRegion(
+                    onEnter: (_) {
+                      setState(() {
+                        hoveredOnStar = true;
+                      });
+                    },
+                    onExit: (_) {
+                      setState(() {
+                        hoveredOnStar = false;
+                      });
+                    },
+                    child: RawMaterialButton(
+                      hoverColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldDefaultBG,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          1000,
+                        ),
+                      ),
+                      onPressed: () {
+                        final contact =
+                            ref.read(addressBookServiceProvider).getContactById(
+                                  widget.contactId,
+                                );
+                        ref.read(addressBookServiceProvider).editContact(
+                              contact.copyWith(
+                                isFavorite: !contact.isFavorite,
+                              ),
+                            );
+                      },
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 25,
+                          vertical: 16,
+                        ),
+                        child: Row(
+                          children: [
+                            SvgPicture.asset(
+                              Assets.svg.star,
+                              width: 24,
+                              height: 22,
+                              color: hoveredOnStar
+                                  ? Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark
+                                  : Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textFieldDefaultSearchIconLeft,
+                            ),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                            Text(
+                              ref.watch(addressBookServiceProvider.select(
+                                      (value) => value
+                                          .getContactById(widget.contactId)
+                                          .isFavorite))
+                                  ? "Remove from favorites"
+                                  : "Add to favorites",
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                      context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              ),
+                            )
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                  if (widget.contactId != "default")
+                    const SizedBox(
+                      height: 2,
+                    ),
+                  if (widget.contactId != "default")
+                    MouseRegion(
+                      onEnter: (_) {
+                        setState(() {
+                          hoveredOnPencil = true;
+                        });
+                      },
+                      onExit: (_) {
+                        setState(() {
+                          hoveredOnPencil = false;
+                        });
+                      },
+                      child: RawMaterialButton(
+                        hoverColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
+                        shape: RoundedRectangleBorder(
+                          borderRadius: BorderRadius.circular(
+                            1000,
+                          ),
+                        ),
+                        onPressed: () {
+                          print("should go to edit");
+                        },
+                        child: Padding(
+                          padding: const EdgeInsets.symmetric(
+                            horizontal: 25,
+                            vertical: 16,
+                          ),
+                          child: Row(
+                            children: [
+                              SvgPicture.asset(
+                                Assets.svg.pencil,
+                                width: 24,
+                                height: 22,
+                                color: hoveredOnPencil
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textFieldDefaultSearchIconLeft,
+                              ),
+                              const SizedBox(
+                                width: 12,
+                              ),
+                              Text(
+                                "Edit contact",
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                        context)
+                                    .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark,
+                                ),
+                              )
+                            ],
+                          ),
+                        ),
+                      ),
+                    ),
+                  if (widget.contactId != "default")
+                    const SizedBox(
+                      height: 2,
+                    ),
+                  if (widget.contactId != "default")
+                    MouseRegion(
+                      onEnter: (_) {
+                        setState(() {
+                          hoveredOnTrash = true;
+                        });
+                      },
+                      onExit: (_) {
+                        setState(() {
+                          hoveredOnTrash = false;
+                        });
+                      },
+                      child: RawMaterialButton(
+                        hoverColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textFieldDefaultBG,
+                        shape: RoundedRectangleBorder(
+                          borderRadius: BorderRadius.circular(
+                            1000,
+                          ),
+                        ),
+                        onPressed: () {
+                          final contact = ref
+                              .read(addressBookServiceProvider)
+                              .getContactById(widget.contactId);
+
+                          // pop context menu
+                          Navigator.of(context).pop();
+
+                          showDialog<dynamic>(
+                            context: context,
+                            useSafeArea: true,
+                            barrierDismissible: true,
+                            builder: (_) => DesktopDialog(
+                              maxWidth: 500,
+                              maxHeight: 300,
+                              child: Column(
+                                children: [
+                                  Row(
+                                    mainAxisAlignment:
+                                        MainAxisAlignment.spaceBetween,
+                                    children: [
+                                      Padding(
+                                        padding: const EdgeInsets.only(
+                                          left: 32,
+                                        ),
+                                        child: Text(
+                                          "Delete ${contact.name}?",
+                                          style: STextStyles.desktopH3(context),
+                                        ),
+                                      ),
+                                      const DesktopDialogCloseButton(),
+                                    ],
+                                  ),
+                                  Expanded(
+                                    child: Padding(
+                                      padding: const EdgeInsets.only(
+                                        left: 32,
+                                        right: 32,
+                                        bottom: 32,
+                                      ),
+                                      child: Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          const Spacer(
+                                            flex: 1,
+                                          ),
+                                          Text(
+                                            "Contact will be deleted permanently!",
+                                            style: STextStyles.desktopTextSmall(
+                                                context),
+                                          ),
+                                          const Spacer(
+                                            flex: 2,
+                                          ),
+                                          Row(
+                                            children: [
+                                              Expanded(
+                                                child: SecondaryButton(
+                                                  label: "Cancel",
+                                                  onPressed:
+                                                      Navigator.of(context).pop,
+                                                  buttonHeight: ButtonHeight.l,
+                                                ),
+                                              ),
+                                              const SizedBox(
+                                                width: 16,
+                                              ),
+                                              Expanded(
+                                                child: Consumer(
+                                                  builder: (context, ref, __) =>
+                                                      PrimaryButton(
+                                                    label: "Delete",
+                                                    buttonHeight:
+                                                        ButtonHeight.l,
+                                                    onPressed: () {
+                                                      ref
+                                                          .read(
+                                                              addressBookServiceProvider)
+                                                          .removeContact(
+                                                              contact.id);
+                                                      Navigator.of(context)
+                                                          .pop();
+                                                      showFloatingFlushBar(
+                                                        type: FlushBarType
+                                                            .success,
+                                                        message:
+                                                            "${contact.name} deleted",
+                                                        context: context,
+                                                      );
+                                                    },
+                                                  ),
+                                                ),
+                                              ),
+                                            ],
+                                          )
+                                        ],
+                                      ),
+                                    ),
+                                  ),
+                                ],
+                              ),
+                            ),
+                          );
+                        },
+                        child: Padding(
+                          padding: const EdgeInsets.symmetric(
+                            horizontal: 25,
+                            vertical: 16,
+                          ),
+                          child: Row(
+                            children: [
+                              SvgPicture.asset(
+                                Assets.svg.trash,
+                                width: 24,
+                                height: 22,
+                                color: hoveredOnTrash
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textFieldDefaultSearchIconLeft,
+                              ),
+                              const SizedBox(
+                                width: 12,
+                              ),
+                              Text(
+                                "Delete contact",
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                        context)
+                                    .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark,
+                                ),
+                              )
+                            ],
+                          ),
+                        ),
+                      ),
+                    ),
+                ],
+              ),
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}

From d4b7ec0f174101e406796f4a2bc6162a0c9f0f58 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 09:54:26 -0600
Subject: [PATCH 322/426] desktop edit contact

---
 .../edit_contact_name_emoji_view.dart         | 576 ++++++++++--------
 .../desktop_contact_options_menu_popup.dart   | 252 ++++----
 2 files changed, 462 insertions(+), 366 deletions(-)

diff --git a/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart b/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart
index fff01eee3..a9b264b3c 100644
--- a/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart
+++ b/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
 import 'package:emojis/emoji.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -7,14 +9,17 @@ import 'package:stackwallet/utilities/assets.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/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/emoji_select_sheet.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';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class EditContactNameEmojiView extends ConsumerStatefulWidget {
   const EditContactNameEmojiView({
     Key? key,
@@ -69,268 +74,323 @@ class _EditContactNameEmojiViewState
     final contact = ref.watch(addressBookServiceProvider
         .select((value) => value.getContactById(contactId)));
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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 contact",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (context, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      children: [
-                        GestureDetector(
-                          onTap: () {
-                            if (_selectedEmoji != null) {
-                              setState(() {
-                                _selectedEmoji = null;
-                              });
-                              return;
-                            }
-                            showModalBottomSheet<dynamic>(
-                              backgroundColor: Colors.transparent,
-                              context: context,
-                              shape: const RoundedRectangleBorder(
-                                borderRadius: BorderRadius.vertical(
-                                  top: Radius.circular(20),
-                                ),
-                              ),
-                              builder: (_) => const EmojiSelectSheet(),
-                            ).then((value) {
-                              if (value is Emoji) {
-                                setState(() {
-                                  _selectedEmoji = value;
-                                });
-                              }
-                            });
-                          },
-                          child: SizedBox(
-                            height: 48,
-                            width: 48,
-                            child: Stack(
-                              children: [
-                                Container(
-                                  height: 48,
-                                  width: 48,
-                                  decoration: BoxDecoration(
-                                    borderRadius: BorderRadius.circular(24),
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textFieldActiveBG,
-                                  ),
-                                  child: Center(
-                                    child: _selectedEmoji == null
-                                        ? SvgPicture.asset(
-                                            Assets.svg.user,
-                                            height: 24,
-                                            width: 24,
-                                          )
-                                        : Text(
-                                            _selectedEmoji!.char,
-                                            style: STextStyles.pageTitleH1(
-                                                context),
-                                          ),
-                                  ),
-                                ),
-                                Align(
-                                  alignment: Alignment.bottomRight,
-                                  child: Container(
-                                    height: 14,
-                                    width: 14,
-                                    decoration: BoxDecoration(
-                                        borderRadius: BorderRadius.circular(14),
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorDark),
-                                    child: Center(
-                                      child: _selectedEmoji == null
-                                          ? SvgPicture.asset(
-                                              Assets.svg.plus,
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textWhite,
-                                              width: 12,
-                                              height: 12,
-                                            )
-                                          : SvgPicture.asset(
-                                              Assets.svg.thickX,
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textWhite,
-                                              width: 8,
-                                              height: 8,
-                                            ),
-                                    ),
-                                  ),
-                                )
-                              ],
-                            ),
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            controller: nameController,
-                            focusNode: nameFocusNode,
-                            style: STextStyles.field(context),
-                            onChanged: (_) => setState(() {}),
-                            decoration: standardInputDecoration(
-                              "Enter contact name",
-                              nameFocusNode,
-                              context,
-                            ).copyWith(
-                              suffixIcon: nameController.text.isNotEmpty
-                                  ? Padding(
-                                      padding: const EdgeInsets.only(right: 0),
-                                      child: UnconstrainedBox(
-                                        child: Row(
-                                          children: [
-                                            TextFieldIconButton(
-                                              child: const XIcon(),
-                                              onTap: () async {
-                                                setState(() {
-                                                  nameController.text = "";
-                                                });
-                                              },
-                                            ),
-                                          ],
-                                        ),
-                                      ),
-                                    )
-                                  : null,
-                            ),
-                          ),
-                        ),
-                        const Spacer(),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        Row(
-                          children: [
-                            Expanded(
-                              child: TextButton(
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getSecondaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Cancel",
-                                  style: STextStyles.button(context).copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .accentColorDark),
-                                ),
-                                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();
-                                  }
-                                },
-                              ),
-                            ),
-                            const SizedBox(
-                              width: 16,
-                            ),
-                            Expanded(
-                              child: Builder(
-                                builder: (context) {
-                                  bool shouldEnableSave =
-                                      nameController.text.isNotEmpty;
+    final isDesktop = Util.isDesktop;
+    final double emojiSize = isDesktop ? 56 : 48;
 
-                                  return TextButton(
-                                    style: shouldEnableSave
-                                        ? Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .getPrimaryEnabledButtonColor(
-                                                context)
-                                        : Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .getPrimaryDisabledButtonColor(
-                                                context),
-                                    onPressed: shouldEnableSave
-                                        ? () async {
-                                            if (FocusScope.of(context)
-                                                .hasFocus) {
-                                              FocusScope.of(context).unfocus();
-                                              await Future<void>.delayed(
-                                                const Duration(
-                                                    milliseconds: 75),
-                                              );
-                                            }
-                                            final editedContact =
-                                                contact.copyWith(
-                                              shouldCopyEmojiWithNull: true,
-                                              name: nameController.text,
-                                              emojiChar: _selectedEmoji == null
-                                                  ? null
-                                                  : _selectedEmoji!.char,
-                                            );
-                                            ref
-                                                .read(
-                                                    addressBookServiceProvider)
-                                                .editContact(
-                                                  editedContact,
-                                                );
-                                            if (mounted) {
-                                              Navigator.of(context).pop();
-                                            }
-                                          }
-                                        : null,
-                                    child: Text(
-                                      "Save",
-                                      style: STextStyles.button(context),
-                                    ),
-                                  );
-                                },
-                              ),
-                            ),
-                          ],
-                        )
-                      ],
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) => Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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 contact",
+            style: STextStyles.navBarTitle(context),
+          ),
+        ),
+        body: LayoutBuilder(
+          builder: (context, constraints) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: child,
                     ),
                   ),
                 ),
               ),
+            );
+          },
+        ),
+      ),
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.center,
+            children: [
+              GestureDetector(
+                onTap: () {
+                  if (_selectedEmoji != null) {
+                    setState(() {
+                      _selectedEmoji = null;
+                    });
+                    return;
+                  }
+                  if (isDesktop) {
+                    showDialog<dynamic>(
+                        barrierColor: Colors.transparent,
+                        context: context,
+                        builder: (context) {
+                          return const DesktopDialog(
+                            maxHeight: 700,
+                            maxWidth: 600,
+                            child: Padding(
+                              padding: EdgeInsets.only(
+                                left: 32,
+                                right: 20,
+                                top: 32,
+                                bottom: 32,
+                              ),
+                              child: EmojiSelectSheet(),
+                            ),
+                          );
+                        }).then((value) {
+                      if (value is Emoji) {
+                        setState(() {
+                          _selectedEmoji = value;
+                        });
+                      }
+                    });
+                  } else {
+                    showModalBottomSheet<dynamic>(
+                      backgroundColor: Colors.transparent,
+                      context: context,
+                      shape: const RoundedRectangleBorder(
+                        borderRadius: BorderRadius.vertical(
+                          top: Radius.circular(20),
+                        ),
+                      ),
+                      builder: (_) => const EmojiSelectSheet(),
+                    ).then((value) {
+                      if (value is Emoji) {
+                        setState(() {
+                          _selectedEmoji = value;
+                        });
+                      }
+                    });
+                  }
+                },
+                child: SizedBox(
+                  height: emojiSize,
+                  width: emojiSize,
+                  child: Stack(
+                    children: [
+                      Container(
+                        height: emojiSize,
+                        width: emojiSize,
+                        decoration: BoxDecoration(
+                          borderRadius: BorderRadius.circular(emojiSize / 2),
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textFieldActiveBG,
+                        ),
+                        child: Center(
+                          child: _selectedEmoji == null
+                              ? SvgPicture.asset(
+                                  Assets.svg.user,
+                                  height: emojiSize / 2,
+                                  width: emojiSize / 2,
+                                )
+                              : Text(
+                                  _selectedEmoji!.char,
+                                  style: isDesktop
+                                      ? STextStyles.desktopH3(context)
+                                      : STextStyles.pageTitleH1(context),
+                                ),
+                        ),
+                      ),
+                      Align(
+                        alignment: Alignment.bottomRight,
+                        child: Container(
+                          height: 14,
+                          width: 14,
+                          decoration: BoxDecoration(
+                              borderRadius: BorderRadius.circular(14),
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorDark),
+                          child: Center(
+                            child: _selectedEmoji == null
+                                ? SvgPicture.asset(
+                                    Assets.svg.plus,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textWhite,
+                                    width: 12,
+                                    height: 12,
+                                  )
+                                : SvgPicture.asset(
+                                    Assets.svg.thickX,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textWhite,
+                                    width: 8,
+                                    height: 8,
+                                  ),
+                          ),
+                        ),
+                      )
+                    ],
+                  ),
+                ),
+              ),
+              if (isDesktop)
+                const SizedBox(
+                  width: 8,
+                ),
+              if (isDesktop)
+                Expanded(
+                  child: ClipRRect(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
+                    child: TextField(
+                      autocorrect: Util.isDesktop ? false : true,
+                      enableSuggestions: Util.isDesktop ? false : true,
+                      controller: nameController,
+                      focusNode: nameFocusNode,
+                      style: STextStyles.field(context),
+                      onChanged: (_) => setState(() {}),
+                      decoration: standardInputDecoration(
+                        "Enter contact name",
+                        nameFocusNode,
+                        context,
+                      ).copyWith(
+                        suffixIcon: nameController.text.isNotEmpty
+                            ? Padding(
+                                padding: const EdgeInsets.only(right: 0),
+                                child: UnconstrainedBox(
+                                  child: Row(
+                                    children: [
+                                      TextFieldIconButton(
+                                        child: const XIcon(),
+                                        onTap: () async {
+                                          setState(() {
+                                            nameController.text = "";
+                                          });
+                                        },
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              )
+                            : null,
+                      ),
+                    ),
+                  ),
+                ),
+            ],
+          ),
+          if (!isDesktop)
+            const SizedBox(
+              height: 8,
             ),
-          );
-        },
+          if (!isDesktop)
+            ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
+                controller: nameController,
+                focusNode: nameFocusNode,
+                style: STextStyles.field(context),
+                onChanged: (_) => setState(() {}),
+                decoration: standardInputDecoration(
+                  "Enter contact name",
+                  nameFocusNode,
+                  context,
+                ).copyWith(
+                  suffixIcon: nameController.text.isNotEmpty
+                      ? Padding(
+                          padding: const EdgeInsets.only(right: 0),
+                          child: UnconstrainedBox(
+                            child: Row(
+                              children: [
+                                TextFieldIconButton(
+                                  child: const XIcon(),
+                                  onTap: () async {
+                                    setState(() {
+                                      nameController.text = "";
+                                    });
+                                  },
+                                ),
+                              ],
+                            ),
+                          ),
+                        )
+                      : null,
+                ),
+              ),
+            ),
+          const Spacer(),
+          const SizedBox(
+            height: 16,
+          ),
+          Row(
+            children: [
+              Expanded(
+                child: SecondaryButton(
+                  label: "Cancel",
+                  buttonHeight: isDesktop ? ButtonHeight.l : null,
+                  onPressed: () async {
+                    if (!isDesktop && FocusScope.of(context).hasFocus) {
+                      FocusScope.of(context).unfocus();
+                      await Future<void>.delayed(
+                          const Duration(milliseconds: 75));
+                    }
+                    if (mounted) {
+                      Navigator.of(context).pop();
+                    }
+                  },
+                ),
+              ),
+              const SizedBox(
+                width: 16,
+              ),
+              Expanded(
+                child: PrimaryButton(
+                  label: "Save",
+                  enabled: nameController.text.isNotEmpty,
+                  buttonHeight: isDesktop ? ButtonHeight.l : null,
+                  onPressed: () async {
+                    if (!isDesktop && FocusScope.of(context).hasFocus) {
+                      FocusScope.of(context).unfocus();
+                      await Future<void>.delayed(
+                        const Duration(milliseconds: 75),
+                      );
+                    }
+                    final editedContact = contact.copyWith(
+                      shouldCopyEmojiWithNull: true,
+                      name: nameController.text,
+                      emojiChar:
+                          _selectedEmoji == null ? null : _selectedEmoji!.char,
+                    );
+                    unawaited(
+                      ref.read(addressBookServiceProvider).editContact(
+                            editedContact,
+                          ),
+                    );
+                    if (mounted) {
+                      Navigator.of(context).pop();
+                    }
+                  },
+                ),
+              ),
+            ],
+          )
+        ],
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_options_menu_popup.dart b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_options_menu_popup.dart
index 88bd6abf0..690d1be98 100644
--- a/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_options_menu_popup.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/subwidgets/desktop_contact_options_menu_popup.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -28,6 +29,147 @@ class _DesktopContactOptionsMenuPopupState
   bool hoveredOnPencil = false;
   bool hoveredOnTrash = false;
 
+  void editContact() {
+    // pop context menu
+    Navigator.of(context).pop();
+
+    showDialog<dynamic>(
+      context: context,
+      useSafeArea: true,
+      barrierDismissible: true,
+      builder: (_) => DesktopDialog(
+        maxWidth: 580,
+        maxHeight: 400,
+        child: Column(
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.only(
+                    left: 32,
+                  ),
+                  child: Text(
+                    "Edit contact",
+                    style: STextStyles.desktopH3(context),
+                  ),
+                ),
+                const DesktopDialogCloseButton(),
+              ],
+            ),
+            Expanded(
+              child: Padding(
+                padding: const EdgeInsets.only(
+                  top: 16,
+                  left: 32,
+                  right: 32,
+                  bottom: 32,
+                ),
+                child: EditContactNameEmojiView(
+                  contactId: widget.contactId,
+                ),
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  void attemptDeleteContact() {
+    final contact =
+        ref.read(addressBookServiceProvider).getContactById(widget.contactId);
+
+    // pop context menu
+    Navigator.of(context).pop();
+
+    showDialog<dynamic>(
+      context: context,
+      useSafeArea: true,
+      barrierDismissible: true,
+      builder: (_) => DesktopDialog(
+        maxWidth: 500,
+        maxHeight: 400,
+        child: Column(
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.only(
+                    left: 32,
+                  ),
+                  child: Text(
+                    "Delete ${contact.name}?",
+                    style: STextStyles.desktopH3(context),
+                  ),
+                ),
+                const DesktopDialogCloseButton(),
+              ],
+            ),
+            Expanded(
+              child: Padding(
+                padding: const EdgeInsets.only(
+                  left: 32,
+                  right: 32,
+                  bottom: 32,
+                ),
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    const Spacer(
+                      flex: 1,
+                    ),
+                    Text(
+                      "Contact will be deleted permanently!",
+                      style: STextStyles.desktopTextSmall(context),
+                    ),
+                    const Spacer(
+                      flex: 2,
+                    ),
+                    Row(
+                      children: [
+                        Expanded(
+                          child: SecondaryButton(
+                            label: "Cancel",
+                            onPressed: Navigator.of(context).pop,
+                            buttonHeight: ButtonHeight.l,
+                          ),
+                        ),
+                        const SizedBox(
+                          width: 16,
+                        ),
+                        Expanded(
+                          child: Consumer(
+                            builder: (context, ref, __) => PrimaryButton(
+                              label: "Delete",
+                              buttonHeight: ButtonHeight.l,
+                              onPressed: () {
+                                ref
+                                    .read(addressBookServiceProvider)
+                                    .removeContact(contact.id);
+                                Navigator.of(context).pop();
+                                showFloatingFlushBar(
+                                  type: FlushBarType.success,
+                                  message: "${contact.name} deleted",
+                                  context: context,
+                                );
+                              },
+                            ),
+                          ),
+                        ),
+                      ],
+                    )
+                  ],
+                ),
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
   @override
   Widget build(BuildContext context) {
     return Stack(
@@ -148,9 +290,7 @@ class _DesktopContactOptionsMenuPopupState
                             1000,
                           ),
                         ),
-                        onPressed: () {
-                          print("should go to edit");
-                        },
+                        onPressed: editContact,
                         child: Padding(
                           padding: const EdgeInsets.symmetric(
                             horizontal: 25,
@@ -213,111 +353,7 @@ class _DesktopContactOptionsMenuPopupState
                             1000,
                           ),
                         ),
-                        onPressed: () {
-                          final contact = ref
-                              .read(addressBookServiceProvider)
-                              .getContactById(widget.contactId);
-
-                          // pop context menu
-                          Navigator.of(context).pop();
-
-                          showDialog<dynamic>(
-                            context: context,
-                            useSafeArea: true,
-                            barrierDismissible: true,
-                            builder: (_) => DesktopDialog(
-                              maxWidth: 500,
-                              maxHeight: 300,
-                              child: Column(
-                                children: [
-                                  Row(
-                                    mainAxisAlignment:
-                                        MainAxisAlignment.spaceBetween,
-                                    children: [
-                                      Padding(
-                                        padding: const EdgeInsets.only(
-                                          left: 32,
-                                        ),
-                                        child: Text(
-                                          "Delete ${contact.name}?",
-                                          style: STextStyles.desktopH3(context),
-                                        ),
-                                      ),
-                                      const DesktopDialogCloseButton(),
-                                    ],
-                                  ),
-                                  Expanded(
-                                    child: Padding(
-                                      padding: const EdgeInsets.only(
-                                        left: 32,
-                                        right: 32,
-                                        bottom: 32,
-                                      ),
-                                      child: Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
-                                        children: [
-                                          const Spacer(
-                                            flex: 1,
-                                          ),
-                                          Text(
-                                            "Contact will be deleted permanently!",
-                                            style: STextStyles.desktopTextSmall(
-                                                context),
-                                          ),
-                                          const Spacer(
-                                            flex: 2,
-                                          ),
-                                          Row(
-                                            children: [
-                                              Expanded(
-                                                child: SecondaryButton(
-                                                  label: "Cancel",
-                                                  onPressed:
-                                                      Navigator.of(context).pop,
-                                                  buttonHeight: ButtonHeight.l,
-                                                ),
-                                              ),
-                                              const SizedBox(
-                                                width: 16,
-                                              ),
-                                              Expanded(
-                                                child: Consumer(
-                                                  builder: (context, ref, __) =>
-                                                      PrimaryButton(
-                                                    label: "Delete",
-                                                    buttonHeight:
-                                                        ButtonHeight.l,
-                                                    onPressed: () {
-                                                      ref
-                                                          .read(
-                                                              addressBookServiceProvider)
-                                                          .removeContact(
-                                                              contact.id);
-                                                      Navigator.of(context)
-                                                          .pop();
-                                                      showFloatingFlushBar(
-                                                        type: FlushBarType
-                                                            .success,
-                                                        message:
-                                                            "${contact.name} deleted",
-                                                        context: context,
-                                                      );
-                                                    },
-                                                  ),
-                                                ),
-                                              ),
-                                            ],
-                                          )
-                                        ],
-                                      ),
-                                    ),
-                                  ),
-                                ],
-                              ),
-                            ),
-                          );
-                        },
+                        onPressed: attemptDeleteContact,
                         child: Padding(
                           padding: const EdgeInsets.symmetric(
                             horizontal: 25,

From 4d17c1db5f732acb00b1726a530125318889f706 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 10:22:34 -0600
Subject: [PATCH 323/426] addressbook filter coins list fix

---
 lib/pages/address_book_views/address_book_view.dart       | 8 ++++----
 .../subviews/address_book_filter_view.dart                | 2 +-
 .../home/address_book_view/desktop_address_book.dart      | 7 ++++---
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index cdc9fb5b7..c87906870 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -51,8 +51,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
     ref.refresh(addressBookFilterProvider);
 
     if (widget.coin == null) {
-      List<Coin> coins =
-          Coin.values.where((e) => !(e == Coin.epicCash)).toList();
+      List<Coin> coins = Coin.values.toList();
       coins.remove(Coin.firoTestNet);
 
       bool showTestNet = ref.read(prefsChangeNotifierProvider).showTestNetCoins;
@@ -60,8 +59,9 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
       if (showTestNet) {
         ref.read(addressBookFilterProvider).addAll(coins, false);
       } else {
-        ref.read(addressBookFilterProvider).addAll(
-            coins.getRange(0, coins.length - kTestNetCoinCount + 1), false);
+        ref
+            .read(addressBookFilterProvider)
+            .addAll(coins.getRange(0, coins.length - kTestNetCoinCount), false);
       }
     } else {
       ref.read(addressBookFilterProvider).add(widget.coin!, false);
diff --git a/lib/pages/address_book_views/subviews/address_book_filter_view.dart b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
index c129251d5..55c3d47ac 100644
--- a/lib/pages/address_book_views/subviews/address_book_filter_view.dart
+++ b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
@@ -38,7 +38,7 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
     } else {
       _coins = coins
           .toList(growable: false)
-          .getRange(0, coins.length - kTestNetCoinCount + 1)
+          .getRange(0, coins.length - kTestNetCoinCount)
           .toList(growable: false);
     }
     super.initState();
diff --git a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
index f028a3424..e5432081c 100644
--- a/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/home/address_book_view/desktop_address_book.dart
@@ -84,7 +84,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
     ref.refresh(addressBookFilterProvider);
 
     // if (widget.coin == null) {
-    List<Coin> coins = Coin.values.where((e) => !(e == Coin.epicCash)).toList();
+    List<Coin> coins = Coin.values.toList();
     coins.remove(Coin.firoTestNet);
 
     bool showTestNet = ref.read(prefsChangeNotifierProvider).showTestNetCoins;
@@ -92,8 +92,9 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
     if (showTestNet) {
       ref.read(addressBookFilterProvider).addAll(coins, false);
     } else {
-      ref.read(addressBookFilterProvider).addAll(
-          coins.getRange(0, coins.length - kTestNetCoinCount + 1), false);
+      ref
+          .read(addressBookFilterProvider)
+          .addAll(coins.getRange(0, coins.length - kTestNetCoinCount), false);
     }
     // } else {
     //   ref.read(addressBookFilterProvider).add(widget.coin!, false);

From 8207474d0973387b9fa7d32d4eb510132b34cc72 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 18 Nov 2022 09:30:21 -0700
Subject: [PATCH 324/426] ocean breeze selector + functionality added

---
 assets/svg/ocean-breeze-theme.svg             |  28 +++++
 lib/main.dart                                 |   2 +-
 .../settings_menu/appearance_settings.dart    | 105 +++++++++++++++++-
 lib/utilities/assets.dart                     |   1 +
 pubspec.yaml                                  |   1 +
 5 files changed, 135 insertions(+), 2 deletions(-)
 create mode 100644 assets/svg/ocean-breeze-theme.svg

diff --git a/assets/svg/ocean-breeze-theme.svg b/assets/svg/ocean-breeze-theme.svg
new file mode 100644
index 000000000..0deb96ec8
--- /dev/null
+++ b/assets/svg/ocean-breeze-theme.svg
@@ -0,0 +1,28 @@
+<svg width="200" height="162" viewBox="0 0 200 162" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_518_22068)">
+<rect width="200" height="162" rx="8" fill="url(#paint0_linear_518_22068)"/>
+<rect x="10" y="10" width="180" height="20" rx="2" fill="#C2DAE2"/>
+<rect x="16" y="16" width="106" height="8" rx="1" fill="#227386"/>
+<rect x="10" y="40" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="46" width="106" height="8" rx="1" fill="#BDD5DB"/>
+<rect x="10" y="62" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="68" width="106" height="8" rx="1" fill="#BDD5DB"/>
+<rect x="10" y="84" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="90" width="106" height="8" rx="1" fill="#BDD5DB"/>
+<rect x="10" y="106" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="112" width="106" height="8" rx="1" fill="#BDD5DB"/>
+<rect x="10" y="128" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="134" width="106" height="8" rx="1" fill="#BDD5DB"/>
+<rect x="10" y="150" width="180" height="20" rx="2" fill="#FEFEFE"/>
+<rect x="16" y="156" width="106" height="8" rx="1" fill="#BDD5DB"/>
+</g>
+<defs>
+<linearGradient id="paint0_linear_518_22068" x1="100" y1="0" x2="100" y2="162" gradientUnits="userSpaceOnUse">
+<stop stop-color="#F3F7FA"/>
+<stop offset="1" stop-color="#E8F2F9"/>
+</linearGradient>
+<clipPath id="clip0_518_22068">
+<rect width="200" height="162" rx="8" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/lib/main.dart b/lib/main.dart
index 2d1bab160..66b3bb974 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -77,7 +77,7 @@ void main() async {
 
   if (Util.isDesktop) {
     setWindowTitle('Stack Wallet');
-    setWindowMinSize(const Size(1200, 1100));
+    setWindowMinSize(const Size(1220, 1100));
     setWindowMaxSize(Size.infinite);
   }
 
diff --git a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
index 7a9ed557f..bfd5f3b61 100644
--- a/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/appearance_settings.dart
@@ -10,6 +10,7 @@ import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/color_theme.dart';
 import 'package:stackwallet/utilities/theme/dark_colors.dart';
 import 'package:stackwallet/utilities/theme/light_colors.dart';
+import 'package:stackwallet/utilities/theme/ocean_breeze_colors.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -291,7 +292,109 @@ class _ThemeToggle extends ConsumerState<ThemeToggle> {
           ),
         ),
         const SizedBox(
-          width: 20,
+          width: 10,
+        ),
+        MaterialButton(
+          splashColor: Colors.transparent,
+          hoverColor: Colors.transparent,
+          padding: const EdgeInsets.all(0),
+          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+          ),
+          onPressed: () {
+            DB.instance.put<dynamic>(
+              boxName: DB.boxNameTheme,
+              key: "colorScheme",
+              value: ThemeType.oceanBreeze.name,
+            );
+            ref.read(colorThemeProvider.state).state =
+                StackColors.fromStackColorTheme(
+              OceanBreezeColors(),
+            );
+
+            setState(() {
+              _selectedTheme = "oceanBreeze";
+            });
+          },
+          child: SizedBox(
+            width: 200,
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                Container(
+                  decoration: BoxDecoration(
+                    border: Border.all(
+                      width: 2.5,
+                      color: _selectedTheme == "oceanBreeze"
+                          ? Theme.of(context)
+                              .extension<StackColors>()!
+                              .infoItemIcons
+                          : Theme.of(context).extension<StackColors>()!.popupBG,
+                    ),
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
+                  ),
+                  child: SvgPicture.asset(
+                    Assets.svg.themeOcean,
+                  ),
+                ),
+                const SizedBox(
+                  height: 12,
+                ),
+                Row(
+                  children: [
+                    SizedBox(
+                      width: 20,
+                      height: 20,
+                      child: Radio(
+                        activeColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .radioButtonIconEnabled,
+                        value: "oceanBreeze",
+                        groupValue: _selectedTheme,
+                        onChanged: (newValue) {
+                          if (newValue is String && newValue == "oceanBreeze") {
+                            DB.instance.put<dynamic>(
+                              boxName: DB.boxNameTheme,
+                              key: "colorScheme",
+                              value: ThemeType.oceanBreeze.name,
+                            );
+                            ref.read(colorThemeProvider.state).state =
+                                StackColors.fromStackColorTheme(
+                              OceanBreezeColors(),
+                            );
+
+                            setState(() {
+                              _selectedTheme = "oceanBreeze";
+                            });
+                          }
+                        },
+                      ),
+                    ),
+                    const SizedBox(
+                      width: 14,
+                    ),
+                    Text(
+                      "Ocean Breeze",
+                      style:
+                          STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark,
+                      ),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          width: 10,
         ),
         MaterialButton(
           splashColor: Colors.transparent,
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 38d720969..d7d2ebc6f 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -59,6 +59,7 @@ class _SVG {
   String txExchangeFailed(BuildContext context) =>
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
 
+  String get themeOcean => "assets/svg/ocean-breeze-theme.svg";
   String get circleSliders => "assets/svg/configuration.svg";
   String get circlePlus => "assets/svg/plus-circle.svg";
   String get framedGear => "assets/svg/framed-gear.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index bba5f6ed2..94670af1a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -316,6 +316,7 @@ flutter:
     - assets/svg/arrow-down.svg
     - assets/svg/plus-circle.svg
     - assets/svg/configuration.svg
+    - assets/svg/ocean-breeze-theme.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Litecoin.svg

From 9508afbd5b84823a264e3c091cab9768292e9e01 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 12:26:27 -0600
Subject: [PATCH 325/426] add ocean breeze specific assets

---
 assets/svg/{dark => }/dark-theme.svg          |  0
 assets/svg/{light => }/light-mode.svg         |  0
 assets/svg/oceanBreeze/bell-new.svg           |  5 ++
 assets/svg/oceanBreeze/buy-coins-icon.svg     | 18 +++++
 assets/svg/oceanBreeze/exchange-2.svg         |  4 +
 assets/svg/oceanBreeze/stack-icon1.svg        |  5 ++
 .../oceanBreeze/tx-exchange-icon-failed.svg   |  7 ++
 .../oceanBreeze/tx-exchange-icon-pending.svg  |  6 ++
 assets/svg/oceanBreeze/tx-exchange-icon.svg   |  4 +
 .../oceanBreeze/tx-icon-receive-failed.svg    |  7 ++
 .../oceanBreeze/tx-icon-receive-pending.svg   |  5 ++
 assets/svg/oceanBreeze/tx-icon-receive.svg    |  4 +
 .../svg/oceanBreeze/tx-icon-send-failed.svg   |  7 ++
 .../svg/oceanBreeze/tx-icon-send-pending.svg  |  6 ++
 assets/svg/oceanBreeze/tx-icon-send.svg       |  4 +
 lib/utilities/assets.dart                     |  5 +-
 pubspec.yaml                                  | 77 ++++++++++++-------
 17 files changed, 135 insertions(+), 29 deletions(-)
 rename assets/svg/{dark => }/dark-theme.svg (100%)
 rename assets/svg/{light => }/light-mode.svg (100%)
 create mode 100644 assets/svg/oceanBreeze/bell-new.svg
 create mode 100644 assets/svg/oceanBreeze/buy-coins-icon.svg
 create mode 100644 assets/svg/oceanBreeze/exchange-2.svg
 create mode 100644 assets/svg/oceanBreeze/stack-icon1.svg
 create mode 100644 assets/svg/oceanBreeze/tx-exchange-icon-failed.svg
 create mode 100644 assets/svg/oceanBreeze/tx-exchange-icon-pending.svg
 create mode 100644 assets/svg/oceanBreeze/tx-exchange-icon.svg
 create mode 100644 assets/svg/oceanBreeze/tx-icon-receive-failed.svg
 create mode 100644 assets/svg/oceanBreeze/tx-icon-receive-pending.svg
 create mode 100644 assets/svg/oceanBreeze/tx-icon-receive.svg
 create mode 100644 assets/svg/oceanBreeze/tx-icon-send-failed.svg
 create mode 100644 assets/svg/oceanBreeze/tx-icon-send-pending.svg
 create mode 100644 assets/svg/oceanBreeze/tx-icon-send.svg

diff --git a/assets/svg/dark/dark-theme.svg b/assets/svg/dark-theme.svg
similarity index 100%
rename from assets/svg/dark/dark-theme.svg
rename to assets/svg/dark-theme.svg
diff --git a/assets/svg/light/light-mode.svg b/assets/svg/light-mode.svg
similarity index 100%
rename from assets/svg/light/light-mode.svg
rename to assets/svg/light-mode.svg
diff --git a/assets/svg/oceanBreeze/bell-new.svg b/assets/svg/oceanBreeze/bell-new.svg
new file mode 100644
index 000000000..8cef32715
--- /dev/null
+++ b/assets/svg/oceanBreeze/bell-new.svg
@@ -0,0 +1,5 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12.5 17.5C12.5 17.9193 12.2383 18.3672 11.7695 18.6797C11.3008 18.9922 10.6289 19.1667 10 19.1667C9.33594 19.1667 8.69922 18.9922 8.23047 18.6797C7.76172 18.3672 7.5 17.9193 7.5 17.5H12.5Z" fill="#227386"/>
+<path d="M11.1903 1.98716V2.67947C13.9059 3.2142 15.9519 5.54245 15.9519 8.33331V9.0112C15.9519 10.7095 16.5955 12.3429 17.7561 13.6122L18.0314 13.9114C18.3439 14.254 18.422 14.7372 18.2286 15.1518C18.0351 15.5665 17.611 15.8333 17.1423 15.8333H2.85739C2.38867 15.8333 1.96351 15.5665 1.77148 15.1518C1.57945 14.7372 1.65626 14.254 1.96771 13.9114L2.24359 13.6122C3.40573 12.3429 4.0478 10.7095 4.0478 9.0112V8.33331C4.0478 5.54245 6.06034 3.2142 8.80945 2.67947V1.98716C8.80945 1.35002 9.34141 0.833313 9.99986 0.833313C10.6583 0.833313 11.1903 1.35002 11.1903 1.98716Z" fill="#227386"/>
+<ellipse cx="17.0833" cy="2.91665" rx="2.08333" ry="2.08333" fill="#D34E50"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/buy-coins-icon.svg b/assets/svg/oceanBreeze/buy-coins-icon.svg
new file mode 100644
index 000000000..d9613bccb
--- /dev/null
+++ b/assets/svg/oceanBreeze/buy-coins-icon.svg
@@ -0,0 +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_519_18707)">
+<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="#227386"/>
+<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="#227386"/>
+<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="#227386"/>
+</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="#227386"/>
+<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="#227386"/>
+<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="#227386"/>
+<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="#227386"/>
+</g>
+<defs>
+<clipPath id="clip0_519_18707">
+<rect width="24" height="24" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/assets/svg/oceanBreeze/exchange-2.svg b/assets/svg/oceanBreeze/exchange-2.svg
new file mode 100644
index 000000000..7baeaf87f
--- /dev/null
+++ b/assets/svg/oceanBreeze/exchange-2.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M19.5 6.5L20.4343 7.33045C20.8552 6.85685 20.8552 6.14315 20.4343 5.66955L19.5 6.5ZM16.4343 1.16955C15.9756 0.653567 15.1855 0.607091 14.6695 1.06574C14.1536 1.52439 14.1071 2.31448 14.5657 2.83045L16.4343 1.16955ZM14.5657 10.1695C14.1071 10.6855 14.1536 11.4756 14.6695 11.9343C15.1855 12.3929 15.9756 12.3464 16.4343 11.8305L14.5657 10.1695ZM0.75 10.5C0.75 11.1904 1.30964 11.75 2 11.75C2.69036 11.75 3.25 11.1904 3.25 10.5H0.75ZM6 7.75H19.5V5.25H6V7.75ZM14.5657 2.83045L18.5657 7.33045L20.4343 5.66955L16.4343 1.16955L14.5657 2.83045ZM16.4343 11.8305L20.4343 7.33045L18.5657 5.66955L14.5657 10.1695L16.4343 11.8305ZM3.25 10.5C3.25 8.98122 4.48122 7.75 6 7.75V5.25C3.10051 5.25 0.75 7.60051 0.75 10.5H3.25Z" fill="#227386"/>
+<path opacity="0.4" d="M4.5 18L3.56574 17.1695C3.14475 17.6432 3.14475 18.3568 3.56574 18.8305L4.5 18ZM7.56574 23.3305C8.02439 23.8464 8.81448 23.8929 9.33045 23.4343C9.84643 22.9756 9.89291 22.1855 9.43426 21.6695L7.56574 23.3305ZM9.43426 14.3305C9.89291 13.8145 9.84643 13.0244 9.33046 12.5657C8.81448 12.1071 8.02439 12.1536 7.56574 12.6695L9.43426 14.3305ZM23.25 14C23.25 13.3096 22.6904 12.75 22 12.75C21.3096 12.75 20.75 13.3096 20.75 14L23.25 14ZM18 16.75L4.5 16.75L4.5 19.25L18 19.25L18 16.75ZM9.43426 21.6695L5.43426 17.1695L3.56574 18.8305L7.56574 23.3305L9.43426 21.6695ZM7.56574 12.6695L3.56574 17.1695L5.43426 18.8305L9.43426 14.3305L7.56574 12.6695ZM20.75 14C20.75 15.5188 19.5188 16.75 18 16.75L18 19.25C20.8995 19.25 23.25 16.8995 23.25 14L20.75 14Z" fill="#227386"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/stack-icon1.svg b/assets/svg/oceanBreeze/stack-icon1.svg
new file mode 100644
index 000000000..f316012d7
--- /dev/null
+++ b/assets/svg/oceanBreeze/stack-icon1.svg
@@ -0,0 +1,5 @@
+<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M41.3715 9.57675C37.2965 7.22564 32.2041 10.1695 32.2041 14.8717C32.2041 19.5739 34.4762 23.6489 38.2004 26.163L53.9717 35.3057L54.0112 35.2908L69.9948 26.0543L41.3715 9.57675Z" fill="#B3B3B3"/>
+<path d="M38.2014 26.163C34.4771 23.6489 32.205 19.4159 32.205 14.8717C32.205 12.6342 33.3757 10.7671 35.0402 9.7101C34.9612 9.75455 35.1192 9.66564 35.0402 9.7101L10.0917 23.7279L6.08593 26.1481L3.35449 27.7188C5.07337 26.8446 7.22692 26.7754 9.14831 27.8917L16.0189 31.8037L22.0399 35.2859L38.0236 44.5076L53.9677 35.2958L38.1964 26.1531L38.2014 26.163Z" fill="#666666"/>
+<path d="M70 44.5187L38.0278 62.9917L31.992 59.5095L31.9673 59.4848L6.06054 44.5187C4.28733 43.3629 2.84505 41.7872 1.82755 40.014C0.642111 37.9691 0 35.618 0 33.1829C0 30.9899 1.10147 29.1771 2.70181 28.1004C2.91914 27.967 3.13153 27.8435 3.35874 27.725C5.07762 26.8507 7.23116 26.7816 9.15256 27.8979L15.9836 31.8394L22.0047 35.3068L22.0442 35.292L38.0278 44.5137L53.9719 35.3019L70 44.5137V44.5187Z" fill="#232323"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/tx-exchange-icon-failed.svg b/assets/svg/oceanBreeze/tx-exchange-icon-failed.svg
new file mode 100644
index 000000000..a54836bba
--- /dev/null
+++ b/assets/svg/oceanBreeze/tx-exchange-icon-failed.svg
@@ -0,0 +1,7 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path opacity="0.4" d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#0056D2"/>
+<path d="M5.30071 12.4C4.91018 12.7905 4.91018 13.4236 5.30071 13.8142C5.69123 14.2047 6.32439 14.2047 6.71492 13.8142L5.30071 12.4ZM13.0789 6.03599L14.0787 6.05567C14.0839 5.78863 13.9821 5.53058 13.796 5.33904C13.6098 5.1475 13.3548 5.03839 13.0877 5.03603L13.0789 6.03599ZM9.00968 5.00004C8.45741 4.99516 8.00576 5.43891 8.00089 5.99117C7.99601 6.54344 8.43976 6.99509 8.99202 6.99996L9.00968 5.00004ZM12.001 9.98032C11.9902 10.5325 12.429 10.9889 12.9812 10.9998C13.5333 11.0107 13.9898 10.5719 14.0007 10.0197L12.001 9.98032ZM18.6429 11.6C19.0334 11.2095 19.0334 10.5764 18.6429 10.1858C18.2524 9.79531 17.6192 9.79531 17.2287 10.1858L18.6429 11.6ZM10.8647 17.964L9.8653 17.9297C9.85604 18.1992 9.95602 18.461 10.1426 18.6557C10.3291 18.8505 10.5864 18.9616 10.856 18.964L10.8647 17.964ZM14.9922 19C15.5444 19.0048 15.996 18.561 16.0008 18.0087C16.0056 17.4564 15.5618 17.0048 15.0096 17L14.9922 19ZM12.0003 14.0343C12.0192 13.4824 11.5871 13.0195 11.0352 13.0006C10.4832 12.9816 10.0204 13.4137 10.0014 13.9657L12.0003 14.0343ZM6.71492 13.8142L13.786 6.7431L12.3718 5.32889L5.30071 12.4L6.71492 13.8142ZM8.99202 6.99996L13.0701 7.03595L13.0877 5.03603L9.00968 5.00004L8.99202 6.99996ZM12.0791 6.01631L12.001 9.98032L14.0007 10.0197L14.0787 6.05567L12.0791 6.01631ZM17.2287 10.1858L10.1576 17.2569L11.5718 18.6711L18.6429 11.6L17.2287 10.1858ZM15.0096 17L10.8734 16.964L10.856 18.964L14.9922 19L15.0096 17ZM11.8641 17.9983L12.0003 14.0343L10.0014 13.9657L9.8653 17.9297L11.8641 17.9983Z" fill="#0056D2"/>
+<circle cx="20.5" cy="20.5" r="3.5" fill="#C00205"/>
+<path d="M19.4395 19.4395L20.5001 20.5001L21.5608 21.5608" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.5 21.5605L20.5607 20.4999L21.6213 19.4392" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/tx-exchange-icon-pending.svg b/assets/svg/oceanBreeze/tx-exchange-icon-pending.svg
new file mode 100644
index 000000000..5f9aa4256
--- /dev/null
+++ b/assets/svg/oceanBreeze/tx-exchange-icon-pending.svg
@@ -0,0 +1,6 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path opacity="0.4" d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#0056D2"/>
+<circle cx="20.5" cy="20.5" r="3.5" fill="#F4C517"/>
+<path d="M20.5 19V20.5H21.5" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M5.30071 12.4C4.91018 12.7905 4.91018 13.4236 5.30071 13.8142C5.69123 14.2047 6.32439 14.2047 6.71492 13.8142L5.30071 12.4ZM13.0789 6.03599L14.0787 6.05567C14.0839 5.78863 13.9821 5.53058 13.796 5.33904C13.6098 5.1475 13.3548 5.03839 13.0877 5.03603L13.0789 6.03599ZM9.00968 5.00004C8.45741 4.99516 8.00576 5.43891 8.00089 5.99117C7.99601 6.54344 8.43976 6.99509 8.99202 6.99996L9.00968 5.00004ZM12.001 9.98032C11.9902 10.5325 12.429 10.9889 12.9812 10.9998C13.5333 11.0107 13.9898 10.5719 14.0007 10.0197L12.001 9.98032ZM18.6429 11.6C19.0334 11.2095 19.0334 10.5764 18.6429 10.1858C18.2524 9.79531 17.6192 9.79531 17.2287 10.1858L18.6429 11.6ZM10.8647 17.964L9.8653 17.9297C9.85605 18.1992 9.95602 18.461 10.1426 18.6557C10.3291 18.8505 10.5864 18.9616 10.856 18.964L10.8647 17.964ZM14.9922 19C15.5444 19.0048 15.996 18.561 16.0008 18.0087C16.0056 17.4564 15.5618 17.0048 15.0096 17L14.9922 19ZM12.0003 14.0343C12.0192 13.4824 11.5871 13.0195 11.0352 13.0006C10.4832 12.9816 10.0204 13.4137 10.0014 13.9657L12.0003 14.0343ZM6.71492 13.8142L13.786 6.7431L12.3718 5.32889L5.30071 12.4L6.71492 13.8142ZM8.99202 6.99996L13.0701 7.03595L13.0877 5.03603L9.00968 5.00004L8.99202 6.99996ZM12.0791 6.01631L12.001 9.98032L14.0007 10.0197L14.0787 6.05567L12.0791 6.01631ZM17.2287 10.1858L10.1576 17.2569L11.5718 18.6711L18.6429 11.6L17.2287 10.1858ZM15.0096 17L10.8734 16.964L10.856 18.964L14.9922 19L15.0096 17ZM11.8641 17.9983L12.0003 14.0343L10.0014 13.9657L9.8653 17.9297L11.8641 17.9983Z" fill="#0056D2"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/tx-exchange-icon.svg b/assets/svg/oceanBreeze/tx-exchange-icon.svg
new file mode 100644
index 000000000..fcd3ef9dc
--- /dev/null
+++ b/assets/svg/oceanBreeze/tx-exchange-icon.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle opacity="0.4" cx="12" cy="12" r="12" fill="#0056D2"/>
+<path d="M5.30071 12.4C4.91018 12.7905 4.91018 13.4236 5.30071 13.8142C5.69123 14.2047 6.32439 14.2047 6.71492 13.8142L5.30071 12.4ZM13.0789 6.03599L14.0787 6.05567C14.0839 5.78863 13.9821 5.53058 13.796 5.33904C13.6098 5.1475 13.3548 5.03839 13.0877 5.03603L13.0789 6.03599ZM9.00968 5.00004C8.45741 4.99516 8.00576 5.43891 8.00089 5.99117C7.99601 6.54344 8.43976 6.99509 8.99202 6.99996L9.00968 5.00004ZM12.001 9.98032C11.9902 10.5325 12.429 10.9889 12.9812 10.9998C13.5333 11.0107 13.9898 10.5719 14.0007 10.0197L12.001 9.98032ZM18.6429 11.6C19.0334 11.2095 19.0334 10.5764 18.6429 10.1858C18.2524 9.79531 17.6192 9.79531 17.2287 10.1858L18.6429 11.6ZM10.8647 17.964L9.8653 17.9297C9.85604 18.1992 9.95602 18.461 10.1426 18.6557C10.3291 18.8505 10.5864 18.9616 10.856 18.964L10.8647 17.964ZM14.9922 19C15.5444 19.0048 15.996 18.561 16.0008 18.0087C16.0056 17.4564 15.5618 17.0048 15.0096 17L14.9922 19ZM12.0003 14.0343C12.0192 13.4824 11.5871 13.0195 11.0352 13.0006C10.4832 12.9816 10.0204 13.4137 10.0014 13.9657L12.0003 14.0343ZM6.71492 13.8142L13.786 6.7431L12.3718 5.32889L5.30071 12.4L6.71492 13.8142ZM8.99202 6.99996L13.0701 7.03595L13.0877 5.03603L9.00968 5.00004L8.99202 6.99996ZM12.0791 6.01631L12.001 9.98032L14.0007 10.0197L14.0787 6.05567L12.0791 6.01631ZM17.2287 10.1858L10.1576 17.2569L11.5718 18.6711L18.6429 11.6L17.2287 10.1858ZM15.0096 17L10.8734 16.964L10.856 18.964L14.9922 19L15.0096 17ZM11.8641 17.9983L12.0003 14.0343L10.0014 13.9657L9.8653 17.9297L11.8641 17.9983Z" fill="#0056D2"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/tx-icon-receive-failed.svg b/assets/svg/oceanBreeze/tx-icon-receive-failed.svg
new file mode 100644
index 000000000..189bd15c9
--- /dev/null
+++ b/assets/svg/oceanBreeze/tx-icon-receive-failed.svg
@@ -0,0 +1,7 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#00A578"/>
+<circle cx="20.5" cy="20.5" r="3.5" fill="#C00205"/>
+<path d="M16 8L8 16M8 16H14M8 16V10" stroke="#00A578" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.4395 19.4395L20.5001 20.5001L21.5608 21.5608" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.5 21.5605L20.5607 20.4999L21.6213 19.4392" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/tx-icon-receive-pending.svg b/assets/svg/oceanBreeze/tx-icon-receive-pending.svg
new file mode 100644
index 000000000..64ea8da3d
--- /dev/null
+++ b/assets/svg/oceanBreeze/tx-icon-receive-pending.svg
@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path opacity="0.4" d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#00A578"/>
+<path d="M16 8L8 16M8 16H14M8 16V10" stroke="#00A578" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M20.5 24C22.433 24 24 22.433 24 20.5C24 18.567 22.433 17 20.5 17C18.567 17 17 18.567 17 20.5C17 22.433 18.567 24 20.5 24ZM21 19C21 18.7239 20.7761 18.5 20.5 18.5C20.2239 18.5 20 18.7239 20 19V20.5C20 20.7761 20.2239 21 20.5 21H21.5C21.7761 21 22 20.7761 22 20.5C22 20.2239 21.7761 20 21.5 20H21V19Z" fill="#F4C517"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/tx-icon-receive.svg b/assets/svg/oceanBreeze/tx-icon-receive.svg
new file mode 100644
index 000000000..1076d8d57
--- /dev/null
+++ b/assets/svg/oceanBreeze/tx-icon-receive.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle opacity="0.4" cx="12" cy="12" r="12" fill="#00A578"/>
+<path d="M16 8L8 16M8 16H14M8 16V10" stroke="#00A578" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/tx-icon-send-failed.svg b/assets/svg/oceanBreeze/tx-icon-send-failed.svg
new file mode 100644
index 000000000..9751b61e8
--- /dev/null
+++ b/assets/svg/oceanBreeze/tx-icon-send-failed.svg
@@ -0,0 +1,7 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path opacity="0.4" d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#FE805C"/>
+<path d="M8 16L16 8M16 8L10 8M16 8L16 14" stroke="#FE805C" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
+<circle cx="20.5" cy="20.5" r="3.5" fill="#C00205"/>
+<path d="M19.4395 19.4395L20.5001 20.5001L21.5608 21.5608" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.5 21.5605L20.5607 20.4999L21.6213 19.4392" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/tx-icon-send-pending.svg b/assets/svg/oceanBreeze/tx-icon-send-pending.svg
new file mode 100644
index 000000000..e4ec777e3
--- /dev/null
+++ b/assets/svg/oceanBreeze/tx-icon-send-pending.svg
@@ -0,0 +1,6 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path opacity="0.4" d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#FE805C"/>
+<path d="M8 16L16 8M16 8L10 8M16 8L16 14" stroke="#FE805C" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
+<circle cx="20.5" cy="20.5" r="3.5" fill="#F4C517"/>
+<path d="M20.5 19V20.5H21.5" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/assets/svg/oceanBreeze/tx-icon-send.svg b/assets/svg/oceanBreeze/tx-icon-send.svg
new file mode 100644
index 000000000..ee32aa6b4
--- /dev/null
+++ b/assets/svg/oceanBreeze/tx-icon-send.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle opacity="0.4" cx="12" cy="12" r="12" fill="#FE805C"/>
+<path d="M8 16L16 8M16 8L10 8M16 8L16 14" stroke="#FE805C" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index d7d2ebc6f..c423ec491 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -60,12 +60,13 @@ class _SVG {
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
 
   String get themeOcean => "assets/svg/ocean-breeze-theme.svg";
+  String get themeLight => "assets/svg/light-mode.svg";
+  String get themeDark => "assets/svg/dark-theme.svg";
+
   String get circleSliders => "assets/svg/configuration.svg";
   String get circlePlus => "assets/svg/plus-circle.svg";
   String get framedGear => "assets/svg/framed-gear.svg";
   String get framedAddressBook => "assets/svg/framed-address-book.svg";
-  String get themeLight => "assets/svg/light/light-mode.svg";
-  String get themeDark => "assets/svg/dark/dark-theme.svg";
   String get circleNode => "assets/svg/node-circle.svg";
   String get circleSun => "assets/svg/sun-circle.svg";
   String get circleArrowRotate => "assets/svg/rotate-circle.svg";
diff --git a/pubspec.yaml b/pubspec.yaml
index 94670af1a..6a721c5c1 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -205,9 +205,6 @@ flutter:
     - assets/svg/plus.svg
     - assets/svg/gear.svg
     - assets/svg/bell.svg
-    - assets/svg/light/bell-new.svg
-    - assets/svg/dark/bell-new.svg
-    - assets/svg/stack-icon1.svg
     - assets/svg/arrow-left-fa.svg
     - assets/svg/copy-fa.svg
     - assets/svg/star.svg
@@ -220,10 +217,7 @@ flutter:
     - assets/svg/bars.svg
     - assets/svg/filter.svg
     - assets/svg/pending.svg
-    - assets/svg/dark/exchange-2.svg
-    - assets/svg/light/exchange-2.svg
     - assets/svg/signal-stream.svg
-    - assets/svg/buy-coins-icon.svg
     - assets/svg/Ellipse-43.svg
     - assets/svg/Ellipse-42.svg
     - assets/svg/arrow-rotate.svg
@@ -265,25 +259,7 @@ flutter:
     - assets/svg/ellipsis-vertical1.svg
     - assets/svg/dice-alt.svg
     - assets/svg/circle-arrow-up-right2.svg
-    - assets/svg/dark/tx-exchange-icon.svg
-    - assets/svg/light/tx-exchange-icon.svg
-    - assets/svg/dark/tx-exchange-icon-pending.svg
-    - assets/svg/light/tx-exchange-icon-pending.svg
-    - assets/svg/dark/tx-exchange-icon-failed.svg
-    - assets/svg/light/tx-exchange-icon-failed.svg
     - assets/svg/loader.svg
-    - assets/svg/dark/tx-icon-send.svg
-    - assets/svg/light/tx-icon-send.svg
-    - assets/svg/dark/tx-icon-send-pending.svg
-    - assets/svg/light/tx-icon-send-pending.svg
-    - assets/svg/dark/tx-icon-send-failed.svg
-    - assets/svg/light/tx-icon-send-failed.svg
-    - assets/svg/dark/tx-icon-receive.svg
-    - assets/svg/light/tx-icon-receive.svg
-    - assets/svg/dark/tx-icon-receive-pending.svg
-    - assets/svg/light/tx-icon-receive-pending.svg
-    - assets/svg/dark/tx-icon-receive-failed.svg
-    - assets/svg/light/tx-icon-receive-failed.svg
     - assets/svg/add-backup.svg
     - assets/svg/auto-backup.svg
     - assets/svg/restore-backup.svg
@@ -305,8 +281,6 @@ flutter:
     - assets/svg/rotate-circle.svg
     - assets/svg/sun-circle.svg
     - assets/svg/node-circle.svg
-    - assets/svg/dark/dark-theme.svg
-    - assets/svg/light/light-mode.svg
     - assets/svg/address-book-desktop.svg
     - assets/svg/about-desktop.svg
     - assets/svg/exchange-desktop.svg
@@ -316,7 +290,6 @@ flutter:
     - assets/svg/arrow-down.svg
     - assets/svg/plus-circle.svg
     - assets/svg/configuration.svg
-    - assets/svg/ocean-breeze-theme.svg
     # coin icons
     - assets/svg/coin_icons/Bitcoin.svg
     - assets/svg/coin_icons/Litecoin.svg
@@ -348,6 +321,56 @@ flutter:
     - assets/svg/exchange_icons/change_now_logo_1.svg
     - assets/svg/exchange_icons/simpleswap-icon.svg
 
+    # theme selectors
+    - assets/svg/dark-theme.svg
+    - assets/svg/light-mode.svg
+    - assets/svg/ocean-breeze-theme.svg
+
+    # light theme specific
+    - assets/svg/light/tx-exchange-icon.svg
+    - assets/svg/light/tx-exchange-icon-pending.svg
+    - assets/svg/light/tx-exchange-icon-failed.svg
+    - assets/svg/light/tx-icon-send.svg
+    - assets/svg/light/tx-icon-send-pending.svg
+    - assets/svg/light/tx-icon-send-failed.svg
+    - assets/svg/light/tx-icon-receive.svg
+    - assets/svg/light/tx-icon-receive-pending.svg
+    - assets/svg/light/tx-icon-receive-failed.svg
+    - assets/svg/light/exchange-2.svg
+    - assets/svg/light/bell-new.svg
+    - assets/svg/light/stack-icon1.svg
+    - assets/svg/light/buy-coins-icon.svg
+
+    # dark theme specific
+    - assets/svg/dark/tx-exchange-icon.svg
+    - assets/svg/dark/tx-exchange-icon-pending.svg
+    - assets/svg/dark/tx-exchange-icon-failed.svg
+    - assets/svg/dark/tx-icon-send.svg
+    - assets/svg/dark/tx-icon-send-pending.svg
+    - assets/svg/dark/tx-icon-send-failed.svg
+    - assets/svg/dark/tx-icon-receive.svg
+    - assets/svg/dark/tx-icon-receive-pending.svg
+    - assets/svg/dark/tx-icon-receive-failed.svg
+    - assets/svg/dark/exchange-2.svg
+    - assets/svg/dark/bell-new.svg
+    - assets/svg/dark/stack-icon1.svg
+    - assets/svg/dark/buy-coins-icon.svg
+
+    # light theme specific
+    - assets/svg/oceanBreeze/tx-exchange-icon.svg
+    - assets/svg/oceanBreeze/tx-exchange-icon-pending.svg
+    - assets/svg/oceanBreeze/tx-exchange-icon-failed.svg
+    - assets/svg/oceanBreeze/tx-icon-send.svg
+    - assets/svg/oceanBreeze/tx-icon-send-pending.svg
+    - assets/svg/oceanBreeze/tx-icon-send-failed.svg
+    - assets/svg/oceanBreeze/tx-icon-receive.svg
+    - assets/svg/oceanBreeze/tx-icon-receive-pending.svg
+    - assets/svg/oceanBreeze/tx-icon-receive-failed.svg
+    - assets/svg/oceanBreeze/exchange-2.svg
+    - assets/svg/oceanBreeze/bell-new.svg
+    - assets/svg/oceanBreeze/stack-icon1.svg
+    - assets/svg/oceanBreeze/buy-coins-icon.svg
+
   # An image asset can refer to one or more resolution-specific "variants", see
   # https://flutter.dev/assets-and-images/#resolution-aware.
   # For details regarding adding assets from package dependencies, see

From 792b91b7c4d27c7212b251150ad4fafef39b96a8 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 18 Nov 2022 11:26:27 -0700
Subject: [PATCH 326/426] syncing pref options show on button press + shows
 card w current syncing prefs

---
 .../syncing_preferences_settings.dart         | 116 ++++++++++++++----
 1 file changed, 91 insertions(+), 25 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
index 815e506db..720d77b8b 100644
--- a/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/syncing_preferences_settings.dart
@@ -3,9 +3,13 @@ import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class SyncingPreferencesSettings extends ConsumerStatefulWidget {
@@ -20,6 +24,19 @@ class SyncingPreferencesSettings extends ConsumerStatefulWidget {
 
 class _SyncingPreferencesSettings
     extends ConsumerState<SyncingPreferencesSettings> {
+  String _currentTypeDescription(SyncingType type) {
+    switch (type) {
+      case SyncingType.currentWalletOnly:
+        return "Sync only currently open wallet";
+      case SyncingType.selectedWalletsAtStartup:
+        return "Sync only selected wallets at startup";
+      case SyncingType.allWalletsOnStartup:
+        return "Sync all wallets at startup";
+    }
+  }
+
+  late bool changePrefs = false;
+
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
@@ -34,13 +51,40 @@ class _SyncingPreferencesSettings
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
-                Padding(
-                  padding: const EdgeInsets.all(8.0),
-                  child: SvgPicture.asset(
-                    Assets.svg.circleArrowRotate,
-                    width: 48,
-                    height: 48,
-                  ),
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.all(8.0),
+                      child: SvgPicture.asset(
+                        Assets.svg.circleArrowRotate,
+                        width: 48,
+                        height: 48,
+                      ),
+                    ),
+                    Padding(
+                      padding: const EdgeInsets.all(8.0),
+                      child: RoundedContainer(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .buttonBackSecondaryDisabled,
+                        child: Padding(
+                          padding: const EdgeInsets.all(8.0),
+                          child: Text(
+                            _currentTypeDescription(ref.watch(
+                                prefsChangeNotifierProvider
+                                    .select((value) => value.syncType))),
+                            style: STextStyles.desktopTextExtraSmall(context)
+                                .copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark2),
+                            textAlign: TextAlign.left,
+                          ),
+                        ),
+                      ),
+                    ),
+                  ],
                 ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.stretch,
@@ -67,28 +111,50 @@ class _SyncingPreferencesSettings
                     ),
                   ],
                 ),
-
-                ///TODO: ONLY SHOW SYNC OPTIONS ON BUTTON PRESS
-                Column(
-                  children: const [
-                    SyncingOptionsView(),
-                  ],
-                ),
                 Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
                   children: [
                     Padding(
-                      padding: const EdgeInsets.all(
-                        10,
-                      ),
-                      child: PrimaryButton(
-                        width: 210,
-                        buttonHeight: ButtonHeight.m,
-                        enabled: true,
-                        label: "Change preferences",
-                        onPressed: () {},
-                      ),
-                    ),
+                        padding: const EdgeInsets.all(
+                          10,
+                        ),
+                        child: changePrefs
+                            ? SizedBox(
+                                width: 512,
+                                child: Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    const SyncingOptionsView(),
+                                    PrimaryButton(
+                                      width: 200,
+                                      buttonHeight: ButtonHeight.m,
+                                      enabled: true,
+                                      label: "Save",
+                                      onPressed: () {
+                                        setState(() {
+                                          changePrefs = false;
+                                        });
+                                      },
+                                    ),
+                                  ],
+                                ),
+                              )
+                            : Column(
+                                children: [
+                                  const SizedBox(height: 10),
+                                  PrimaryButton(
+                                    width: 200,
+                                    buttonHeight: ButtonHeight.m,
+                                    enabled: true,
+                                    label: "Change preferences",
+                                    onPressed: () {
+                                      setState(() {
+                                        changePrefs = true;
+                                      });
+                                    },
+                                  ),
+                                ],
+                              )),
                   ],
                 ),
               ],

From 7ef31cbf87a80598478c2ef68a4ff98cbe3c130a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 12:34:25 -0600
Subject: [PATCH 327/426] add back exchange menu option and adjust icon color

---
 .../home/desktop_menu.dart                    | 76 ++++++++++---------
 lib/utilities/theme/ocean_breeze_colors.dart  |  2 +-
 2 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_menu.dart b/lib/pages_desktop_specific/home/desktop_menu.dart
index bdaa1d6ce..60a424a06 100644
--- a/lib/pages_desktop_specific/home/desktop_menu.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu.dart
@@ -104,10 +104,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                     .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                             : Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                                 .withOpacity(0.8),
                       ),
                       label: "My Stack",
@@ -120,29 +120,33 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                     const SizedBox(
                       height: 2,
                     ),
-                    // DesktopMenuItem(
-                    //   icon: SvgPicture.asset(
-                    //     Assets.svg.exchangeDesktop,
-                    //     width: 20,
-                    //     height: 20,
-                    //     color: DesktopMenuItemId.exchange == ref.watch(currentDesktopMenuItemProvider.state).state
-                    //         ? Theme.of(context)
-                    //             .extension<StackColors>()!
-                    //             .textDark
-                    //         : Theme.of(context)
-                    //             .extension<StackColors>()!
-                    //             .textDark
-                    //             .withOpacity(0.8),
-                    //   ),
-                    //   label: "Exchange",
-                    //   value: DesktopMenuItemId.exchange,
-                    //   group: ref.watch(currentDesktopMenuItemProvider.state).state,
-                    //   onChanged: updateSelectedMenuItem,
-                    //   iconOnly: _width == minimizedWidth,
-                    // ),
-                    // const SizedBox(
-                    //   height: 2,
-                    // ),
+                    DesktopMenuItem(
+                      icon: SvgPicture.asset(
+                        Assets.svg.exchangeDesktop,
+                        width: 20,
+                        height: 20,
+                        color: DesktopMenuItemId.exchange ==
+                                ref
+                                    .watch(currentDesktopMenuItemProvider.state)
+                                    .state
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorDark
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorDark
+                                .withOpacity(0.8),
+                      ),
+                      label: "Exchange",
+                      value: DesktopMenuItemId.exchange,
+                      group:
+                          ref.watch(currentDesktopMenuItemProvider.state).state,
+                      onChanged: updateSelectedMenuItem,
+                      iconOnly: _width == minimizedWidth,
+                    ),
+                    const SizedBox(
+                      height: 2,
+                    ),
                     DesktopMenuItem(
                       icon: SvgPicture.asset(
                         Assets.svg.bell,
@@ -154,10 +158,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                     .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                             : Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                                 .withOpacity(0.8),
                       ),
                       label: "Notifications",
@@ -181,10 +185,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                     .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                             : Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                                 .withOpacity(0.8),
                       ),
                       label: "Address Book",
@@ -208,10 +212,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                     .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                             : Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                                 .withOpacity(0.8),
                       ),
                       label: "Settings",
@@ -235,10 +239,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                     .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                             : Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                                 .withOpacity(0.8),
                       ),
                       label: "Support",
@@ -262,10 +266,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                                     .state
                             ? Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                             : Theme.of(context)
                                 .extension<StackColors>()!
-                                .textDark
+                                .accentColorDark
                                 .withOpacity(0.8),
                       ),
                       label: "About",
@@ -283,7 +287,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         height: 20,
                         color: Theme.of(context)
                             .extension<StackColors>()!
-                            .textDark
+                            .accentColorDark
                             .withOpacity(0.8),
                       ),
                       label: "Exit",
diff --git a/lib/utilities/theme/ocean_breeze_colors.dart b/lib/utilities/theme/ocean_breeze_colors.dart
index ff2f4e85e..1eb06e068 100644
--- a/lib/utilities/theme/ocean_breeze_colors.dart
+++ b/lib/utilities/theme/ocean_breeze_colors.dart
@@ -21,7 +21,7 @@ class OceanBreezeColors extends StackColorTheme {
   @override
   Color get accentColorOrange => const Color(0xFFFF985F);
   @override
-  Color get accentColorDark => const Color(0xFF232323);
+  Color get accentColorDark => const Color(0xFF227386);
 
   @override
   Color get shadow => const Color(0xFF388192);

From ea143d9ffa901d30cf9f2631b0362fab80cfee71 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 12:45:42 -0600
Subject: [PATCH 328/426] basic desktop exchange layout

---
 .../desktop_exchange_view.dart                |  89 +++++++++++++++
 .../subwidgets/desktop_trade_history.dart     | 103 ++++++++++++++++++
 .../home/desktop_home_view.dart               |  10 +-
 lib/route_generator.dart                      |   7 ++
 4 files changed, 205 insertions(+), 4 deletions(-)
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart

diff --git a/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart b/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart
new file mode 100644
index 000000000..0f44eb59b
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart
@@ -0,0 +1,89 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/pages/exchange_view/exchange_form.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
+import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class DesktopExchangeView extends StatefulWidget {
+  const DesktopExchangeView({Key? key}) : super(key: key);
+
+  static const String routeName = "/desktopExchange";
+
+  @override
+  State<DesktopExchangeView> createState() => _DesktopExchangeViewState();
+}
+
+class _DesktopExchangeViewState extends State<DesktopExchangeView> {
+  @override
+  Widget build(BuildContext context) {
+    return DesktopScaffold(
+      appBar: DesktopAppBar(
+        isCompactHeight: true,
+        leading: Padding(
+          padding: const EdgeInsets.only(
+            left: 24,
+          ),
+          child: Text(
+            "Exchange",
+            style: STextStyles.desktopH3(context),
+          ),
+        ),
+      ),
+      body: Padding(
+        padding: const EdgeInsets.only(
+          left: 24,
+          right: 24,
+          bottom: 24,
+        ),
+        child: Row(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          children: [
+            Expanded(
+              child: Column(
+                mainAxisSize: MainAxisSize.min,
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Text(
+                    "Exchange details",
+                    style: STextStyles.desktopTextExtraExtraSmall(context),
+                  ),
+                  const SizedBox(
+                    height: 16,
+                  ),
+                  const RoundedWhiteContainer(
+                    padding: EdgeInsets.all(24),
+                    child: ExchangeForm(),
+                  ),
+                ],
+              ),
+            ),
+            const SizedBox(
+              width: 16,
+            ),
+            Expanded(
+              child: Column(
+                mainAxisSize: MainAxisSize.min,
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Text(
+                    "Exchange details",
+                    style: STextStyles.desktopTextExtraExtraSmall(context),
+                  ),
+                  const SizedBox(
+                    height: 16,
+                  ),
+                  const RoundedWhiteContainer(
+                    padding: EdgeInsets.all(0),
+                    child: DesktopTradeHistory(),
+                  ),
+                ],
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
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
new file mode 100644
index 000000000..40eeb8c1b
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart
@@ -0,0 +1,103 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
+import 'package:stackwallet/providers/exchange/trade_sent_from_stack_lookup_provider.dart';
+import 'package:stackwallet/providers/global/trades_service_provider.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/trade_card.dart';
+import 'package:tuple/tuple.dart';
+
+class DesktopTradeHistory extends ConsumerStatefulWidget {
+  const DesktopTradeHistory({Key? key}) : super(key: key);
+
+  @override
+  ConsumerState<DesktopTradeHistory> createState() =>
+      _DesktopTradeHistoryState();
+}
+
+class _DesktopTradeHistoryState extends ConsumerState<DesktopTradeHistory> {
+  @override
+  Widget build(BuildContext context) {
+    final trades =
+        ref.watch(tradesServiceProvider.select((value) => value.trades));
+
+    final tradeCount = trades.length;
+    final hasHistory = tradeCount > 0;
+
+    if (hasHistory) {
+      return ListView.separated(
+        itemBuilder: (context, index) {
+          return TradeCard(
+            key: Key("tradeCard_${trades[index].uuid}"),
+            trade: trades[index],
+            onTap: () async {
+              final String tradeId = trades[index].tradeId;
+
+              final lookup = ref.read(tradeSentFromStackLookupProvider).all;
+
+              debugPrint("ALL: $lookup");
+
+              final String? txid = ref
+                  .read(tradeSentFromStackLookupProvider)
+                  .getTxidForTradeId(tradeId);
+              final List<String>? walletIds = ref
+                  .read(tradeSentFromStackLookupProvider)
+                  .getWalletIdsForTradeId(tradeId);
+
+              if (txid != null && walletIds != null && walletIds.isNotEmpty) {
+                final manager = ref
+                    .read(walletsChangeNotifierProvider)
+                    .getManager(walletIds.first);
+
+                debugPrint("name: ${manager.walletName}");
+
+                // TODO store tx data completely locally in isar so we don't lock up ui here when querying txData
+                final txData = await manager.transactionData;
+
+                final tx = txData.getAllTransactions()[txid];
+
+                if (mounted) {
+                  unawaited(
+                    Navigator.of(context).pushNamed(
+                      TradeDetailsView.routeName,
+                      arguments: Tuple4(
+                          tradeId, tx, walletIds.first, manager.walletName),
+                    ),
+                  );
+                }
+              } else {
+                unawaited(
+                  Navigator.of(context).pushNamed(
+                    TradeDetailsView.routeName,
+                    arguments: Tuple4(tradeId, null, walletIds?.first, null),
+                  ),
+                );
+              }
+            },
+          );
+        },
+        separatorBuilder: (context, index) {
+          return Container(
+            height: 1,
+            color: Theme.of(context).extension<StackColors>()!.background,
+          );
+        },
+        itemCount: tradeCount,
+      );
+    } else {
+      return RoundedWhiteContainer(
+        child: Center(
+          child: Text(
+            "Trades will appear here",
+            style: STextStyles.desktopTextExtraExtraSmall(context),
+          ),
+        ),
+      );
+    }
+  }
+}
diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index b1c35f00b..9791cd867 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/address_book_view/desktop_address_book.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_menu.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
@@ -29,10 +30,11 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: MyStackView.routeName,
     ),
-    // Container(
-    //   // todo: exchange
-    //   color: Colors.green,
-    // ),
+    DesktopMenuItemId.exchange: const Navigator(
+      key: Key("desktopExchangeHomeKey"),
+      onGenerateRoute: RouteGenerator.generateRoute,
+      initialRoute: DesktopExchangeView.routeName,
+    ),
     DesktopMenuItemId.notifications: const Navigator(
       key: Key("desktopNotificationsHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index d7865d013..8ccc923bc 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -85,6 +85,7 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_sear
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
 import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
 import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart';
 import 'package:stackwallet/pages_desktop_specific/forgot_password_desktop_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/address_book_view/desktop_address_book.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
@@ -1019,6 +1020,12 @@ class RouteGenerator {
             builder: (_) => const DesktopNotificationsView(),
             settings: RouteSettings(name: settings.name));
 
+      case DesktopExchangeView.routeName:
+        return getRoute(
+            shouldUseMaterialRoute: useMaterialPageRoute,
+            builder: (_) => const DesktopExchangeView(),
+            settings: RouteSettings(name: settings.name));
+
       case DesktopSettingsView.routeName:
         return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,

From 83e2554b545e62a6cf4af323093a150dfe054812 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 18 Nov 2022 12:42:12 -0700
Subject: [PATCH 329/426] mobile theme radio buttons

---
 .../appearance_settings_view.dart             | 364 +++++++++++++++---
 1 file changed, 309 insertions(+), 55 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart b/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart
index 3a1b842f6..d1e893802 100644
--- a/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart
+++ b/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart
@@ -8,6 +8,7 @@ import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/color_theme.dart';
 import 'package:stackwallet/utilities/theme/dark_colors.dart';
 import 'package:stackwallet/utilities/theme/light_colors.dart';
+import 'package:stackwallet/utilities/theme/ocean_breeze_colors.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
@@ -18,6 +19,17 @@ class AppearanceSettingsView extends ConsumerWidget {
 
   static const String routeName = "/appearanceSettings";
 
+  String chooseThemeType(ThemeType type) {
+    switch (type) {
+      case ThemeType.light:
+        return "Light theme";
+      case ThemeType.oceanBreeze:
+        return "Ocean theme";
+      case ThemeType.dark:
+        return "Dark theme";
+    }
+  }
+
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     return Scaffold(
@@ -100,68 +112,39 @@ class AppearanceSettingsView extends ConsumerWidget {
                         height: 10,
                       ),
                       RoundedWhiteContainer(
-                        child: Consumer(
-                          builder: (_, ref, __) {
-                            return RawMaterialButton(
-                              splashColor: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .highlight,
-                              materialTapTargetSize:
-                                  MaterialTapTargetSize.shrinkWrap,
-                              shape: RoundedRectangleBorder(
-                                borderRadius: BorderRadius.circular(
-                                  Constants.size.circularBorderRadius,
-                                ),
-                              ),
-                              onPressed: null,
-                              child: Padding(
-                                padding:
-                                    const EdgeInsets.symmetric(vertical: 8),
-                                child: Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
+                        padding: const EdgeInsets.all(0),
+                        child: RawMaterialButton(
+                          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                          padding: const EdgeInsets.all(0),
+                          materialTapTargetSize:
+                              MaterialTapTargetSize.shrinkWrap,
+                          shape: RoundedRectangleBorder(
+                            borderRadius: BorderRadius.circular(
+                              Constants.size.circularBorderRadius,
+                            ),
+                          ),
+                          onPressed: null,
+                          child: Padding(
+                            padding: const EdgeInsets.all(12),
+                            child: Row(
+                              children: [
+                                Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
                                   children: [
                                     Text(
-                                      "Enable dark mode",
+                                      "Choose Theme",
                                       style: STextStyles.titleBold12(context),
                                       textAlign: TextAlign.left,
                                     ),
-                                    SizedBox(
-                                      height: 20,
-                                      width: 40,
-                                      child: DraggableSwitchButton(
-                                        isOn: (DB.instance.get<dynamic>(
-                                                    boxName: DB.boxNameTheme,
-                                                    key: "colorScheme")
-                                                as String?) ==
-                                            "dark",
-                                        onValueChanged: (newValue) {
-                                          DB.instance.put<dynamic>(
-                                            boxName: DB.boxNameTheme,
-                                            key: "colorScheme",
-                                            value: (newValue
-                                                    ? ThemeType.dark
-                                                    : (newValue
-                                                        ? ThemeType.light
-                                                        : ThemeType
-                                                            .oceanBreeze))
-                                                .name,
-                                          );
-                                          ref
-                                                  .read(colorThemeProvider.state)
-                                                  .state =
-                                              StackColors.fromStackColorTheme(
-                                                  newValue
-                                                      ? DarkColors()
-                                                      : LightColors());
-                                        },
-                                      ),
-                                    )
+                                    const Padding(
+                                      padding: EdgeInsets.all(10),
+                                      child: ThemeOptionsView(),
+                                    ),
                                   ],
                                 ),
-                              ),
-                            );
-                          },
+                              ],
+                            ),
+                          ),
                         ),
                       ),
                     ],
@@ -175,3 +158,274 @@ class AppearanceSettingsView extends ConsumerWidget {
     );
   }
 }
+
+class ThemeOptionsView extends ConsumerStatefulWidget {
+  const ThemeOptionsView({
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  ConsumerState<ThemeOptionsView> createState() => _ThemeOptionsView();
+}
+
+class _ThemeOptionsView extends ConsumerState<ThemeOptionsView> {
+  late String _selectedTheme;
+
+  @override
+  void initState() {
+    _selectedTheme =
+        DB.instance.get<dynamic>(boxName: DB.boxNameTheme, key: "colorScheme")
+                as String? ??
+            "light";
+
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        MaterialButton(
+          splashColor: Colors.transparent,
+          hoverColor: Colors.transparent,
+          padding: const EdgeInsets.all(0),
+          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+          ),
+          onPressed: () {
+            DB.instance.put<dynamic>(
+              boxName: DB.boxNameTheme,
+              key: "colorScheme",
+              value: ThemeType.light.name,
+            );
+            ref.read(colorThemeProvider.state).state =
+                StackColors.fromStackColorTheme(
+              LightColors(),
+            );
+
+            setState(() {
+              _selectedTheme = "light";
+            });
+          },
+          child: SizedBox(
+            width: 200,
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                Row(
+                  children: [
+                    SizedBox(
+                      width: 10,
+                      height: 10,
+                      child: Radio(
+                        activeColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .radioButtonIconEnabled,
+                        value: "light",
+                        groupValue: _selectedTheme,
+                        onChanged: (newValue) {
+                          if (newValue is String && newValue == "light") {
+                            DB.instance.put<dynamic>(
+                              boxName: DB.boxNameTheme,
+                              key: "colorScheme",
+                              value: ThemeType.light.name,
+                            );
+                            ref.read(colorThemeProvider.state).state =
+                                StackColors.fromStackColorTheme(
+                              LightColors(),
+                            );
+
+                            setState(() {
+                              _selectedTheme = "light";
+                            });
+                          }
+                        },
+                      ),
+                    ),
+                    const SizedBox(
+                      width: 14,
+                    ),
+                    Text(
+                      "Light",
+                      style:
+                          STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark2,
+                      ),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 10,
+        ),
+        MaterialButton(
+          splashColor: Colors.transparent,
+          hoverColor: Colors.transparent,
+          padding: const EdgeInsets.all(0),
+          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+          ),
+          onPressed: () {
+            DB.instance.put<dynamic>(
+              boxName: DB.boxNameTheme,
+              key: "colorScheme",
+              value: ThemeType.oceanBreeze.name,
+            );
+            ref.read(colorThemeProvider.state).state =
+                StackColors.fromStackColorTheme(
+              OceanBreezeColors(),
+            );
+
+            setState(() {
+              _selectedTheme = "oceanBreeze";
+            });
+          },
+          child: SizedBox(
+            width: 200,
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                Row(
+                  children: [
+                    SizedBox(
+                      width: 10,
+                      height: 10,
+                      child: Radio(
+                        activeColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .radioButtonIconEnabled,
+                        value: "oceanBreeze",
+                        groupValue: _selectedTheme,
+                        onChanged: (newValue) {
+                          if (newValue is String && newValue == "oceanBreeze") {
+                            DB.instance.put<dynamic>(
+                              boxName: DB.boxNameTheme,
+                              key: "colorScheme",
+                              value: ThemeType.oceanBreeze.name,
+                            );
+                            ref.read(colorThemeProvider.state).state =
+                                StackColors.fromStackColorTheme(
+                              OceanBreezeColors(),
+                            );
+
+                            setState(() {
+                              _selectedTheme = "oceanBreeze";
+                            });
+                          }
+                        },
+                      ),
+                    ),
+                    const SizedBox(
+                      width: 14,
+                    ),
+                    Text(
+                      "Ocean Breeze",
+                      style:
+                          STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark2,
+                      ),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 10,
+        ),
+        MaterialButton(
+          splashColor: Colors.transparent,
+          hoverColor: Colors.transparent,
+          padding: const EdgeInsets.all(0),
+          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+          ),
+          onPressed: () {
+            DB.instance.put<dynamic>(
+              boxName: DB.boxNameTheme,
+              key: "colorScheme",
+              value: ThemeType.dark.name,
+            );
+            ref.read(colorThemeProvider.state).state =
+                StackColors.fromStackColorTheme(
+              DarkColors(),
+            );
+
+            setState(() {
+              _selectedTheme = "dark";
+            });
+          },
+          child: SizedBox(
+            width: 200,
+            child: Column(
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                Row(
+                  children: [
+                    SizedBox(
+                      width: 10,
+                      height: 10,
+                      child: Radio(
+                        activeColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .radioButtonIconEnabled,
+                        value: "dark",
+                        groupValue: _selectedTheme,
+                        onChanged: (newValue) {
+                          if (newValue is String && newValue == "dark") {
+                            DB.instance.put<dynamic>(
+                              boxName: DB.boxNameTheme,
+                              key: "colorScheme",
+                              value: ThemeType.dark.name,
+                            );
+                            ref.read(colorThemeProvider.state).state =
+                                StackColors.fromStackColorTheme(
+                              DarkColors(),
+                            );
+
+                            setState(() {
+                              _selectedTheme = "dark";
+                            });
+                          }
+                        },
+                      ),
+                    ),
+                    const SizedBox(
+                      width: 14,
+                    ),
+                    Text(
+                      "Dark",
+                      style:
+                          STextStyles.desktopTextExtraSmall(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark2,
+                      ),
+                    ),
+                  ],
+                ),
+              ],
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}

From 9956a497df081a54a67a90ae68f93ee5d6e32cc3 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 18 Nov 2022 13:26:17 -0700
Subject: [PATCH 330/426] ocean breeze shadow color fix

---
 lib/utilities/theme/ocean_breeze_colors.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/utilities/theme/ocean_breeze_colors.dart b/lib/utilities/theme/ocean_breeze_colors.dart
index 1eb06e068..665eaa0c3 100644
--- a/lib/utilities/theme/ocean_breeze_colors.dart
+++ b/lib/utilities/theme/ocean_breeze_colors.dart
@@ -24,7 +24,7 @@ class OceanBreezeColors extends StackColorTheme {
   Color get accentColorDark => const Color(0xFF227386);
 
   @override
-  Color get shadow => const Color(0xFF388192);
+  Color get shadow => const Color(0x0F2D3132);
 
   @override
   Color get textDark => const Color(0xFF232323);

From e665926b1bc229e6abee16bdda38debe242191e4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 14:59:53 -0600
Subject: [PATCH 331/426] firo anonymize navigation fix

---
 .../wallet_view/desktop_wallet_view.dart      | 47 +++++++++++++++++--
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index d08864eee..85dde4aba 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -193,6 +193,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
     if (publicBalance <= Decimal.zero) {
       shouldPop = true;
       if (mounted) {
+        Navigator.of(context, rootNavigator: true).pop();
         Navigator.of(context).popUntil(
           ModalRoute.withName(DesktopWalletView.routeName),
         );
@@ -211,6 +212,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
       await firoWallet.anonymizeAllPublicFunds();
       shouldPop = true;
       if (mounted) {
+        Navigator.of(context, rootNavigator: true).pop();
         Navigator.of(context).popUntil(
           ModalRoute.withName(DesktopWalletView.routeName),
         );
@@ -225,14 +227,53 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
     } catch (e) {
       shouldPop = true;
       if (mounted) {
+        Navigator.of(context, rootNavigator: true).pop();
         Navigator.of(context).popUntil(
           ModalRoute.withName(DesktopWalletView.routeName),
         );
         await showDialog<dynamic>(
           context: context,
-          builder: (_) => StackOkDialog(
-            title: "Anonymize all failed",
-            message: "Reason: $e",
+          builder: (_) => DesktopDialog(
+            maxWidth: 400,
+            maxHeight: 300,
+            child: Padding(
+              padding: const EdgeInsets.all(24),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Text(
+                    "Anonymize all failed",
+                    style: STextStyles.desktopH3(context),
+                  ),
+                  const Spacer(
+                    flex: 1,
+                  ),
+                  Text(
+                    "Reason: $e",
+                    style: STextStyles.desktopTextSmall(context),
+                  ),
+                  const Spacer(
+                    flex: 2,
+                  ),
+                  Row(
+                    children: [
+                      const Spacer(),
+                      const SizedBox(
+                        width: 16,
+                      ),
+                      Expanded(
+                        child: PrimaryButton(
+                          label: "Ok",
+                          buttonHeight: ButtonHeight.l,
+                          onPressed:
+                              Navigator.of(context, rootNavigator: true).pop,
+                        ),
+                      ),
+                    ],
+                  )
+                ],
+              ),
+            ),
           ),
         );
       }

From 9ba83f36eb480ff0dab6af8ca4a2ebed5d37642d Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 16:05:15 -0600
Subject: [PATCH 332/426] desktop exchange rate toggle style

---
 assets/svg/lock-open.svg                      |   3 +
 .../sub_widgets/rate_type_toggle.dart         | 115 +++++++++++++-----
 pubspec.yaml                                  |   1 +
 3 files changed, 88 insertions(+), 31 deletions(-)
 create mode 100644 assets/svg/lock-open.svg

diff --git a/assets/svg/lock-open.svg b/assets/svg/lock-open.svg
new file mode 100644
index 000000000..f2b00f341
--- /dev/null
+++ b/assets/svg/lock-open.svg
@@ -0,0 +1,3 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7 1.75C5.79141 1.75 4.8125 2.72945 4.8125 3.9375V5.25H11.375C12.3402 5.25 13.125 6.03477 13.125 7V12.25C13.125 13.2152 12.3402 14 11.375 14H2.625C1.6584 14 0.875 13.2152 0.875 12.25V7C0.875 6.03477 1.6584 5.25 2.625 5.25H3.0625V3.9375C3.0625 1.76285 4.82617 0 7 0C8.57227 0 9.92578 0.921211 10.5574 2.24957C10.7652 2.68598 10.5793 3.20742 10.1199 3.41523C9.68242 3.62305 9.18476 3.43711 8.97695 2.99961C8.62422 2.25941 7.87227 1.75 7 1.75ZM7.875 10.5C8.35898 10.5 8.75 10.109 8.75 9.625C8.75 9.14102 8.35898 8.75 7.875 8.75H6.125C5.64102 8.75 5.25 9.14102 5.25 9.625C5.25 10.109 5.64102 10.5 6.125 10.5H7.875Z" fill="#0056D2"/>
+</svg>
diff --git a/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart b/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart
index 31460c75f..9697710e8 100644
--- a/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart
+++ b/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart
@@ -7,8 +7,8 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.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/rounded_container.dart';
-import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class RateTypeToggle extends ConsumerWidget {
   const RateTypeToggle({
@@ -21,12 +21,17 @@ class RateTypeToggle extends ConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     debugPrint("BUILD: $runtimeType");
+    final isDesktop = Util.isDesktop;
+
     final estimated = ref.watch(prefsChangeNotifierProvider
             .select((value) => value.exchangeRateType)) ==
         ExchangeRateType.estimated;
 
-    return RoundedWhiteContainer(
+    return RoundedContainer(
       padding: const EdgeInsets.all(0),
+      color: isDesktop
+          ? Theme.of(context).extension<StackColors>()!.buttonBackSecondary
+          : Theme.of(context).extension<StackColors>()!.popupBG,
       child: Row(
         children: [
           Expanded(
@@ -39,6 +44,9 @@ class RateTypeToggle extends ConsumerWidget {
                 }
               },
               child: RoundedContainer(
+                padding: isDesktop
+                    ? const EdgeInsets.all(17)
+                    : const EdgeInsets.all(0),
                 color: estimated
                     ? Theme.of(context)
                         .extension<StackColors>()!
@@ -48,29 +56,50 @@ class RateTypeToggle extends ConsumerWidget {
                   mainAxisAlignment: MainAxisAlignment.center,
                   children: [
                     SvgPicture.asset(
-                      Assets.svg.lock,
+                      Assets.svg.lockOpen,
                       width: 12,
                       height: 14,
-                      color: estimated
-                          ? Theme.of(context).extension<StackColors>()!.textDark
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .textSubtitle1,
+                      color: isDesktop
+                          ? estimated
+                              ? Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorBlue
+                              : Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .buttonTextSecondary
+                          : estimated
+                              ? Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark
+                              : Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textSubtitle1,
                     ),
                     const SizedBox(
                       width: 5,
                     ),
                     Text(
                       "Estimate rate",
-                      style: STextStyles.smallMed12(context).copyWith(
-                        color: estimated
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .textSubtitle1,
-                      ),
+                      style: isDesktop
+                          ? STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                              color: estimated
+                                  ? Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .accentColorBlue
+                                  : Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .buttonTextSecondary,
+                            )
+                          : STextStyles.smallMed12(context).copyWith(
+                              color: estimated
+                                  ? Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark
+                                  : Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textSubtitle1,
+                            ),
                     ),
                   ],
                 ),
@@ -87,6 +116,9 @@ class RateTypeToggle extends ConsumerWidget {
                 }
               },
               child: RoundedContainer(
+                padding: isDesktop
+                    ? const EdgeInsets.all(17)
+                    : const EdgeInsets.all(0),
                 color: !estimated
                     ? Theme.of(context)
                         .extension<StackColors>()!
@@ -99,26 +131,47 @@ class RateTypeToggle extends ConsumerWidget {
                       Assets.svg.lock,
                       width: 12,
                       height: 14,
-                      color: !estimated
-                          ? Theme.of(context).extension<StackColors>()!.textDark
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .textSubtitle1,
+                      color: isDesktop
+                          ? !estimated
+                              ? Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorBlue
+                              : Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .buttonTextSecondary
+                          : !estimated
+                              ? Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark
+                              : Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textSubtitle1,
                     ),
                     const SizedBox(
                       width: 5,
                     ),
                     Text(
                       "Fixed rate",
-                      style: STextStyles.smallMed12(context).copyWith(
-                        color: !estimated
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .textSubtitle1,
-                      ),
+                      style: isDesktop
+                          ? STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                              color: !estimated
+                                  ? Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .accentColorBlue
+                                  : Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .buttonTextSecondary,
+                            )
+                          : STextStyles.smallMed12(context).copyWith(
+                              color: !estimated
+                                  ? Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark
+                                  : Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textSubtitle1,
+                            ),
                     ),
                   ],
                 ),
diff --git a/pubspec.yaml b/pubspec.yaml
index 6a721c5c1..e8f417586 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -228,6 +228,7 @@ flutter:
     - assets/svg/chevron-down.svg
     - assets/svg/chevron-up.svg
     - assets/svg/lock-keyhole.svg
+    - assets/svg/lock-open.svg
     - assets/svg/rotate-exclamation.svg
     - assets/svg/folder-down.svg
     - assets/svg/network-wired.svg

From 16113fd1d52319b855cb6e38044da84f810feb7a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 16:05:46 -0600
Subject: [PATCH 333/426] desktop exchange provider options dropdown style

---
 .../exchange_provider_options.dart            | 706 ++++++++++--------
 1 file changed, 379 insertions(+), 327 deletions(-)

diff --git a/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart b/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart
index 2113e199c..4dd768403 100644
--- a/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart
+++ b/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart
@@ -15,7 +15,9 @@ import 'package:stackwallet/utilities/format.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/animated_text.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class ExchangeProviderOptions extends ConsumerWidget {
@@ -38,353 +40,403 @@ class ExchangeProviderOptions extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
+    final isDesktop = Util.isDesktop;
     return RoundedWhiteContainer(
+      padding: isDesktop ? const EdgeInsets.all(0) : const EdgeInsets.all(12),
+      borderColor: isDesktop
+          ? Theme.of(context).extension<StackColors>()!.background
+          : null,
       child: Column(
         children: [
-          GestureDetector(
-            onTap: () {
-              if (ref.read(currentExchangeNameStateProvider.state).state !=
-                  ChangeNowExchange.exchangeName) {
-                ref.read(currentExchangeNameStateProvider.state).state =
-                    ChangeNowExchange.exchangeName;
-                ref.read(exchangeFormStateProvider).exchange =
-                    Exchange.fromName(
-                        ref.read(currentExchangeNameStateProvider.state).state);
-              }
-            },
-            child: Container(
-              color: Colors.transparent,
-              child: Row(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  SizedBox(
-                    width: 20,
-                    height: 20,
-                    child: Radio(
-                      activeColor: Theme.of(context)
-                          .extension<StackColors>()!
-                          .radioButtonIconEnabled,
-                      value: ChangeNowExchange.exchangeName,
-                      groupValue: ref
-                          .watch(currentExchangeNameStateProvider.state)
-                          .state,
-                      onChanged: (value) {
-                        if (value is String) {
-                          ref
-                              .read(currentExchangeNameStateProvider.state)
-                              .state = value;
-                          ref.read(exchangeFormStateProvider).exchange =
-                              Exchange.fromName(ref
+          ConditionalParent(
+            condition: isDesktop,
+            builder: (child) => MouseRegion(
+              cursor: SystemMouseCursors.click,
+              child: child,
+            ),
+            child: GestureDetector(
+              onTap: () {
+                if (ref.read(currentExchangeNameStateProvider.state).state !=
+                    ChangeNowExchange.exchangeName) {
+                  ref.read(currentExchangeNameStateProvider.state).state =
+                      ChangeNowExchange.exchangeName;
+                  ref.read(exchangeFormStateProvider).exchange =
+                      Exchange.fromName(ref
+                          .read(currentExchangeNameStateProvider.state)
+                          .state);
+                }
+              },
+              child: Container(
+                color: Colors.transparent,
+                child: Padding(
+                  padding: isDesktop
+                      ? const EdgeInsets.all(16)
+                      : const EdgeInsets.all(0),
+                  child: Row(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      SizedBox(
+                        width: 20,
+                        height: 20,
+                        child: Radio(
+                          activeColor: Theme.of(context)
+                              .extension<StackColors>()!
+                              .radioButtonIconEnabled,
+                          value: ChangeNowExchange.exchangeName,
+                          groupValue: ref
+                              .watch(currentExchangeNameStateProvider.state)
+                              .state,
+                          onChanged: (value) {
+                            if (value is String) {
+                              ref
                                   .read(currentExchangeNameStateProvider.state)
-                                  .state);
-                        }
-                      },
-                    ),
-                  ),
-                  const SizedBox(
-                    width: 14,
-                  ),
-                  SvgPicture.asset(
-                    Assets.exchange.changeNow,
-                    width: 24,
-                    height: 24,
-                  ),
-                  const SizedBox(
-                    width: 10,
-                  ),
-                  Expanded(
-                    child: Column(
-                      mainAxisAlignment: MainAxisAlignment.start,
-                      mainAxisSize: MainAxisSize.min,
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        Text(
-                          ChangeNowExchange.exchangeName,
-                          style: STextStyles.titleBold12(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark2,
-                          ),
+                                  .state = value;
+                              ref.read(exchangeFormStateProvider).exchange =
+                                  Exchange.fromName(ref
+                                      .read(currentExchangeNameStateProvider
+                                          .state)
+                                      .state);
+                            }
+                          },
                         ),
-                        if (from != null &&
-                            to != null &&
-                            toAmount != null &&
-                            toAmount! > Decimal.zero &&
-                            fromAmount != null &&
-                            fromAmount! > Decimal.zero)
-                          FutureBuilder(
-                            future: ChangeNowExchange().getEstimate(
-                              from!,
-                              to!,
-                              reversed ? toAmount! : fromAmount!,
-                              fixedRate,
-                              reversed,
+                      ),
+                      const SizedBox(
+                        width: 14,
+                      ),
+                      SvgPicture.asset(
+                        Assets.exchange.changeNow,
+                        width: isDesktop ? 32 : 24,
+                        height: isDesktop ? 32 : 24,
+                      ),
+                      const SizedBox(
+                        width: 10,
+                      ),
+                      Expanded(
+                        child: Column(
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          mainAxisSize: MainAxisSize.min,
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            Text(
+                              ChangeNowExchange.exchangeName,
+                              style: STextStyles.titleBold12(context).copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark2,
+                              ),
                             ),
-                            builder: (context,
-                                AsyncSnapshot<ExchangeResponse<Estimate>>
-                                    snapshot) {
-                              if (snapshot.connectionState ==
-                                      ConnectionState.done &&
-                                  snapshot.hasData) {
-                                final estimate = snapshot.data?.value;
-                                if (estimate != null) {
-                                  Decimal rate;
-                                  if (estimate.reversed) {
-                                    rate =
-                                        (toAmount! / estimate.estimatedAmount)
+                            if (from != null &&
+                                to != null &&
+                                toAmount != null &&
+                                toAmount! > Decimal.zero &&
+                                fromAmount != null &&
+                                fromAmount! > Decimal.zero)
+                              FutureBuilder(
+                                future: ChangeNowExchange().getEstimate(
+                                  from!,
+                                  to!,
+                                  reversed ? toAmount! : fromAmount!,
+                                  fixedRate,
+                                  reversed,
+                                ),
+                                builder: (context,
+                                    AsyncSnapshot<ExchangeResponse<Estimate>>
+                                        snapshot) {
+                                  if (snapshot.connectionState ==
+                                          ConnectionState.done &&
+                                      snapshot.hasData) {
+                                    final estimate = snapshot.data?.value;
+                                    if (estimate != null) {
+                                      Decimal rate;
+                                      if (estimate.reversed) {
+                                        rate = (toAmount! /
+                                                estimate.estimatedAmount)
                                             .toDecimal(
                                                 scaleOnInfinitePrecision: 12);
+                                      } else {
+                                        rate = (estimate.estimatedAmount /
+                                                fromAmount!)
+                                            .toDecimal(
+                                                scaleOnInfinitePrecision: 12);
+                                      }
+                                      return Text(
+                                        "1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
+                                          value: rate,
+                                          locale: ref.watch(
+                                            localeServiceChangeNotifierProvider
+                                                .select(
+                                                    (value) => value.locale),
+                                          ),
+                                          decimalPlaces: to!.toUpperCase() ==
+                                                  Coin.monero.ticker
+                                                      .toUpperCase()
+                                              ? Constants.decimalPlacesMonero
+                                              : Constants.decimalPlaces,
+                                        )} ${to!.toUpperCase()}",
+                                        style:
+                                            STextStyles.itemSubtitle12(context)
+                                                .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .textSubtitle1,
+                                        ),
+                                      );
+                                    } else {
+                                      Logging.instance.log(
+                                        "$runtimeType failed to fetch rate for ChangeNOW: ${snapshot.data}",
+                                        level: LogLevel.Warning,
+                                      );
+                                      return Text(
+                                        "Failed to fetch rate",
+                                        style:
+                                            STextStyles.itemSubtitle12(context)
+                                                .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .textSubtitle1,
+                                        ),
+                                      );
+                                    }
                                   } else {
-                                    rate =
-                                        (estimate.estimatedAmount / fromAmount!)
-                                            .toDecimal(
-                                                scaleOnInfinitePrecision: 12);
-                                  }
-                                  return Text(
-                                    "1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
-                                      value: rate,
-                                      locale: ref.watch(
-                                        localeServiceChangeNotifierProvider
-                                            .select((value) => value.locale),
+                                    return AnimatedText(
+                                      stringsToLoopThrough: const [
+                                        "Loading",
+                                        "Loading.",
+                                        "Loading..",
+                                        "Loading...",
+                                      ],
+                                      style: STextStyles.itemSubtitle12(context)
+                                          .copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textSubtitle1,
                                       ),
-                                      decimalPlaces: to!.toUpperCase() ==
-                                              Coin.monero.ticker.toUpperCase()
-                                          ? Constants.decimalPlacesMonero
-                                          : Constants.decimalPlaces,
-                                    )} ${to!.toUpperCase()}",
-                                    style: STextStyles.itemSubtitle12(context)
-                                        .copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textSubtitle1,
-                                    ),
-                                  );
-                                } else {
-                                  Logging.instance.log(
-                                    "$runtimeType failed to fetch rate for ChangeNOW: ${snapshot.data}",
-                                    level: LogLevel.Warning,
-                                  );
-                                  return Text(
-                                    "Failed to fetch rate",
-                                    style: STextStyles.itemSubtitle12(context)
-                                        .copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textSubtitle1,
-                                    ),
-                                  );
-                                }
-                              } else {
-                                return AnimatedText(
-                                  stringsToLoopThrough: const [
-                                    "Loading",
-                                    "Loading.",
-                                    "Loading..",
-                                    "Loading...",
-                                  ],
-                                  style: STextStyles.itemSubtitle12(context)
-                                      .copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textSubtitle1,
-                                  ),
-                                );
-                              }
-                            },
-                          ),
-                        if (!(from != null &&
-                            to != null &&
-                            toAmount != null &&
-                            toAmount! > Decimal.zero &&
-                            fromAmount != null &&
-                            fromAmount! > Decimal.zero))
-                          Text(
-                            "n/a",
-                            style: STextStyles.itemSubtitle12(context).copyWith(
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textSubtitle1,
-                            ),
-                          ),
-                      ],
-                    ),
+                                    );
+                                  }
+                                },
+                              ),
+                            if (!(from != null &&
+                                to != null &&
+                                toAmount != null &&
+                                toAmount! > Decimal.zero &&
+                                fromAmount != null &&
+                                fromAmount! > Decimal.zero))
+                              Text(
+                                "n/a",
+                                style: STextStyles.itemSubtitle12(context)
+                                    .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textSubtitle1,
+                                ),
+                              ),
+                          ],
+                        ),
+                      ),
+                    ],
                   ),
-                ],
+                ),
               ),
             ),
           ),
-          const SizedBox(
-            height: 16,
-          ),
-          GestureDetector(
-            onTap: () {
-              if (ref.read(currentExchangeNameStateProvider.state).state !=
-                  SimpleSwapExchange.exchangeName) {
-                ref.read(currentExchangeNameStateProvider.state).state =
-                    SimpleSwapExchange.exchangeName;
-                ref.read(exchangeFormStateProvider).exchange =
-                    Exchange.fromName(
-                        ref.read(currentExchangeNameStateProvider.state).state);
-              }
-            },
-            child: Container(
-              color: Colors.transparent,
-              child: Row(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  SizedBox(
-                    width: 20,
-                    height: 20,
-                    child: Radio(
-                      activeColor: Theme.of(context)
-                          .extension<StackColors>()!
-                          .radioButtonIconEnabled,
-                      value: SimpleSwapExchange.exchangeName,
-                      groupValue: ref
-                          .watch(currentExchangeNameStateProvider.state)
-                          .state,
-                      onChanged: (value) {
-                        if (value is String) {
-                          ref
-                              .read(currentExchangeNameStateProvider.state)
-                              .state = value;
-                          ref.read(exchangeFormStateProvider).exchange =
-                              Exchange.fromName(ref
+          if (isDesktop)
+            Container(
+              height: 1,
+              color: Theme.of(context).extension<StackColors>()!.background,
+            ),
+          if (!isDesktop)
+            const SizedBox(
+              height: 16,
+            ),
+          ConditionalParent(
+            condition: isDesktop,
+            builder: (child) => MouseRegion(
+              cursor: SystemMouseCursors.click,
+              child: child,
+            ),
+            child: GestureDetector(
+              onTap: () {
+                if (ref.read(currentExchangeNameStateProvider.state).state !=
+                    SimpleSwapExchange.exchangeName) {
+                  ref.read(currentExchangeNameStateProvider.state).state =
+                      SimpleSwapExchange.exchangeName;
+                  ref.read(exchangeFormStateProvider).exchange =
+                      Exchange.fromName(ref
+                          .read(currentExchangeNameStateProvider.state)
+                          .state);
+                }
+              },
+              child: Container(
+                color: Colors.transparent,
+                child: Padding(
+                  padding: isDesktop
+                      ? const EdgeInsets.all(16)
+                      : const EdgeInsets.all(0),
+                  child: Row(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      SizedBox(
+                        width: 20,
+                        height: 20,
+                        child: Radio(
+                          activeColor: Theme.of(context)
+                              .extension<StackColors>()!
+                              .radioButtonIconEnabled,
+                          value: SimpleSwapExchange.exchangeName,
+                          groupValue: ref
+                              .watch(currentExchangeNameStateProvider.state)
+                              .state,
+                          onChanged: (value) {
+                            if (value is String) {
+                              ref
                                   .read(currentExchangeNameStateProvider.state)
-                                  .state);
-                        }
-                      },
-                    ),
-                  ),
-                  const SizedBox(
-                    width: 14,
-                  ),
-                  SvgPicture.asset(
-                    Assets.exchange.simpleSwap,
-                    width: 24,
-                    height: 24,
-                  ),
-                  const SizedBox(
-                    width: 10,
-                  ),
-                  Expanded(
-                    child: Column(
-                      mainAxisAlignment: MainAxisAlignment.start,
-                      mainAxisSize: MainAxisSize.min,
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        Text(
-                          SimpleSwapExchange.exchangeName,
-                          style: STextStyles.titleBold12(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark2,
-                          ),
+                                  .state = value;
+                              ref.read(exchangeFormStateProvider).exchange =
+                                  Exchange.fromName(ref
+                                      .read(currentExchangeNameStateProvider
+                                          .state)
+                                      .state);
+                            }
+                          },
                         ),
-                        if (from != null &&
-                            to != null &&
-                            toAmount != null &&
-                            toAmount! > Decimal.zero &&
-                            fromAmount != null &&
-                            fromAmount! > Decimal.zero)
-                          FutureBuilder(
-                            future: SimpleSwapExchange().getEstimate(
-                              from!,
-                              to!,
-                              // reversed ? toAmount! : fromAmount!,
-                              fromAmount!,
-                              fixedRate,
-                              // reversed,
-                              false,
+                      ),
+                      const SizedBox(
+                        width: 14,
+                      ),
+                      SvgPicture.asset(
+                        Assets.exchange.simpleSwap,
+                        width: isDesktop ? 32 : 24,
+                        height: isDesktop ? 32 : 24,
+                      ),
+                      const SizedBox(
+                        width: 10,
+                      ),
+                      Expanded(
+                        child: Column(
+                          mainAxisAlignment: MainAxisAlignment.start,
+                          mainAxisSize: MainAxisSize.min,
+                          crossAxisAlignment: CrossAxisAlignment.start,
+                          children: [
+                            Text(
+                              SimpleSwapExchange.exchangeName,
+                              style: STextStyles.titleBold12(context).copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark2,
+                              ),
                             ),
-                            builder: (context,
-                                AsyncSnapshot<ExchangeResponse<Estimate>>
-                                    snapshot) {
-                              if (snapshot.connectionState ==
-                                      ConnectionState.done &&
-                                  snapshot.hasData) {
-                                final estimate = snapshot.data?.value;
-                                if (estimate != null) {
-                                  Decimal rate = (estimate.estimatedAmount /
-                                          fromAmount!)
-                                      .toDecimal(scaleOnInfinitePrecision: 12);
+                            if (from != null &&
+                                to != null &&
+                                toAmount != null &&
+                                toAmount! > Decimal.zero &&
+                                fromAmount != null &&
+                                fromAmount! > Decimal.zero)
+                              FutureBuilder(
+                                future: SimpleSwapExchange().getEstimate(
+                                  from!,
+                                  to!,
+                                  // reversed ? toAmount! : fromAmount!,
+                                  fromAmount!,
+                                  fixedRate,
+                                  // reversed,
+                                  false,
+                                ),
+                                builder: (context,
+                                    AsyncSnapshot<ExchangeResponse<Estimate>>
+                                        snapshot) {
+                                  if (snapshot.connectionState ==
+                                          ConnectionState.done &&
+                                      snapshot.hasData) {
+                                    final estimate = snapshot.data?.value;
+                                    if (estimate != null) {
+                                      Decimal rate = (estimate.estimatedAmount /
+                                              fromAmount!)
+                                          .toDecimal(
+                                              scaleOnInfinitePrecision: 12);
 
-                                  return Text(
-                                    "1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
-                                      value: rate,
-                                      locale: ref.watch(
-                                        localeServiceChangeNotifierProvider
-                                            .select((value) => value.locale),
+                                      return Text(
+                                        "1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
+                                          value: rate,
+                                          locale: ref.watch(
+                                            localeServiceChangeNotifierProvider
+                                                .select(
+                                                    (value) => value.locale),
+                                          ),
+                                          decimalPlaces: to!.toUpperCase() ==
+                                                  Coin.monero.ticker
+                                                      .toUpperCase()
+                                              ? Constants.decimalPlacesMonero
+                                              : Constants.decimalPlaces,
+                                        )} ${to!.toUpperCase()}",
+                                        style:
+                                            STextStyles.itemSubtitle12(context)
+                                                .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .textSubtitle1,
+                                        ),
+                                      );
+                                    } else {
+                                      Logging.instance.log(
+                                        "$runtimeType failed to fetch rate for SimpleSwap: ${snapshot.data}",
+                                        level: LogLevel.Warning,
+                                      );
+                                      return Text(
+                                        "Failed to fetch rate",
+                                        style:
+                                            STextStyles.itemSubtitle12(context)
+                                                .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .textSubtitle1,
+                                        ),
+                                      );
+                                    }
+                                  } else {
+                                    return AnimatedText(
+                                      stringsToLoopThrough: const [
+                                        "Loading",
+                                        "Loading.",
+                                        "Loading..",
+                                        "Loading...",
+                                      ],
+                                      style: STextStyles.itemSubtitle12(context)
+                                          .copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textSubtitle1,
                                       ),
-                                      decimalPlaces: to!.toUpperCase() ==
-                                              Coin.monero.ticker.toUpperCase()
-                                          ? Constants.decimalPlacesMonero
-                                          : Constants.decimalPlaces,
-                                    )} ${to!.toUpperCase()}",
-                                    style: STextStyles.itemSubtitle12(context)
-                                        .copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textSubtitle1,
-                                    ),
-                                  );
-                                } else {
-                                  Logging.instance.log(
-                                    "$runtimeType failed to fetch rate for SimpleSwap: ${snapshot.data}",
-                                    level: LogLevel.Warning,
-                                  );
-                                  return Text(
-                                    "Failed to fetch rate",
-                                    style: STextStyles.itemSubtitle12(context)
-                                        .copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textSubtitle1,
-                                    ),
-                                  );
-                                }
-                              } else {
-                                return AnimatedText(
-                                  stringsToLoopThrough: const [
-                                    "Loading",
-                                    "Loading.",
-                                    "Loading..",
-                                    "Loading...",
-                                  ],
-                                  style: STextStyles.itemSubtitle12(context)
-                                      .copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textSubtitle1,
-                                  ),
-                                );
-                              }
-                            },
-                          ),
-                        // if (!(from != null &&
-                        //     to != null &&
-                        //     (reversed
-                        //         ? toAmount != null && toAmount! > Decimal.zero
-                        //         : fromAmount != null &&
-                        //             fromAmount! > Decimal.zero)))
-                        if (!(from != null &&
-                            to != null &&
-                            toAmount != null &&
-                            toAmount! > Decimal.zero &&
-                            fromAmount != null &&
-                            fromAmount! > Decimal.zero))
-                          Text(
-                            "n/a",
-                            style: STextStyles.itemSubtitle12(context).copyWith(
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textSubtitle1,
-                            ),
-                          ),
-                      ],
-                    ),
+                                    );
+                                  }
+                                },
+                              ),
+                            // if (!(from != null &&
+                            //     to != null &&
+                            //     (reversed
+                            //         ? toAmount != null && toAmount! > Decimal.zero
+                            //         : fromAmount != null &&
+                            //             fromAmount! > Decimal.zero)))
+                            if (!(from != null &&
+                                to != null &&
+                                toAmount != null &&
+                                toAmount! > Decimal.zero &&
+                                fromAmount != null &&
+                                fromAmount! > Decimal.zero))
+                              Text(
+                                "n/a",
+                                style: STextStyles.itemSubtitle12(context)
+                                    .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textSubtitle1,
+                                ),
+                              ),
+                          ],
+                        ),
+                      ),
+                    ],
                   ),
-                ],
+                ),
               ),
             ),
           ),

From 96453e90541ce78a9c7a2f6e57f81554fc1839c0 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 16:06:03 -0600
Subject: [PATCH 334/426] missing asset declaration

---
 lib/utilities/assets.dart | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index c423ec491..6fbe61005 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -107,6 +107,7 @@ class _SVG {
   String get swap => "assets/svg/swap.svg";
   String get downloadFolder => "assets/svg/folder-down.svg";
   String get lock => "assets/svg/lock-keyhole.svg";
+  String get lockOpen => "assets/svg/lock-open.svg";
   String get network => "assets/svg/network-wired.svg";
   String get networkWired => "assets/svg/network-wired-2.svg";
   String get addressBook => "assets/svg/address-book.svg";

From 3ae38c582bdcd70c9ab68560ef832a6a7aad3fdf Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 16:06:29 -0600
Subject: [PATCH 335/426] desktop exchange form layout

---
 lib/pages/exchange_view/exchange_form.dart | 194 ++++++++++++++-------
 1 file changed, 134 insertions(+), 60 deletions(-)

diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index 7b04f90b3..5ece5aba8 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -27,9 +27,12 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_loading_overlay.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:tuple/tuple.dart';
 
@@ -54,6 +57,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
 
   late final TextEditingController _sendController;
   late final TextEditingController _receiveController;
+  final isDesktop = Util.isDesktop;
   final FocusNode _sendFocusNode = FocusNode();
   final FocusNode _receiveFocusNode = FocusNode();
 
@@ -960,8 +964,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
             color: Theme.of(context).extension<StackColors>()!.textDark3,
           ),
         ),
-        const SizedBox(
-          height: 4,
+        SizedBox(
+          height: isDesktop ? 10 : 4,
         ),
         TextFormField(
           style: STextStyles.smallMed14(context).copyWith(
@@ -970,6 +974,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
           focusNode: _sendFocusNode,
           controller: _sendController,
           textAlign: TextAlign.right,
+          enableSuggestions: false,
+          autocorrect: false,
           onTap: () {
             if (_sendController.text == "-") {
               _sendController.text = "";
@@ -1100,68 +1106,122 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
             ),
           ),
         ),
-        const SizedBox(
-          height: 4,
+
+        SizedBox(
+          height: isDesktop ? 10 : 4,
         ),
-        Stack(
+        if (ref
+                .watch(
+                    exchangeFormStateProvider.select((value) => value.warning))
+                .isNotEmpty &&
+            !ref.watch(
+                exchangeFormStateProvider.select((value) => value.reversed)))
+          Text(
+            ref.watch(
+                exchangeFormStateProvider.select((value) => value.warning)),
+            style: STextStyles.errorSmall(context),
+          ),
+        Row(
+          crossAxisAlignment: CrossAxisAlignment.end,
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
           children: [
-            Positioned.fill(
-              child: Align(
-                alignment: Alignment.bottomLeft,
-                child: Text(
-                  "You will receive",
-                  style: STextStyles.itemSubtitle(context).copyWith(
-                    color:
-                        Theme.of(context).extension<StackColors>()!.textDark3,
-                  ),
+            Text(
+              "You will receive",
+              style: STextStyles.itemSubtitle(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark3,
+              ),
+            ),
+            ConditionalParent(
+              condition: isDesktop,
+              builder: (child) => MouseRegion(
+                cursor: SystemMouseCursors.click,
+                child: RoundedContainer(
+                  padding: const EdgeInsets.all(6),
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .buttonBackSecondary,
+                  radiusMultiplier: 0.75,
+                  child: child,
                 ),
               ),
-            ),
-            Center(
-              child: Column(
-                children: [
-                  const SizedBox(
-                    height: 6,
+              child: GestureDetector(
+                onTap: () async {
+                  await _swap();
+                },
+                child: Padding(
+                  padding: const EdgeInsets.all(4),
+                  child: SvgPicture.asset(
+                    Assets.svg.swap,
+                    width: 20,
+                    height: 20,
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .accentColorDark,
                   ),
-                  GestureDetector(
-                    onTap: () async {
-                      await _swap();
-                    },
-                    child: Padding(
-                      padding: const EdgeInsets.all(4),
-                      child: SvgPicture.asset(
-                        Assets.svg.swap,
-                        width: 20,
-                        height: 20,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .accentColorDark,
-                      ),
-                    ),
-                  ),
-                  const SizedBox(
-                    height: 6,
-                  ),
-                ],
-              ),
-            ),
-            Positioned.fill(
-              child: Align(
-                alignment: ref.watch(exchangeFormStateProvider
-                        .select((value) => value.reversed))
-                    ? Alignment.bottomRight
-                    : Alignment.topRight,
-                child: Text(
-                  ref.watch(exchangeFormStateProvider
-                      .select((value) => value.warning)),
-                  style: STextStyles.errorSmall(context),
                 ),
               ),
             ),
           ],
         ),
-        const SizedBox(
-          height: 4,
+        // Stack(
+        //   children: [
+        //     Positioned.fill(
+        //       child: Align(
+        //         alignment: Alignment.bottomLeft,
+        //         child: Text(
+        //           "You will receive",
+        //           style: STextStyles.itemSubtitle(context).copyWith(
+        //             color:
+        //                 Theme.of(context).extension<StackColors>()!.textDark3,
+        //           ),
+        //         ),
+        //       ),
+        //     ),
+        //     Center(
+        //       child: Column(
+        //         children: [
+        //           const SizedBox(
+        //             height: 6,
+        //           ),
+        //           GestureDetector(
+        //             onTap: () async {
+        //               await _swap();
+        //             },
+        //             child: Padding(
+        //               padding: const EdgeInsets.all(4),
+        //               child: SvgPicture.asset(
+        //                 Assets.svg.swap,
+        //                 width: 20,
+        //                 height: 20,
+        //                 color: Theme.of(context)
+        //                     .extension<StackColors>()!
+        //                     .accentColorDark,
+        //               ),
+        //             ),
+        //           ),
+        //           const SizedBox(
+        //             height: 6,
+        //           ),
+        //         ],
+        //       ),
+        //     ),
+        //     Positioned.fill(
+        //       child: Align(
+        //         alignment: ref.watch(exchangeFormStateProvider
+        //                 .select((value) => value.reversed))
+        //             ? Alignment.bottomRight
+        //             : Alignment.topRight,
+        //         child: Text(
+        //           ref.watch(exchangeFormStateProvider
+        //               .select((value) => value.warning)),
+        //           style: STextStyles.errorSmall(context),
+        //         ),
+        //       ),
+        //     ),
+        //   ],
+        // ),
+        SizedBox(
+          height: isDesktop ? 10 : 4,
         ),
         TextFormField(
           style: STextStyles.smallMed14(context).copyWith(
@@ -1169,6 +1229,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
           ),
           focusNode: _receiveFocusNode,
           controller: _receiveController,
+          enableSuggestions: false,
+          autocorrect: false,
           readOnly: ref.watch(prefsChangeNotifierProvider
                       .select((value) => value.exchangeRateType)) ==
                   ExchangeRateType.estimated ||
@@ -1304,16 +1366,27 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
             ),
           ),
         ),
-        const SizedBox(
-          height: 12,
+        if (ref
+                .watch(
+                    exchangeFormStateProvider.select((value) => value.warning))
+                .isNotEmpty &&
+            ref.watch(
+                exchangeFormStateProvider.select((value) => value.reversed)))
+          Text(
+            ref.watch(
+                exchangeFormStateProvider.select((value) => value.warning)),
+            style: STextStyles.errorSmall(context),
+          ),
+        SizedBox(
+          height: isDesktop ? 20 : 12,
         ),
         RateTypeToggle(
           onChanged: onRateTypeChanged,
         ),
         if (ref.read(exchangeFormStateProvider).fromAmount != null &&
             ref.read(exchangeFormStateProvider).fromAmount != Decimal.zero)
-          const SizedBox(
-            height: 8,
+          SizedBox(
+            height: isDesktop ? 20 : 12,
           ),
         if (ref.read(exchangeFormStateProvider).fromAmount != null &&
             ref.read(exchangeFormStateProvider).fromAmount != Decimal.zero)
@@ -1328,10 +1401,11 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
             reversed: ref.watch(
                 exchangeFormStateProvider.select((value) => value.reversed)),
           ),
-        const SizedBox(
-          height: 12,
+        SizedBox(
+          height: isDesktop ? 20 : 12,
         ),
         PrimaryButton(
+          buttonHeight: isDesktop ? ButtonHeight.l : null,
           enabled: ref.watch(
               exchangeFormStateProvider.select((value) => value.canExchange)),
           onPressed: ref.watch(exchangeFormStateProvider

From 51cfc3f4dfce57fd22832173bdd0f2a3daddbdf0 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 18 Nov 2022 16:14:27 -0600
Subject: [PATCH 336/426] light colors accent blue fix?

---
 lib/utilities/theme/light_colors.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/utilities/theme/light_colors.dart b/lib/utilities/theme/light_colors.dart
index ea3a7cb92..896ae4e5e 100644
--- a/lib/utilities/theme/light_colors.dart
+++ b/lib/utilities/theme/light_colors.dart
@@ -11,7 +11,7 @@ class LightColors extends StackColorTheme {
   Color get overlay => const Color(0xFF111215);
 
   @override
-  Color get accentColorBlue => const Color(0xFF4C86E9);
+  Color get accentColorBlue => const Color(0xFF0052DF);
   @override
   Color get accentColorGreen => const Color(0xFF4CC0A0);
   @override

From 80802727381722405be4bee6a06941b076d9510d Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 18 Nov 2022 16:19:38 -0700
Subject: [PATCH 337/426] WIP: delete wallet

---
 .../wallet_view/desktop_wallet_view.dart      |   5 +
 .../sub_widgets/delete_wallet_button.dart     | 238 ++++++++++++++++++
 2 files changed, 243 insertions(+)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 85dde4aba..739dbe1a1 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -8,6 +8,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
 import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/my_wallet.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart';
@@ -412,6 +413,10 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                   WalletKeysButton(
                     walletId: walletId,
                   ),
+                  const SizedBox(
+                    width: 2,
+                  ),
+                  DeleteWalletButton(),
                   const SizedBox(
                     width: 12,
                   ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
new file mode 100644
index 000000000..f45367d0b
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
@@ -0,0 +1,238 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.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/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+
+class DeleteWalletButton extends ConsumerStatefulWidget {
+  const DeleteWalletButton({
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  ConsumerState<DeleteWalletButton> createState() => _DeleteWalletButton();
+}
+
+class _DeleteWalletButton extends ConsumerState<DeleteWalletButton> {
+  late final TextEditingController passwordController;
+  late final FocusNode passwordFocusNode;
+
+  bool hidePassword = true;
+  bool _continueEnabled = false;
+
+  Future<void> attentionDelete() async {
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) => DesktopDialog(
+        maxWidth: 580,
+        maxHeight: 400,
+        child: Column(
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.end,
+              children: const [
+                DesktopDialogCloseButton(),
+              ],
+            ),
+            Column(
+              children: [
+                Padding(
+                  padding:
+                      const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
+                  child: Text(
+                    "Attention!",
+                    style: STextStyles.desktopH2(context),
+                  ),
+                ),
+              ],
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  @override
+  void initState() {
+    passwordController = TextEditingController();
+    passwordFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    passwordController.dispose();
+    passwordFocusNode.dispose();
+
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return RawMaterialButton(
+      shape: RoundedRectangleBorder(
+        borderRadius: BorderRadius.circular(1000),
+      ),
+      onPressed: () {
+        showDialog(
+          barrierDismissible: true,
+          context: context,
+          builder: (context) => DesktopDialog(
+            maxHeight: 475,
+            child: Column(
+              children: [
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.end,
+                  children: const [
+                    DesktopDialogCloseButton(),
+                  ],
+                ),
+                Padding(
+                  padding:
+                      const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
+                  child: Column(
+                    children: [
+                      const SizedBox(height: 16),
+                      Text(
+                        "Delete wallet",
+                        style: STextStyles.desktopH2(context),
+                      ),
+                      const SizedBox(height: 16),
+                      Text(
+                        "Enter your password",
+                        style: STextStyles.desktopTextMedium(context).copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark3,
+                        ),
+                      ),
+                      const SizedBox(height: 24),
+                      ClipRRect(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                        child: TextField(
+                          key: const Key("desktopDeleteWalletPasswordFieldKey"),
+                          focusNode: passwordFocusNode,
+                          controller: passwordController,
+                          style: STextStyles.field(context),
+                          obscureText: hidePassword,
+                          enableSuggestions: false,
+                          autocorrect: false,
+                          decoration: standardInputDecoration(
+                            "Enter password",
+                            passwordFocusNode,
+                            context,
+                          ).copyWith(
+                            labelStyle: STextStyles.fieldLabel(context),
+                            suffixIcon: UnconstrainedBox(
+                              child: SizedBox(
+                                height: 70,
+                                child: Row(
+                                  children: [
+                                    const SizedBox(
+                                      width: 24,
+                                    ),
+                                    GestureDetector(
+                                      key: const Key(
+                                          "desktopDeleteWalletShowPasswordButtonKey"),
+                                      onTap: () async {
+                                        setState(() {
+                                          hidePassword = !hidePassword;
+                                        });
+                                      },
+                                      child: MouseRegion(
+                                        cursor: SystemMouseCursors.click,
+                                        child: SvgPicture.asset(
+                                          hidePassword
+                                              ? Assets.svg.eye
+                                              : Assets.svg.eyeSlash,
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .textDark3,
+                                          width: 24,
+                                          height: 24,
+                                        ),
+                                      ),
+                                    ),
+                                    const SizedBox(
+                                      width: 12,
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            ),
+                          ),
+                          onChanged: (newValue) {
+                            setState(() {
+                              _continueEnabled =
+                                  passwordController.text.isNotEmpty;
+                            });
+                          },
+                        ),
+                      ),
+                      const SizedBox(height: 50),
+                      Row(
+                        mainAxisAlignment: MainAxisAlignment.center,
+                        children: [
+                          SecondaryButton(
+                            width: 250,
+                            buttonHeight: ButtonHeight.xl,
+                            label: "Cancel",
+                            onPressed: () {
+                              Navigator.of(context).pop();
+                            },
+                          ),
+                          const SizedBox(width: 16),
+                          PrimaryButton(
+                            width: 250,
+                            buttonHeight: ButtonHeight.xl,
+                            enabled: _continueEnabled,
+                            label: "Continue",
+                            onPressed: () {
+                              Navigator.of(context).pop();
+
+                              attentionDelete();
+                            },
+                          ),
+                        ],
+                      )
+                    ],
+                  ),
+                ),
+              ],
+            ),
+          ),
+        );
+      },
+      child: Padding(
+        padding: const EdgeInsets.symmetric(
+          vertical: 19,
+          horizontal: 32,
+        ),
+        child: Row(
+          children: [
+            SvgPicture.asset(
+              Assets.svg.ellipsis,
+              width: 20,
+              height: 20,
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .buttonTextSecondary,
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}

From 92da601fb80350706b412bc72bc2f952120446a0 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Fri, 18 Nov 2022 17:43:35 -0700
Subject: [PATCH 338/426] WIP: delete wallete Attention dialog

---
 .../sub_widgets/delete_wallet_button.dart     | 66 ++++++++++++++++---
 1 file changed, 56 insertions(+), 10 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
index f45367d0b..96930c044 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
@@ -9,6 +9,7 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 
 class DeleteWalletButton extends ConsumerStatefulWidget {
@@ -34,7 +35,7 @@ class _DeleteWalletButton extends ConsumerState<DeleteWalletButton> {
       barrierDismissible: true,
       builder: (context) => DesktopDialog(
         maxWidth: 580,
-        maxHeight: 400,
+        maxHeight: 530,
         child: Column(
           children: [
             Row(
@@ -43,17 +44,62 @@ class _DeleteWalletButton extends ConsumerState<DeleteWalletButton> {
                 DesktopDialogCloseButton(),
               ],
             ),
-            Column(
-              children: [
-                Padding(
-                  padding:
-                      const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
-                  child: Text(
+            Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
+              child: Column(
+                children: [
+                  Text(
                     "Attention!",
                     style: STextStyles.desktopH2(context),
                   ),
-                ),
-              ],
+                  const SizedBox(
+                    height: 16,
+                  ),
+                  RoundedContainer(
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .snackBarBackError,
+                    child: Padding(
+                      padding: const EdgeInsets.all(10.0),
+                      child: Text(
+                        "You are going to permanently delete you wallet.\n\nIf you delete your wallet, "
+                        "the only way you can have access to your funds is by using your backup key."
+                        "\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet."
+                        "\n\nPLEASE SAVE YOUR BACKUP KEY.",
+                        style: STextStyles.desktopTextExtraExtraSmall(context)
+                            .copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark3,
+                        ),
+                      ),
+                    ),
+                  ),
+                  const SizedBox(height: 30),
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      SecondaryButton(
+                        width: 250,
+                        buttonHeight: ButtonHeight.xl,
+                        label: "Cancel",
+                        onPressed: () {
+                          Navigator.of(context).pop();
+                        },
+                      ),
+                      const SizedBox(width: 16),
+                      PrimaryButton(
+                        width: 250,
+                        buttonHeight: ButtonHeight.xl,
+                        label: "View Backup Key",
+                        onPressed: () {
+                          Navigator.of(context).pop();
+                        },
+                      ),
+                    ],
+                  )
+                ],
+              ),
             ),
           ],
         ),
@@ -84,7 +130,7 @@ class _DeleteWalletButton extends ConsumerState<DeleteWalletButton> {
         borderRadius: BorderRadius.circular(1000),
       ),
       onPressed: () {
-        showDialog(
+        showDialog<dynamic>(
           barrierDismissible: true,
           context: context,
           builder: (context) => DesktopDialog(

From 5f1a485ed5b4a7f2db44bee6a06172774fafe5a6 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Sat, 19 Nov 2022 11:00:15 -0700
Subject: [PATCH 339/426] WIP: delete wallete stateful widget + attention
 warning dialog

---
 .../wallet_view/desktop_wallet_view.dart      |   4 +-
 .../sub_widgets/delete_wallet_button.dart     | 253 ++-------------
 .../desktop_delete_wallet_dialog.dart         | 299 ++++++++++++++++++
 lib/route_generator.dart                      |  23 ++
 4 files changed, 350 insertions(+), 229 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 739dbe1a1..5996597b5 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -416,7 +416,9 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
                   const SizedBox(
                     width: 2,
                   ),
-                  DeleteWalletButton(),
+                  DeleteWalletButton(
+                    walletId: walletId,
+                  ),
                   const SizedBox(
                     width: 12,
                   ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
index 96930c044..54f991c37 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
@@ -1,128 +1,37 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.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/widgets/desktop/desktop_dialog.dart';
-import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
-import 'package:stackwallet/widgets/desktop/primary_button.dart';
-import 'package:stackwallet/widgets/desktop/secondary_button.dart';
-import 'package:stackwallet/widgets/rounded_container.dart';
-import 'package:stackwallet/widgets/stack_text_field.dart';
+
+import 'desktop_delete_wallet_dialog.dart';
 
 class DeleteWalletButton extends ConsumerStatefulWidget {
   const DeleteWalletButton({
     Key? key,
+    required this.walletId,
   }) : super(key: key);
 
+  final String walletId;
+
   @override
   ConsumerState<DeleteWalletButton> createState() => _DeleteWalletButton();
 }
 
 class _DeleteWalletButton extends ConsumerState<DeleteWalletButton> {
-  late final TextEditingController passwordController;
-  late final FocusNode passwordFocusNode;
-
-  bool hidePassword = true;
-  bool _continueEnabled = false;
-
-  Future<void> attentionDelete() async {
-    await showDialog<dynamic>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: true,
-      builder: (context) => DesktopDialog(
-        maxWidth: 580,
-        maxHeight: 530,
-        child: Column(
-          children: [
-            Row(
-              mainAxisAlignment: MainAxisAlignment.end,
-              children: const [
-                DesktopDialogCloseButton(),
-              ],
-            ),
-            Padding(
-              padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
-              child: Column(
-                children: [
-                  Text(
-                    "Attention!",
-                    style: STextStyles.desktopH2(context),
-                  ),
-                  const SizedBox(
-                    height: 16,
-                  ),
-                  RoundedContainer(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .snackBarBackError,
-                    child: Padding(
-                      padding: const EdgeInsets.all(10.0),
-                      child: Text(
-                        "You are going to permanently delete you wallet.\n\nIf you delete your wallet, "
-                        "the only way you can have access to your funds is by using your backup key."
-                        "\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet."
-                        "\n\nPLEASE SAVE YOUR BACKUP KEY.",
-                        style: STextStyles.desktopTextExtraExtraSmall(context)
-                            .copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .textDark3,
-                        ),
-                      ),
-                    ),
-                  ),
-                  const SizedBox(height: 30),
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.center,
-                    children: [
-                      SecondaryButton(
-                        width: 250,
-                        buttonHeight: ButtonHeight.xl,
-                        label: "Cancel",
-                        onPressed: () {
-                          Navigator.of(context).pop();
-                        },
-                      ),
-                      const SizedBox(width: 16),
-                      PrimaryButton(
-                        width: 250,
-                        buttonHeight: ButtonHeight.xl,
-                        label: "View Backup Key",
-                        onPressed: () {
-                          Navigator.of(context).pop();
-                        },
-                      ),
-                    ],
-                  )
-                ],
-              ),
-            ),
-          ],
-        ),
-      ),
-    );
-  }
+  late final String walletId;
 
   @override
   void initState() {
-    passwordController = TextEditingController();
-    passwordFocusNode = FocusNode();
+    walletId = widget.walletId;
+    final managerProvider =
+        ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
 
     super.initState();
   }
 
-  @override
-  void dispose() {
-    passwordController.dispose();
-    passwordFocusNode.dispose();
-
-    super.dispose();
-  }
-
   @override
   Widget build(BuildContext context) {
     return RawMaterialButton(
@@ -130,134 +39,22 @@ class _DeleteWalletButton extends ConsumerState<DeleteWalletButton> {
         borderRadius: BorderRadius.circular(1000),
       ),
       onPressed: () {
-        showDialog<dynamic>(
-          barrierDismissible: true,
+        showDialog<void>(
           context: context,
-          builder: (context) => DesktopDialog(
-            maxHeight: 475,
-            child: Column(
-              children: [
-                Row(
-                  mainAxisAlignment: MainAxisAlignment.end,
-                  children: const [
-                    DesktopDialogCloseButton(),
-                  ],
-                ),
-                Padding(
-                  padding:
-                      const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
-                  child: Column(
-                    children: [
-                      const SizedBox(height: 16),
-                      Text(
-                        "Delete wallet",
-                        style: STextStyles.desktopH2(context),
-                      ),
-                      const SizedBox(height: 16),
-                      Text(
-                        "Enter your password",
-                        style: STextStyles.desktopTextMedium(context).copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .textDark3,
-                        ),
-                      ),
-                      const SizedBox(height: 24),
-                      ClipRRect(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
-                        ),
-                        child: TextField(
-                          key: const Key("desktopDeleteWalletPasswordFieldKey"),
-                          focusNode: passwordFocusNode,
-                          controller: passwordController,
-                          style: STextStyles.field(context),
-                          obscureText: hidePassword,
-                          enableSuggestions: false,
-                          autocorrect: false,
-                          decoration: standardInputDecoration(
-                            "Enter password",
-                            passwordFocusNode,
-                            context,
-                          ).copyWith(
-                            labelStyle: STextStyles.fieldLabel(context),
-                            suffixIcon: UnconstrainedBox(
-                              child: SizedBox(
-                                height: 70,
-                                child: Row(
-                                  children: [
-                                    const SizedBox(
-                                      width: 24,
-                                    ),
-                                    GestureDetector(
-                                      key: const Key(
-                                          "desktopDeleteWalletShowPasswordButtonKey"),
-                                      onTap: () async {
-                                        setState(() {
-                                          hidePassword = !hidePassword;
-                                        });
-                                      },
-                                      child: MouseRegion(
-                                        cursor: SystemMouseCursors.click,
-                                        child: SvgPicture.asset(
-                                          hidePassword
-                                              ? Assets.svg.eye
-                                              : Assets.svg.eyeSlash,
-                                          color: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .textDark3,
-                                          width: 24,
-                                          height: 24,
-                                        ),
-                                      ),
-                                    ),
-                                    const SizedBox(
-                                      width: 12,
-                                    ),
-                                  ],
-                                ),
-                              ),
-                            ),
-                          ),
-                          onChanged: (newValue) {
-                            setState(() {
-                              _continueEnabled =
-                                  passwordController.text.isNotEmpty;
-                            });
-                          },
-                        ),
-                      ),
-                      const SizedBox(height: 50),
-                      Row(
-                        mainAxisAlignment: MainAxisAlignment.center,
-                        children: [
-                          SecondaryButton(
-                            width: 250,
-                            buttonHeight: ButtonHeight.xl,
-                            label: "Cancel",
-                            onPressed: () {
-                              Navigator.of(context).pop();
-                            },
-                          ),
-                          const SizedBox(width: 16),
-                          PrimaryButton(
-                            width: 250,
-                            buttonHeight: ButtonHeight.xl,
-                            enabled: _continueEnabled,
-                            label: "Continue",
-                            onPressed: () {
-                              Navigator.of(context).pop();
-
-                              attentionDelete();
-                            },
-                          ),
-                        ],
-                      )
-                    ],
+          barrierDismissible: false,
+          builder: (context) => Navigator(
+            initialRoute: DesktopDeleteWalletDialog.routeName,
+            onGenerateRoute: RouteGenerator.generateRoute,
+            onGenerateInitialRoutes: (_, __) {
+              return [
+                RouteGenerator.generateRoute(
+                  RouteSettings(
+                    name: DesktopDeleteWalletDialog.routeName,
+                    arguments: walletId,
                   ),
-                ),
-              ],
-            ),
+                )
+              ];
+            },
           ),
         );
       },
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
new file mode 100644
index 000000000..e2ab4fa86
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
@@ -0,0 +1,299 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/utilities/assets.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/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+
+import '../../../../../providers/desktop/storage_crypto_handler_provider.dart';
+import '../../../../../providers/global/wallets_provider.dart';
+
+class DesktopDeleteWalletDialog extends ConsumerStatefulWidget {
+  const DesktopDeleteWalletDialog({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  static const String routeName = "/desktopDeleteWalletDialog";
+
+  @override
+  ConsumerState<DesktopDeleteWalletDialog> createState() =>
+      _DesktopDeleteWalletDialog();
+}
+
+class _DesktopDeleteWalletDialog
+    extends ConsumerState<DesktopDeleteWalletDialog> {
+  late final TextEditingController passwordController;
+  late final FocusNode passwordFocusNode;
+
+  bool hidePassword = true;
+  bool _continueEnabled = false;
+
+  Future<void> attentionDelete() async {
+    await showDialog<dynamic>(
+      context: context,
+      useSafeArea: false,
+      barrierDismissible: true,
+      builder: (context) => DesktopDialog(
+        maxWidth: 610,
+        maxHeight: 530,
+        child: Column(
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.end,
+              children: [
+                DesktopDialogCloseButton(
+                  onPressedOverride: () {
+                    int count = 0;
+                    Navigator.of(context).popUntil((_) => count++ >= 2);
+                  },
+                ),
+              ],
+            ),
+            Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
+              child: Column(
+                children: [
+                  Text(
+                    "Attention!",
+                    style: STextStyles.desktopH2(context),
+                  ),
+                  const SizedBox(
+                    height: 16,
+                  ),
+                  RoundedContainer(
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .snackBarBackError,
+                    child: Padding(
+                      padding: const EdgeInsets.all(10.0),
+                      child: Text(
+                        "You are going to permanently delete you wallet.\n\nIf you delete your wallet, "
+                        "the only way you can have access to your funds is by using your backup key."
+                        "\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet."
+                        "\n\nPLEASE SAVE YOUR BACKUP KEY.",
+                        style: STextStyles.desktopTextExtraExtraSmall(context)
+                            .copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark3,
+                        ),
+                      ),
+                    ),
+                  ),
+                  const SizedBox(height: 30),
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      SecondaryButton(
+                        width: 250,
+                        buttonHeight: ButtonHeight.xl,
+                        label: "Cancel",
+                        onPressed: () {
+                          int count = 0;
+                          Navigator.of(context).popUntil((_) => count++ >= 2);
+                        },
+                      ),
+                      const SizedBox(width: 16),
+                      PrimaryButton(
+                        width: 250,
+                        buttonHeight: ButtonHeight.xl,
+                        label: "View Backup Key",
+                        onPressed: () {},
+                      ),
+                    ],
+                  )
+                ],
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  @override
+  void initState() {
+    passwordController = TextEditingController();
+    passwordFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    passwordController.dispose();
+    passwordFocusNode.dispose();
+
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 580,
+      maxHeight: double.infinity,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.end,
+            children: [
+              DesktopDialogCloseButton(
+                onPressedOverride: Navigator.of(
+                  context,
+                  rootNavigator: true,
+                ).pop,
+              ),
+            ],
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
+            child: Column(
+              children: [
+                const SizedBox(height: 16),
+                Text(
+                  "Delete wallet",
+                  style: STextStyles.desktopH2(context),
+                ),
+                const SizedBox(height: 16),
+                Text(
+                  "Enter your password",
+                  style: STextStyles.desktopTextMedium(context).copyWith(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.textDark3,
+                  ),
+                ),
+                const SizedBox(height: 24),
+                ClipRRect(
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
+                  child: TextField(
+                    key: const Key("desktopDeleteWalletPasswordFieldKey"),
+                    focusNode: passwordFocusNode,
+                    controller: passwordController,
+                    style: STextStyles.field(context),
+                    obscureText: hidePassword,
+                    enableSuggestions: false,
+                    autocorrect: false,
+                    decoration: standardInputDecoration(
+                      "Enter password",
+                      passwordFocusNode,
+                      context,
+                    ).copyWith(
+                      labelStyle: STextStyles.fieldLabel(context),
+                      suffixIcon: UnconstrainedBox(
+                        child: SizedBox(
+                          height: 70,
+                          child: Row(
+                            children: [
+                              const SizedBox(
+                                width: 24,
+                              ),
+                              GestureDetector(
+                                key: const Key(
+                                    "desktopDeleteWalletShowPasswordButtonKey"),
+                                onTap: () async {
+                                  setState(() {
+                                    hidePassword = !hidePassword;
+                                  });
+                                },
+                                child: MouseRegion(
+                                  cursor: SystemMouseCursors.click,
+                                  child: SvgPicture.asset(
+                                    hidePassword
+                                        ? Assets.svg.eye
+                                        : Assets.svg.eyeSlash,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark3,
+                                    width: 24,
+                                    height: 24,
+                                  ),
+                                ),
+                              ),
+                              const SizedBox(
+                                width: 12,
+                              ),
+                            ],
+                          ),
+                        ),
+                      ),
+                    ),
+                    onChanged: (newValue) {
+                      setState(() {
+                        _continueEnabled = passwordController.text.isNotEmpty;
+                      });
+                    },
+                  ),
+                ),
+                const SizedBox(height: 50),
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  children: [
+                    SecondaryButton(
+                      width: 250,
+                      buttonHeight: ButtonHeight.xl,
+                      label: "Cancel",
+                      onPressed: Navigator.of(
+                        context,
+                        rootNavigator: true,
+                      ).pop,
+                    ),
+                    const SizedBox(width: 16),
+                    PrimaryButton(
+                      width: 250,
+                      buttonHeight: ButtonHeight.xl,
+                      enabled: _continueEnabled,
+                      label: "Continue",
+                      onPressed: _continueEnabled
+                          ? () async {
+                              final verified = await ref
+                                  .read(storageCryptoHandlerProvider)
+                                  .verifyPassphrase(passwordController.text);
+
+                              if (verified) {
+                                final words = await ref
+                                    .read(walletsChangeNotifierProvider)
+                                    .getManager(widget.walletId)
+                                    .mnemonic;
+
+                                if (mounted) {
+                                  Navigator.of(context).pop();
+
+                                  attentionDelete();
+                                }
+                              } else {
+                                unawaited(
+                                  showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "Invalid passphrase!",
+                                    context: context,
+                                  ),
+                                );
+                              }
+                            }
+                          : null,
+                    ),
+                  ],
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 8ccc923bc..77b5e7d11 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -92,6 +92,7 @@ import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
 import 'package:stackwallet/pages_desktop_specific/home/notifications/desktop_notifications_view.dart';
@@ -1170,6 +1171,28 @@ class RouteGenerator {
         }
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
+      case DesktopDeleteWalletDialog.routeName:
+        if (args is String) {
+          return FadePageRoute(
+            DesktopDeleteWalletDialog(
+              walletId: args,
+            ),
+            RouteSettings(
+              name: settings.name,
+            ),
+          );
+          // return getRoute(
+          //   shouldUseMaterialRoute: useMaterialPageRoute,
+          //   builder: (_) => WalletKeysDesktopPopup(
+          //     words: args,
+          //   ),
+          //   settings: RouteSettings(
+          //     name: settings.name,
+          //   ),
+          // );
+        }
+        return _routeError("${settings.name} invalid args: ${args.toString()}");
+
       case QRCodeDesktopPopupContent.routeName:
         if (args is String) {
           return FadePageRoute(

From a8faa7b8e7b851c0e919b0678f9d066fc237120a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 19 Nov 2022 09:20:43 -0600
Subject: [PATCH 340/426] exchange form desktop routing and dialogs

---
 lib/pages/exchange_view/exchange_form.dart    | 223 +++++++++++++-----
 .../desktop/simple_desktop_dialog.dart        |  65 +++++
 2 files changed, 229 insertions(+), 59 deletions(-)
 create mode 100644 lib/widgets/desktop/simple_desktop_dialog.dart

diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index 5ece5aba8..a6d736228 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -30,7 +30,11 @@ 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/custom_loading_overlay.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/desktop/simple_desktop_dialog.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -139,14 +143,27 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
                     .read(exchangeFormStateProvider)
                     .updateMarket(market, true);
               } catch (e) {
-                unawaited(showDialog<dynamic>(
-                  context: context,
-                  builder: (_) => const StackDialog(
-                    title: "Fixed rate market error",
-                    message:
-                        "Could not find the specified fixed rate trade pair",
+                unawaited(
+                  showDialog<dynamic>(
+                    context: context,
+                    builder: (_) {
+                      if (isDesktop) {
+                        return const SimpleDesktopDialog(
+                          title: "Fixed rate market error",
+                          message:
+                              "Could not find the specified fixed rate trade pair",
+                        );
+                      } else {
+                        return const StackDialog(
+                          title: "Fixed rate market error",
+                          message:
+                              "Could not find the specified fixed rate trade pair",
+                        );
+                      }
+                    },
                   ),
-                ));
+                );
+
                 return;
               }
             },
@@ -229,14 +246,26 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
                     .read(exchangeFormStateProvider)
                     .updateMarket(market, true);
               } catch (e) {
-                unawaited(showDialog<dynamic>(
-                  context: context,
-                  builder: (_) => const StackDialog(
-                    title: "Fixed rate market error",
-                    message:
-                        "Could not find the specified fixed rate trade pair",
+                unawaited(
+                  showDialog<dynamic>(
+                    context: context,
+                    builder: (_) {
+                      if (isDesktop) {
+                        return const SimpleDesktopDialog(
+                          title: "Fixed rate market error",
+                          message:
+                              "Could not find the specified fixed rate trade pair",
+                        );
+                      } else {
+                        return const StackDialog(
+                          title: "Fixed rate market error",
+                          message:
+                              "Could not find the specified fixed rate trade pair",
+                        );
+                      }
+                    },
                   ),
-                ));
+                );
                 return;
               }
             },
@@ -324,7 +353,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
       await ref.read(exchangeFormStateProvider).swap();
     }
     if (mounted) {
-      Navigator.of(context).pop();
+      Navigator.of(context, rootNavigator: isDesktop).pop();
     }
     _swapLock = false;
   }
@@ -567,14 +596,14 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
                       ? "-"
                       : ref.read(exchangeFormStateProvider).toAmountString;
               if (mounted) {
-                Navigator.of(context).pop();
+                Navigator.of(context, rootNavigator: isDesktop).pop();
               }
               return;
             }
           }
         }
         if (mounted) {
-          Navigator.of(context).pop();
+          Navigator.of(context, rootNavigator: isDesktop).pop();
         }
         if (!(fromTicker == "-" || toTicker == "-")) {
           unawaited(
@@ -620,7 +649,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
                     true,
                   );
               if (mounted) {
-                Navigator.of(context).pop();
+                Navigator.of(context, rootNavigator: isDesktop).pop();
               }
               return;
             case SimpleSwapExchange.exchangeName:
@@ -657,7 +686,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
                           ? "-"
                           : ref.read(exchangeFormStateProvider).toAmountString;
                   if (mounted) {
-                    Navigator.of(context).pop();
+                    Navigator.of(context, rootNavigator: isDesktop).pop();
                   }
                   return;
                 }
@@ -669,7 +698,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
           }
         }
         if (mounted) {
-          Navigator.of(context).pop();
+          Navigator.of(context, rootNavigator: isDesktop).pop();
         }
         unawaited(
           showFloatingFlushBar(
@@ -722,15 +751,27 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
         }
 
         if (!isAvailable) {
-          unawaited(showDialog<dynamic>(
-            context: context,
-            barrierDismissible: true,
-            builder: (_) => StackDialog(
-              title: "Selected trade pair unavailable",
-              message:
-                  "The $fromTicker - $toTicker market is currently disabled for estimated/floating rate trades",
+          unawaited(
+            showDialog<dynamic>(
+              context: context,
+              barrierDismissible: true,
+              builder: (_) {
+                if (isDesktop) {
+                  return SimpleDesktopDialog(
+                    title: "Selected trade pair unavailable",
+                    message:
+                        "The $fromTicker - $toTicker market is currently disabled for estimated/floating rate trades",
+                  );
+                } else {
+                  return StackDialog(
+                    title: "Selected trade pair unavailable",
+                    message:
+                        "The $fromTicker - $toTicker market is currently disabled for estimated/floating rate trades",
+                  );
+                }
+              },
             ),
-          ));
+          );
           return;
         }
         rate =
@@ -744,37 +785,101 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
           shouldCancel = await showDialog<bool?>(
             context: context,
             barrierDismissible: true,
-            builder: (_) => StackDialog(
-              title: "Failed to update trade estimate",
-              message:
-                  "${estimate.warningMessage!}\n\nDo you want to attempt trade anyways?",
-              leftButton: TextButton(
-                style: Theme.of(context)
-                    .extension<StackColors>()!
-                    .getSecondaryEnabledButtonColor(context),
-                child: Text(
-                  "Cancel",
-                  style: STextStyles.itemSubtitle12(context),
-                ),
-                onPressed: () {
-                  // notify return to cancel
-                  Navigator.of(context).pop(true);
-                },
-              ),
-              rightButton: TextButton(
-                style: Theme.of(context)
-                    .extension<StackColors>()!
-                    .getPrimaryEnabledButtonColor(context),
-                child: Text(
-                  "Attempt",
-                  style: STextStyles.button(context),
-                ),
-                onPressed: () {
-                  // continue and try to attempt trade
-                  Navigator.of(context).pop(false);
-                },
-              ),
-            ),
+            builder: (_) {
+              if (isDesktop) {
+                return DesktopDialog(
+                  maxWidth: 500,
+                  maxHeight: 300,
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Text(
+                            "Failed to update trade estimate",
+                            style: STextStyles.desktopH3(context),
+                          ),
+                          const DesktopDialogCloseButton(),
+                        ],
+                      ),
+                      const Spacer(),
+                      Text(
+                        estimate.warningMessage!,
+                        style: STextStyles.desktopTextSmall(context),
+                      ),
+                      const Spacer(),
+                      Text(
+                        "Do you want to attempt trade anyways?",
+                        style: STextStyles.desktopTextSmall(context),
+                      ),
+                      const Spacer(
+                        flex: 2,
+                      ),
+                      Row(
+                        children: [
+                          Expanded(
+                            child: SecondaryButton(
+                              label: "Cancel",
+                              buttonHeight: ButtonHeight.l,
+                              onPressed: () => Navigator.of(
+                                context,
+                                rootNavigator: true,
+                              ).pop(true),
+                            ),
+                          ),
+                          const SizedBox(
+                            width: 16,
+                          ),
+                          Expanded(
+                            child: PrimaryButton(
+                              label: "Attempt",
+                              buttonHeight: ButtonHeight.l,
+                              onPressed: () => Navigator.of(
+                                context,
+                                rootNavigator: true,
+                              ).pop(false),
+                            ),
+                          ),
+                        ],
+                      )
+                    ],
+                  ),
+                );
+              } else {
+                return StackDialog(
+                  title: "Failed to update trade estimate",
+                  message:
+                      "${estimate.warningMessage!}\n\nDo you want to attempt trade anyways?",
+                  leftButton: TextButton(
+                    style: Theme.of(context)
+                        .extension<StackColors>()!
+                        .getSecondaryEnabledButtonColor(context),
+                    child: Text(
+                      "Cancel",
+                      style: STextStyles.itemSubtitle12(context),
+                    ),
+                    onPressed: () {
+                      // notify return to cancel
+                      Navigator.of(context).pop(true);
+                    },
+                  ),
+                  rightButton: TextButton(
+                    style: Theme.of(context)
+                        .extension<StackColors>()!
+                        .getPrimaryEnabledButtonColor(context),
+                    child: Text(
+                      "Attempt",
+                      style: STextStyles.button(context),
+                    ),
+                    onPressed: () {
+                      // continue and try to attempt trade
+                      Navigator.of(context).pop(false);
+                    },
+                  ),
+                );
+              }
+            },
           );
         }
 
diff --git a/lib/widgets/desktop/simple_desktop_dialog.dart b/lib/widgets/desktop/simple_desktop_dialog.dart
new file mode 100644
index 000000000..cd066c221
--- /dev/null
+++ b/lib/widgets/desktop/simple_desktop_dialog.dart
@@ -0,0 +1,65 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+
+class SimpleDesktopDialog extends StatelessWidget {
+  const SimpleDesktopDialog({
+    Key? key,
+    required this.title,
+    required this.message,
+  }) : super(key: key);
+
+  final String title;
+  final String message;
+
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 500,
+      maxHeight: 300,
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Text(
+                title,
+                style: STextStyles.desktopH3(context),
+              ),
+              const DesktopDialogCloseButton(),
+            ],
+          ),
+          const Spacer(),
+          Text(
+            message,
+            style: STextStyles.desktopTextSmall(context),
+          ),
+          const Spacer(
+            flex: 2,
+          ),
+          Row(
+            children: [
+              const Spacer(),
+              const SizedBox(
+                width: 16,
+              ),
+              Expanded(
+                child: PrimaryButton(
+                  label: "Ok",
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: Navigator.of(
+                    context,
+                    rootNavigator: true,
+                  ).pop,
+                ),
+              ),
+            ],
+          )
+        ],
+      ),
+    );
+  }
+}

From b2ff99be19400374c71b9e2fbe6be4eb08bc8147 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 19 Nov 2022 09:20:58 -0600
Subject: [PATCH 341/426] login loading indicator size

---
 lib/pages_desktop_specific/desktop_login_view.dart | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index f60ce2240..f865fad47 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -49,8 +49,15 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
       unawaited(
         showDialog(
           context: context,
-          builder: (context) => const LoadingIndicator(
-            width: 200,
+          builder: (context) => Column(
+            mainAxisAlignment: MainAxisAlignment.center,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: const [
+              LoadingIndicator(
+                width: 200,
+                height: 200,
+              ),
+            ],
           ),
         ),
       );

From cc4dc9e3c71d67745fd0294e38dd74ddd709f413 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 19 Nov 2022 09:24:32 -0600
Subject: [PATCH 342/426] exchange rate type toggle mouse regions

---
 .../sub_widgets/rate_type_toggle.dart         | 287 ++++++++++--------
 1 file changed, 153 insertions(+), 134 deletions(-)

diff --git a/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart b/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart
index 9697710e8..31ee01ce2 100644
--- a/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart
+++ b/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart
@@ -8,6 +8,7 @@ import 'package:stackwallet/utilities/assets.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 RateTypeToggle extends ConsumerWidget {
@@ -35,145 +36,163 @@ class RateTypeToggle extends ConsumerWidget {
       child: Row(
         children: [
           Expanded(
-            child: GestureDetector(
-              onTap: () {
-                if (!estimated) {
-                  ref.read(prefsChangeNotifierProvider).exchangeRateType =
-                      ExchangeRateType.estimated;
-                  onChanged?.call(ExchangeRateType.estimated);
-                }
-              },
-              child: RoundedContainer(
-                padding: isDesktop
-                    ? const EdgeInsets.all(17)
-                    : const EdgeInsets.all(0),
-                color: estimated
-                    ? Theme.of(context)
-                        .extension<StackColors>()!
-                        .textFieldDefaultBG
-                    : Colors.transparent,
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.center,
-                  children: [
-                    SvgPicture.asset(
-                      Assets.svg.lockOpen,
-                      width: 12,
-                      height: 14,
-                      color: isDesktop
-                          ? estimated
-                              ? Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .accentColorBlue
-                              : Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .buttonTextSecondary
-                          : estimated
-                              ? Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textDark
-                              : Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textSubtitle1,
-                    ),
-                    const SizedBox(
-                      width: 5,
-                    ),
-                    Text(
-                      "Estimate rate",
-                      style: isDesktop
-                          ? STextStyles.desktopTextExtraExtraSmall(context)
-                              .copyWith(
-                              color: estimated
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .accentColorBlue
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .buttonTextSecondary,
-                            )
-                          : STextStyles.smallMed12(context).copyWith(
-                              color: estimated
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textSubtitle1,
-                            ),
-                    ),
-                  ],
+            child: ConditionalParent(
+              condition: isDesktop,
+              builder: (child) => MouseRegion(
+                cursor: estimated
+                    ? SystemMouseCursors.basic
+                    : SystemMouseCursors.click,
+                child: child,
+              ),
+              child: GestureDetector(
+                onTap: () {
+                  if (!estimated) {
+                    ref.read(prefsChangeNotifierProvider).exchangeRateType =
+                        ExchangeRateType.estimated;
+                    onChanged?.call(ExchangeRateType.estimated);
+                  }
+                },
+                child: RoundedContainer(
+                  padding: isDesktop
+                      ? const EdgeInsets.all(17)
+                      : const EdgeInsets.all(0),
+                  color: estimated
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldDefaultBG
+                      : Colors.transparent,
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      SvgPicture.asset(
+                        Assets.svg.lockOpen,
+                        width: 12,
+                        height: 14,
+                        color: isDesktop
+                            ? estimated
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorBlue
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .buttonTextSecondary
+                            : estimated
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textSubtitle1,
+                      ),
+                      const SizedBox(
+                        width: 5,
+                      ),
+                      Text(
+                        "Estimate rate",
+                        style: isDesktop
+                            ? STextStyles.desktopTextExtraExtraSmall(context)
+                                .copyWith(
+                                color: estimated
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorBlue
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .buttonTextSecondary,
+                              )
+                            : STextStyles.smallMed12(context).copyWith(
+                                color: estimated
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textSubtitle1,
+                              ),
+                      ),
+                    ],
+                  ),
                 ),
               ),
             ),
           ),
           Expanded(
-            child: GestureDetector(
-              onTap: () {
-                if (estimated) {
-                  ref.read(prefsChangeNotifierProvider).exchangeRateType =
-                      ExchangeRateType.fixed;
-                  onChanged?.call(ExchangeRateType.fixed);
-                }
-              },
-              child: RoundedContainer(
-                padding: isDesktop
-                    ? const EdgeInsets.all(17)
-                    : const EdgeInsets.all(0),
-                color: !estimated
-                    ? Theme.of(context)
-                        .extension<StackColors>()!
-                        .textFieldDefaultBG
-                    : Colors.transparent,
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.center,
-                  children: [
-                    SvgPicture.asset(
-                      Assets.svg.lock,
-                      width: 12,
-                      height: 14,
-                      color: isDesktop
-                          ? !estimated
-                              ? Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .accentColorBlue
-                              : Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .buttonTextSecondary
-                          : !estimated
-                              ? Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textDark
-                              : Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textSubtitle1,
-                    ),
-                    const SizedBox(
-                      width: 5,
-                    ),
-                    Text(
-                      "Fixed rate",
-                      style: isDesktop
-                          ? STextStyles.desktopTextExtraExtraSmall(context)
-                              .copyWith(
-                              color: !estimated
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .accentColorBlue
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .buttonTextSecondary,
-                            )
-                          : STextStyles.smallMed12(context).copyWith(
-                              color: !estimated
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textSubtitle1,
-                            ),
-                    ),
-                  ],
+            child: ConditionalParent(
+              condition: isDesktop,
+              builder: (child) => MouseRegion(
+                cursor: !estimated
+                    ? SystemMouseCursors.basic
+                    : SystemMouseCursors.click,
+                child: child,
+              ),
+              child: GestureDetector(
+                onTap: () {
+                  if (estimated) {
+                    ref.read(prefsChangeNotifierProvider).exchangeRateType =
+                        ExchangeRateType.fixed;
+                    onChanged?.call(ExchangeRateType.fixed);
+                  }
+                },
+                child: RoundedContainer(
+                  padding: isDesktop
+                      ? const EdgeInsets.all(17)
+                      : const EdgeInsets.all(0),
+                  color: !estimated
+                      ? Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldDefaultBG
+                      : Colors.transparent,
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      SvgPicture.asset(
+                        Assets.svg.lock,
+                        width: 12,
+                        height: 14,
+                        color: isDesktop
+                            ? !estimated
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorBlue
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .buttonTextSecondary
+                            : !estimated
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textSubtitle1,
+                      ),
+                      const SizedBox(
+                        width: 5,
+                      ),
+                      Text(
+                        "Fixed rate",
+                        style: isDesktop
+                            ? STextStyles.desktopTextExtraExtraSmall(context)
+                                .copyWith(
+                                color: !estimated
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorBlue
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .buttonTextSecondary,
+                              )
+                            : STextStyles.smallMed12(context).copyWith(
+                                color: !estimated
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textSubtitle1,
+                              ),
+                      ),
+                    ],
+                  ),
                 ),
               ),
             ),

From 601001f96df83e182959782e1de05e90e782ce9a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 19 Nov 2022 10:01:09 -0600
Subject: [PATCH 343/426] WIP: desktop exchange steps flow ui

---
 lib/pages/exchange_view/exchange_form.dart    |  54 ++++++--
 .../exchange_steps/step_scaffold.dart         |  55 ++++++++
 .../desktop_exchange_steps_indicator.dart     | 121 ++++++++++++++++++
 3 files changed, 218 insertions(+), 12 deletions(-)
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart

diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index a6d736228..2d89c7660 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -18,6 +18,7 @@ import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_2_view.
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_provider_options.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/rate_type_toggle.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
 import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
@@ -908,20 +909,49 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
       if (walletInitiated) {
         ref.read(exchangeSendFromWalletIdStateProvider.state).state =
             Tuple2(walletId!, coin!);
-        unawaited(
-          Navigator.of(context).pushNamed(
-            Step2View.routeName,
-            arguments: model,
-          ),
-        );
+        if (isDesktop) {
+          await showDialog<void>(
+            context: context,
+            builder: (context) {
+              return const DesktopDialog(
+                maxWidth: 700,
+                child: StepScaffold(
+                  step: 1,
+                ),
+              );
+            },
+          );
+        } else {
+          unawaited(
+            Navigator.of(context).pushNamed(
+              Step2View.routeName,
+              arguments: model,
+            ),
+          );
+        }
       } else {
         ref.read(exchangeSendFromWalletIdStateProvider.state).state = null;
-        unawaited(
-          Navigator.of(context).pushNamed(
-            Step1View.routeName,
-            arguments: model,
-          ),
-        );
+
+        if (isDesktop) {
+          await showDialog<void>(
+            context: context,
+            builder: (context) {
+              return const DesktopDialog(
+                maxWidth: 700,
+                child: StepScaffold(
+                  step: 0,
+                ),
+              );
+            },
+          );
+        } else {
+          unawaited(
+            Navigator.of(context).pushNamed(
+              Step1View.routeName,
+              arguments: model,
+            ),
+          );
+        }
       }
     }
   }
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
new file mode 100644
index 000000000..09aea9dbf
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
@@ -0,0 +1,55 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+
+class StepScaffold extends StatefulWidget {
+  const StepScaffold({Key? key, required this.step}) : super(key: key);
+
+  final int step;
+
+  @override
+  State<StepScaffold> createState() => _StepScaffoldState();
+}
+
+class _StepScaffoldState extends State<StepScaffold> {
+  int currentStep = 0;
+
+  @override
+  void initState() {
+    currentStep = widget.step;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Row(
+          children: [
+            const AppBarBackButton(
+              isCompact: true,
+            ),
+            Text(
+              "Exchange XXX to XXX",
+              style: STextStyles.desktopH3(context),
+            ),
+          ],
+        ),
+        const SizedBox(
+          height: 32,
+        ),
+        DesktopExchangeStepsIndicator(
+          currentStep: currentStep,
+        ),
+        const SizedBox(
+          height: 32,
+        ),
+        Container(
+          height: 200,
+          color: Colors.red,
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart
new file mode 100644
index 000000000..44831bb4b
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart
@@ -0,0 +1,121 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
+
+class DesktopExchangeStepsIndicator extends StatelessWidget {
+  const DesktopExchangeStepsIndicator({Key? key, required this.currentStep})
+      : super(key: key);
+
+  final int currentStep;
+
+  Color getColor(BuildContext context, int step) {
+    if (currentStep > step) {
+      return Theme.of(context)
+          .extension<StackColors>()!
+          .accentColorBlue
+          .withOpacity(0.5);
+    } else if (currentStep < step) {
+      return Theme.of(context).extension<StackColors>()!.textSubtitle3;
+    } else {
+      return Theme.of(context).extension<StackColors>()!.accentColorBlue;
+    }
+  }
+
+  static const double verticalSpacing = 4;
+  static const double horizontalSpacing = 16;
+  static const double barHeight = 6;
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      children: [
+        Expanded(
+          child: Column(
+            children: [
+              Text(
+                "Confirm amount",
+                style: STextStyles.desktopTextSmall(context).copyWith(
+                  color: getColor(context, 0),
+                ),
+              ),
+              const SizedBox(
+                height: verticalSpacing,
+              ),
+              RoundedContainer(
+                color: getColor(context, 0),
+                height: barHeight,
+              ),
+            ],
+          ),
+        ),
+        const SizedBox(
+          width: horizontalSpacing,
+        ),
+        Expanded(
+          child: Column(
+            children: [
+              Text(
+                "Enter details",
+                style: STextStyles.desktopTextSmall(context).copyWith(
+                  color: getColor(context, 1),
+                ),
+              ),
+              const SizedBox(
+                height: verticalSpacing,
+              ),
+              RoundedContainer(
+                color: getColor(context, 1),
+                height: barHeight,
+              ),
+            ],
+          ),
+        ),
+        const SizedBox(
+          width: horizontalSpacing,
+        ),
+        Expanded(
+          child: Column(
+            children: [
+              Text(
+                "Confirm details",
+                style: STextStyles.desktopTextSmall(context).copyWith(
+                  color: getColor(context, 2),
+                ),
+              ),
+              const SizedBox(
+                height: verticalSpacing,
+              ),
+              RoundedContainer(
+                color: getColor(context, 2),
+                height: barHeight,
+              ),
+            ],
+          ),
+        ),
+        const SizedBox(
+          width: horizontalSpacing,
+        ),
+        Expanded(
+          child: Column(
+            children: [
+              Text(
+                "Complete exchange",
+                style: STextStyles.desktopTextSmall(context).copyWith(
+                  color: getColor(context, 3),
+                ),
+              ),
+              const SizedBox(
+                height: verticalSpacing,
+              ),
+              RoundedContainer(
+                color: getColor(context, 3),
+                height: barHeight,
+              ),
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+}

From 90dc9e3116747ca80f0aa541bfce550bbee1113c Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 19 Nov 2022 11:32:18 -0600
Subject: [PATCH 344/426] mobile button height fix

---
 .../manage_nodes_views/node_details_view.dart                   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index 3d49ae6f7..71d764135 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -349,7 +349,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
                 Expanded(
                   child: SecondaryButton(
                     label: "Test connection",
-                    buttonHeight: ButtonHeight.l,
+                    buttonHeight: isDesktop ? ButtonHeight.l : null,
                     onPressed: () async {
                       await _testConnection(ref, context);
                     },

From d4d85259e1c89d6f418c044a48e432704c83501b Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 19 Nov 2022 12:52:32 -0600
Subject: [PATCH 345/426] logging fix

---
 lib/services/coins/wownero/wownero_wallet.dart | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index e39d13005..3d5ae3ad6 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -863,7 +863,8 @@ class WowneroWallet extends CoinServiceAPI {
         await DB.instance.get<dynamic>(boxName: walletId, key: indexKey) as int;
     // Use new index to derive a new receiving address
     final newReceivingAddress = await _generateAddressForChain(0, curIndex);
-    Logging.instance.log("xmr address in init existing: $newReceivingAddress",
+    Logging.instance.log(
+        "wownero address in init existing: $newReceivingAddress",
         level: LogLevel.Info);
     _currentReceivingAddress = Future(() => newReceivingAddress);
   }

From 719c7abd49906cc621612aabd19e4e1fe1776f43 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 19 Nov 2022 13:44:36 -0600
Subject: [PATCH 346/426] clean up logs

---
 lib/services/coins/monero/monero_wallet.dart   |  4 ++--
 lib/services/coins/wownero/wownero_wallet.dart | 12 ++++++------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index c35323d53..f94f0cd2a 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -185,8 +185,8 @@ class MoneroWallet extends CoinServiceAPI {
     try {
       if (walletBase!.syncStatus! is SyncedSyncStatus &&
           walletBase!.syncStatus!.progress() == 1.0) {
-        Logging.instance
-            .log("currentSyncingHeight lol", level: LogLevel.Warning);
+        // Logging.instance
+        //     .log("currentSyncingHeight lol", level: LogLevel.Warning);
         return getSyncingHeight();
       }
     } catch (e, s) {}
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 3d5ae3ad6..e6a531b78 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -153,7 +153,7 @@ class WowneroWallet extends CoinServiceAPI {
     try {
       _height = (walletBase!.syncStatus as SyncingSyncStatus).height;
     } catch (e, s) {
-      Logging.instance.log("$e $s", level: LogLevel.Warning);
+      // Logging.instance.log("$e $s", level: LogLevel.Warning);
     }
 
     int blocksRemaining = -1;
@@ -162,7 +162,7 @@ class WowneroWallet extends CoinServiceAPI {
       blocksRemaining =
           (walletBase!.syncStatus as SyncingSyncStatus).blocksLeft;
     } catch (e, s) {
-      Logging.instance.log("$e $s", level: LogLevel.Warning);
+      // Logging.instance.log("$e $s", level: LogLevel.Warning);
     }
     int currentHeight = _height + blocksRemaining;
     if (_height == -1 || blocksRemaining == -1) {
@@ -186,8 +186,8 @@ class WowneroWallet extends CoinServiceAPI {
     try {
       if (walletBase!.syncStatus! is SyncedSyncStatus &&
           walletBase!.syncStatus!.progress() == 1.0) {
-        Logging.instance
-            .log("currentSyncingHeight lol", level: LogLevel.Warning);
+        // Logging.instance
+        //     .log("currentSyncingHeight lol", level: LogLevel.Warning);
         return getSyncingHeight();
       }
     } catch (e, s) {}
@@ -195,7 +195,7 @@ class WowneroWallet extends CoinServiceAPI {
     try {
       syncingHeight = (walletBase!.syncStatus as SyncingSyncStatus).height;
     } catch (e, s) {
-      Logging.instance.log("$e $s", level: LogLevel.Warning);
+      // Logging.instance.log("$e $s", level: LogLevel.Warning);
     }
     final cachedHeight =
         DB.instance.get<dynamic>(boxName: walletId, key: "storedSyncingHeight")
@@ -418,7 +418,7 @@ class WowneroWallet extends CoinServiceAPI {
       try {
         progress = (walletBase!.syncStatus!).progress();
       } catch (e, s) {
-        Logging.instance.log("$e $s", level: LogLevel.Warning);
+        // Logging.instance.log("$e $s", level: LogLevel.Warning);
       }
       await _fetchTransactionData();
 

From b333253287c44beb6bc86428cdfe3f55eb938df9 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 19 Nov 2022 15:12:08 -0600
Subject: [PATCH 347/426] reduce minimum window height

---
 lib/main.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/main.dart b/lib/main.dart
index 66b3bb974..6879b69c5 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -77,7 +77,7 @@ void main() async {
 
   if (Util.isDesktop) {
     setWindowTitle('Stack Wallet');
-    setWindowMinSize(const Size(1220, 1100));
+    setWindowMinSize(const Size(1220, 1000));
     setWindowMaxSize(Size.infinite);
   }
 

From e2a172f7477550da845224003325da7bfbce35c5 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 19 Nov 2022 18:04:53 -0600
Subject: [PATCH 348/426] firo private/public balance desktop toggle

---
 assets/images/glasses-hidden.png              | Bin 0 -> 1060 bytes
 assets/images/glasses.png                     | Bin 0 -> 1955 bytes
 .../desktop_balance_toggle_button.dart        |  60 +++
 .../sub_widgets/desktop_wallet_summary.dart   | 375 +++++++-----------
 lib/utilities/assets.dart                     |   3 +
 pubspec.yaml                                  |   2 +
 6 files changed, 215 insertions(+), 225 deletions(-)
 create mode 100644 assets/images/glasses-hidden.png
 create mode 100644 assets/images/glasses.png
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart

diff --git a/assets/images/glasses-hidden.png b/assets/images/glasses-hidden.png
new file mode 100644
index 0000000000000000000000000000000000000000..9176cc69b914fb6b435fe881fd4987835a0fd5dc
GIT binary patch
literal 1060
zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8Ea{HEjtmSN`?>!lvI6-E$sR$z
z3=CCj3=9n|3=F@3LJcn%7)lKo7+xg+b<JR45HFasD-dK5TavfC3&Vd9T(EcfWS|Ip
ziKnkC`!gmfA#Qn#&!RvBm^D0I978hhy}fZZJ0?`(_(y+ZwT&*^T_Kt*8^v4}zBn|s
zgS%Ys5A&U0;vGA}1Y9mG^**?Cg@Rs}NMN9W%SzsBZrvT7x2A`z{&seW=Pb{4-NkuD
z#ygE?s+2G3e$L%)U7Y^zukHTNpXP`+DR3a69ZPS9*IE4fA^i0FUx~xAKX=J1OT4Qn
z6V;A5CM2evDrp{g;LFLA`<hM~PATk3FnK-w>9?AEiM4&lZ%393nj6eNt<+`IRx3Jj
z`A3<)2MX`bC>`Fx>nzLUYIgVBvFV#G?BCJk{ew5%pnLy@3IC%*dU&6A?PceGFtNtA
zV|S5E^34|>eM>`g*PMxR*SY@DJne&>-9-6m@!y2z-3+yVc{a<e$~Jy_Q9+SvUz#)f
zlDMn4THW;L9crF&z$vrB_Z46Bf~jX^Brg2^ooHDd^M09j1+)6U<qTZXcdIVUIrREc
z#I;=}<>&UcAA4wHcRbO?MB!t0g?Ro$<;*$q(~6EN{17>x+%?6<db7#O{qlzoGjlu;
z-J{l<9rUPDF#p!9mT#wY=1raS?3d5Rd6nA1$9eWiHQdY&S{5_c&NA|qXpr_FV}`x!
zKL)pN*A4bP$q&@cKWFXEdPgZg-{ND(asu*q1PR-FUv{5-=0VZfzpEqHd)~^5D(`;C
zwRzV2w9BuS?+cxi7x7xFZsqTVvmbWfED7H7QFnIso==rtn{8i}&$-?Cu(IZQ0>ks|
zmG?{dHfipg9#vU=cxu%A2~o>9)vl<onPgdWbHcT#YpY{#@O-WKz*3j1(7?K9x%bo1
zWy|@Otjt~?b0FpE-CAk8?#H|=1w8R3+zSq|*yT99H;xqw3kRB1?|$pi+i9A6v~s1l
zKVG)w+21t&D)EoodZ*qI+m(0p)30Ctnh#};-mUuHG0DlR>i9>dx-}t5x>LXYNnL4u
zue~ty^$q^)OCPEw<-cEgy|ZrZoTi?~o;Gd2H~+lYb%Qtavc0;lf!}kZ{c~?h*<Skh
z<6=zTg9#-P25PbrB9~0cTxZq!d7geKIrVa{tn@n}pVQBjr#X3fyv^B{-)wzBX4B6n
zOKox^Pwwi?WOEc?furp<{~34v{Bv>IuQX?1Hc~BdjVMV;EJ?LWE=mPb3`Pb<M!E(@
zx<+Oph89+ahE_)A+6D$z1_t}Z-)}?Fkei>9nO2Eg!#S^TP<g=M>FVdQ&MBb@01M61
A`2YX_

literal 0
HcmV?d00001

diff --git a/assets/images/glasses.png b/assets/images/glasses.png
new file mode 100644
index 0000000000000000000000000000000000000000..8c9e7dc276660d6b8284916943c78137a0d6ad2f
GIT binary patch
literal 1955
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
Fz~8{u`yl`T

literal 0
HcmV?d00001

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart
new file mode 100644
index 000000000..9c890b223
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart
@@ -0,0 +1,60 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+
+class DesktopBalanceToggleButton extends ConsumerWidget {
+  const DesktopBalanceToggleButton({
+    Key? key,
+    this.onPressed,
+  }) : super(key: key);
+
+  final VoidCallback? onPressed;
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return SizedBox(
+      height: 22,
+      width: 22,
+      child: MaterialButton(
+        color: Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
+        splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+        onPressed: () {
+          if (ref.read(walletBalanceToggleStateProvider.state).state ==
+              WalletBalanceToggleState.available) {
+            ref.read(walletBalanceToggleStateProvider.state).state =
+                WalletBalanceToggleState.full;
+          } else {
+            ref.read(walletBalanceToggleStateProvider.state).state =
+                WalletBalanceToggleState.available;
+          }
+          onPressed?.call();
+        },
+        elevation: 0,
+        highlightElevation: 0,
+        hoverElevation: 0,
+        padding: EdgeInsets.zero,
+        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+        shape: RoundedRectangleBorder(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
+          ),
+        ),
+        child: Center(
+          child: Image(
+            image: AssetImage(
+              ref.watch(walletBalanceToggleStateProvider.state).state ==
+                      WalletBalanceToggleState.available
+                  ? Assets.png.glassesHidden
+                  : Assets.png.glasses,
+            ),
+            width: 16,
+          ),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
index f4bfed976..d6e99ce70 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
@@ -1,13 +1,15 @@
 import 'package:decimal/decimal.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart';
 import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_refresh_button.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
 import 'package:stackwallet/services/coins/manager.dart';
 import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -33,19 +35,6 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
   late final String walletId;
   late final ChangeNotifierProvider<Manager> managerProvider;
 
-  void showSheet() {
-    showModalBottomSheet<dynamic>(
-      backgroundColor: Colors.transparent,
-      context: context,
-      shape: const RoundedRectangleBorder(
-        borderRadius: BorderRadius.vertical(
-          top: Radius.circular(20),
-        ),
-      ),
-      builder: (_) => WalletBalanceToggleSheet(walletId: walletId),
-    );
-  }
-
   Decimal? _balanceTotalCached;
   Decimal? _balanceCached;
 
@@ -59,225 +48,161 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
-    return Row(
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Column(
+    return Consumer(
+      builder: (context, ref, __) {
+        final Coin coin =
+            ref.watch(managerProvider.select((value) => value.coin));
+        return Row(
+          crossAxisAlignment: CrossAxisAlignment.start,
           children: [
-            Consumer(
-              builder: (_, ref, __) {
-                final Coin coin =
-                    ref.watch(managerProvider.select((value) => value.coin));
-                final externalCalls = ref.watch(prefsChangeNotifierProvider
-                    .select((value) => value.externalCalls));
+            Column(
+              children: [
+                Consumer(
+                  builder: (_, ref, __) {
+                    final externalCalls = ref.watch(prefsChangeNotifierProvider
+                        .select((value) => value.externalCalls));
 
-                Future<Decimal>? totalBalanceFuture;
-                Future<Decimal>? availableBalanceFuture;
-                if (coin == Coin.firo || coin == Coin.firoTestNet) {
-                  final firoWallet =
-                      ref.watch(managerProvider.select((value) => value.wallet))
+                    Future<Decimal>? totalBalanceFuture;
+                    Future<Decimal>? availableBalanceFuture;
+                    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+                      final firoWallet = ref.watch(
+                              managerProvider.select((value) => value.wallet))
                           as FiroWallet;
-                  totalBalanceFuture = firoWallet.availablePublicBalance();
-                  availableBalanceFuture = firoWallet.availablePrivateBalance();
-                } else {
-                  totalBalanceFuture = ref.watch(
-                      managerProvider.select((value) => value.totalBalance));
-
-                  availableBalanceFuture = ref.watch(managerProvider
-                      .select((value) => value.availableBalance));
-                }
-
-                final locale = ref.watch(localeServiceChangeNotifierProvider
-                    .select((value) => value.locale));
-
-                final baseCurrency = ref.watch(prefsChangeNotifierProvider
-                    .select((value) => value.currency));
-
-                final priceTuple = ref.watch(priceAnd24hChangeNotifierProvider
-                    .select((value) => value.getPrice(coin)));
-
-                final _showAvailable = false;
-                // ref.watch(walletBalanceToggleStateProvider.state).state ==
-                //     WalletBalanceToggleState.available;
-
-                return FutureBuilder(
-                  future: _showAvailable
-                      ? availableBalanceFuture
-                      : totalBalanceFuture,
-                  builder: (fbContext, AsyncSnapshot<Decimal> snapshot) {
-                    if (snapshot.connectionState == ConnectionState.done &&
-                        snapshot.hasData &&
-                        snapshot.data != null) {
-                      if (_showAvailable) {
-                        _balanceCached = snapshot.data!;
-                      } else {
-                        _balanceTotalCached = snapshot.data!;
-                      }
-                    }
-                    Decimal? balanceToShow =
-                        _showAvailable ? _balanceCached : _balanceTotalCached;
-
-                    if (balanceToShow != null) {
-                      return Column(
-                        crossAxisAlignment: CrossAxisAlignment.start,
-                        children: [
-                          // GestureDetector(
-                          //   onTap: showSheet,
-                          //   child: Row(
-                          //     children: [
-                          //       if (coin == Coin.firo ||
-                          //           coin == Coin.firoTestNet)
-                          //         Text(
-                          //           "${_showAvailable ? "Private" : "Public"} Balance",
-                          //           style: STextStyles.subtitle500(context)
-                          //               .copyWith(
-                          //             color: Theme.of(context)
-                          //                 .extension<StackColors>()!
-                          //                 .textFavoriteCard,
-                          //           ),
-                          //         ),
-                          //       if (coin != Coin.firo &&
-                          //           coin != Coin.firoTestNet)
-                          //         Text(
-                          //           "${_showAvailable ? "Available" : "Full"} Balance",
-                          //           style: STextStyles.subtitle500(context)
-                          //               .copyWith(
-                          //             color: Theme.of(context)
-                          //                 .extension<StackColors>()!
-                          //                 .textFavoriteCard,
-                          //           ),
-                          //         ),
-                          //       const SizedBox(
-                          //         width: 4,
-                          //       ),
-                          //       SvgPicture.asset(
-                          //         Assets.svg.chevronDown,
-                          //         color: Theme.of(context)
-                          //             .extension<StackColors>()!
-                          //             .textFavoriteCard,
-                          //         width: 8,
-                          //         height: 4,
-                          //       ),
-                          //     ],
-                          //   ),
-                          // ),
-                          FittedBox(
-                            fit: BoxFit.scaleDown,
-                            child: Text(
-                              "${Format.localizedStringAsFixed(
-                                value: balanceToShow,
-                                locale: locale,
-                                decimalPlaces: 8,
-                              )} ${coin.ticker}",
-                              style: STextStyles.desktopH3(context),
-                            ),
-                          ),
-                          if (externalCalls)
-                            Text(
-                              "${Format.localizedStringAsFixed(
-                                value: priceTuple.item1 * balanceToShow,
-                                locale: locale,
-                                decimalPlaces: 2,
-                              )} $baseCurrency",
-                              style: STextStyles.desktopTextExtraSmall(context)
-                                  .copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textSubtitle1,
-                              ),
-                            ),
-                        ],
-                      );
+                      totalBalanceFuture = firoWallet.availablePublicBalance();
+                      availableBalanceFuture =
+                          firoWallet.availablePrivateBalance();
                     } else {
-                      return Column(
-                        crossAxisAlignment: CrossAxisAlignment.start,
-                        children: [
-                          // GestureDetector(
-                          //   onTap: showSheet,
-                          //   child: Row(
-                          //     children: [
-                          //       if (coin == Coin.firo ||
-                          //           coin == Coin.firoTestNet)
-                          //         Text(
-                          //           "${_showAvailable ? "Private" : "Public"} Balance",
-                          //           style: STextStyles.subtitle500(context)
-                          //               .copyWith(
-                          //             color: Theme.of(context)
-                          //                 .extension<StackColors>()!
-                          //                 .textFavoriteCard,
-                          //           ),
-                          //         ),
-                          //       if (coin != Coin.firo &&
-                          //           coin != Coin.firoTestNet)
-                          //         Text(
-                          //           "${_showAvailable ? "Available" : "Full"} Balance",
-                          //           style: STextStyles.subtitle500(context)
-                          //               .copyWith(
-                          //             color: Theme.of(context)
-                          //                 .extension<StackColors>()!
-                          //                 .textFavoriteCard,
-                          //           ),
-                          //         ),
-                          //       const SizedBox(
-                          //         width: 4,
-                          //       ),
-                          //       SvgPicture.asset(
-                          //         Assets.svg.chevronDown,
-                          //         width: 8,
-                          //         height: 4,
-                          //         color: Theme.of(context)
-                          //             .extension<StackColors>()!
-                          //             .textFavoriteCard,
-                          //       ),
-                          //     ],
-                          //   ),
-                          // ),
-                          AnimatedText(
-                            stringsToLoopThrough: const [
-                              "Loading balance   ",
-                              "Loading balance.  ",
-                              "Loading balance.. ",
-                              "Loading balance..."
-                            ],
-                            style: STextStyles.desktopH3(context).copyWith(
-                              fontSize: 24,
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textDark,
-                            ),
-                          ),
-                          if (externalCalls)
-                            AnimatedText(
-                              stringsToLoopThrough: const [
-                                "Loading balance   ",
-                                "Loading balance.  ",
-                                "Loading balance.. ",
-                                "Loading balance..."
-                              ],
-                              style: STextStyles.desktopTextExtraSmall(context)
-                                  .copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .textSubtitle1,
-                              ),
-                            ),
-                        ],
-                      );
+                      totalBalanceFuture = ref.watch(managerProvider
+                          .select((value) => value.totalBalance));
+
+                      availableBalanceFuture = ref.watch(managerProvider
+                          .select((value) => value.availableBalance));
                     }
+
+                    final locale = ref.watch(localeServiceChangeNotifierProvider
+                        .select((value) => value.locale));
+
+                    final baseCurrency = ref.watch(prefsChangeNotifierProvider
+                        .select((value) => value.currency));
+
+                    final priceTuple = ref.watch(
+                        priceAnd24hChangeNotifierProvider
+                            .select((value) => value.getPrice(coin)));
+
+                    final _showAvailable = ref
+                            .watch(walletBalanceToggleStateProvider.state)
+                            .state ==
+                        WalletBalanceToggleState.available;
+
+                    return FutureBuilder(
+                      future: _showAvailable
+                          ? availableBalanceFuture
+                          : totalBalanceFuture,
+                      builder: (fbContext, AsyncSnapshot<Decimal> snapshot) {
+                        if (snapshot.connectionState == ConnectionState.done &&
+                            snapshot.hasData &&
+                            snapshot.data != null) {
+                          if (_showAvailable) {
+                            _balanceCached = snapshot.data!;
+                          } else {
+                            _balanceTotalCached = snapshot.data!;
+                          }
+                        }
+                        Decimal? balanceToShow = _showAvailable
+                            ? _balanceCached
+                            : _balanceTotalCached;
+
+                        if (balanceToShow != null) {
+                          return Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              FittedBox(
+                                fit: BoxFit.scaleDown,
+                                child: Text(
+                                  "${Format.localizedStringAsFixed(
+                                    value: balanceToShow,
+                                    locale: locale,
+                                    decimalPlaces: 8,
+                                  )} ${coin.ticker}",
+                                  style: STextStyles.desktopH3(context),
+                                ),
+                              ),
+                              if (externalCalls)
+                                Text(
+                                  "${Format.localizedStringAsFixed(
+                                    value: priceTuple.item1 * balanceToShow,
+                                    locale: locale,
+                                    decimalPlaces: 2,
+                                  )} $baseCurrency",
+                                  style:
+                                      STextStyles.desktopTextExtraSmall(context)
+                                          .copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textSubtitle1,
+                                  ),
+                                ),
+                            ],
+                          );
+                        } else {
+                          return Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              AnimatedText(
+                                stringsToLoopThrough: const [
+                                  "Loading balance   ",
+                                  "Loading balance.  ",
+                                  "Loading balance.. ",
+                                  "Loading balance..."
+                                ],
+                                style: STextStyles.desktopH3(context).copyWith(
+                                  fontSize: 24,
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark,
+                                ),
+                              ),
+                              if (externalCalls)
+                                AnimatedText(
+                                  stringsToLoopThrough: const [
+                                    "Loading balance   ",
+                                    "Loading balance.  ",
+                                    "Loading balance.. ",
+                                    "Loading balance..."
+                                  ],
+                                  style:
+                                      STextStyles.desktopTextExtraSmall(context)
+                                          .copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textSubtitle1,
+                                  ),
+                                ),
+                            ],
+                          );
+                        }
+                      },
+                    );
                   },
-                );
-              },
+                ),
+              ],
             ),
+            if (coin == Coin.firo || coin == Coin.firoTestNet)
+              const SizedBox(
+                width: 8,
+              ),
+            if (coin == Coin.firo || coin == Coin.firoTestNet)
+              const DesktopBalanceToggleButton(),
+            const SizedBox(
+              width: 8,
+            ),
+            WalletRefreshButton(
+              walletId: walletId,
+              initialSyncStatus: widget.initialSyncStatus,
+            )
           ],
-        ),
-        const SizedBox(
-          width: 8,
-        ),
-        WalletRefreshButton(
-          walletId: walletId,
-          initialSyncStatus: widget.initialSyncStatus,
-        )
-      ],
+        );
+      },
     );
   }
 }
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 6fbe61005..149d46b3c 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -231,6 +231,9 @@ class _PNG {
   String get bitcoincash => "assets/images/bitcoincash.png";
   String get namecoin => "assets/images/namecoin.png";
 
+  String get glasses => "assets/images/glasses.png";
+  String get glassesHidden => "assets/images/glasses-hidden.png";
+
   String imageFor({required Coin coin}) {
     switch (coin) {
       case Coin.bitcoin:
diff --git a/pubspec.yaml b/pubspec.yaml
index e8f417586..af4370d99 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -202,6 +202,8 @@ flutter:
     - assets/images/epic-cash.png
     - assets/images/bitcoincash.png
     - assets/images/namecoin.png
+    - assets/images/glasses.png
+    - assets/images/glasses-hidden.png
     - assets/svg/plus.svg
     - assets/svg/gear.svg
     - assets/svg/bell.svg

From 345ed958e080999ac2696ca24850d0d5944bbc39 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 07:44:45 -0600
Subject: [PATCH 349/426] initial window size linux

---
 lib/main.dart           | 2 +-
 linux/my_application.cc | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/main.dart b/lib/main.dart
index 6879b69c5..728152951 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -77,7 +77,7 @@ void main() async {
 
   if (Util.isDesktop) {
     setWindowTitle('Stack Wallet');
-    setWindowMinSize(const Size(1220, 1000));
+    setWindowMinSize(const Size(1220, 900));
     setWindowMaxSize(Size.infinite);
   }
 
diff --git a/linux/my_application.cc b/linux/my_application.cc
index 280895e03..9cb3acebd 100644
--- a/linux/my_application.cc
+++ b/linux/my_application.cc
@@ -47,7 +47,7 @@ static void my_application_activate(GApplication* application) {
     gtk_window_set_title(window, "Stack Wallet");
   }
 
-  gtk_window_set_default_size(window, 720, 1280);
+  gtk_window_set_default_size(window, 1220, 900);
   gtk_widget_show(GTK_WIDGET(window));
 
   g_autoptr(FlDartProject) project = fl_dart_project_new();

From b22b4195d6bf3cd4f7bec097a58c0cef7fb737d9 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 09:15:13 -0600
Subject: [PATCH 350/426] desktop exchange steps scaffolding

---
 lib/pages/exchange_view/exchange_form.dart    |  23 ++--
 .../exchange_steps/step_scaffold.dart         |  28 +++--
 .../subwidgets/desktop_step_1.dart            | 104 ++++++++++++++++++
 .../subwidgets/desktop_step_2.dart            |  66 +++++++++++
 .../subwidgets/desktop_step_3.dart            |  91 +++++++++++++++
 .../subwidgets/desktop_step_4.dart            |  98 +++++++++++++++++
 .../subwidgets/step_one_item.dart             |  38 +++++++
 .../desktop_exchange_steps_indicator.dart     |  32 +++---
 8 files changed, 452 insertions(+), 28 deletions(-)
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart

diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index 2d89c7660..148c74920 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -19,12 +19,13 @@ import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_provider_op
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/rate_type_toggle.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
 import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -913,10 +914,14 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
           await showDialog<void>(
             context: context,
             builder: (context) {
-              return const DesktopDialog(
-                maxWidth: 700,
+              return DesktopDialog(
+                maxWidth: 720,
+                maxHeight: double.infinity,
                 child: StepScaffold(
-                  step: 1,
+                  step: 2,
+                  body: DesktopStep2(
+                    model: model,
+                  ),
                 ),
               );
             },
@@ -936,10 +941,14 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
           await showDialog<void>(
             context: context,
             builder: (context) {
-              return const DesktopDialog(
-                maxWidth: 700,
+              return DesktopDialog(
+                maxWidth: 720,
+                maxHeight: double.infinity,
                 child: StepScaffold(
-                  step: 0,
+                  step: 1,
+                  body: DesktopStep1(
+                    model: model,
+                  ),
                 ),
               );
             },
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
index 09aea9dbf..62a293c27 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
@@ -4,8 +4,13 @@ import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 
 class StepScaffold extends StatefulWidget {
-  const StepScaffold({Key? key, required this.step}) : super(key: key);
+  const StepScaffold({
+    Key? key,
+    required this.body,
+    required this.step,
+  }) : super(key: key);
 
+  final Widget body;
   final int step;
 
   @override
@@ -24,11 +29,13 @@ class _StepScaffoldState extends State<StepScaffold> {
   @override
   Widget build(BuildContext context) {
     return Column(
+      mainAxisAlignment: MainAxisAlignment.start,
       children: [
         Row(
           children: [
             const AppBarBackButton(
               isCompact: true,
+              iconSize: 23,
             ),
             Text(
               "Exchange XXX to XXX",
@@ -37,17 +44,24 @@ class _StepScaffoldState extends State<StepScaffold> {
           ],
         ),
         const SizedBox(
-          height: 32,
+          height: 12,
         ),
-        DesktopExchangeStepsIndicator(
-          currentStep: currentStep,
+        Padding(
+          padding: const EdgeInsets.symmetric(
+            horizontal: 32,
+          ),
+          child: DesktopExchangeStepsIndicator(
+            currentStep: currentStep,
+          ),
         ),
         const SizedBox(
           height: 32,
         ),
-        Container(
-          height: 200,
-          color: Colors.red,
+        Padding(
+          padding: const EdgeInsets.symmetric(
+            horizontal: 32,
+          ),
+          child: widget.body,
         ),
       ],
     );
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
new file mode 100644
index 000000000..7334cae05
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
@@ -0,0 +1,104 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class DesktopStep1 extends StatelessWidget {
+  const DesktopStep1({
+    Key? key,
+    required this.model,
+  }) : super(key: key);
+
+  final IncompleteExchangeModel model;
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Text(
+          "Confirm amount",
+          style: STextStyles.desktopTextMedium(context),
+        ),
+        const SizedBox(
+          height: 8,
+        ),
+        Text(
+          "Network fees and other exchange charges are included in the rate.",
+          style: STextStyles.desktopTextExtraExtraSmall(context),
+        ),
+        const SizedBox(
+          height: 20,
+        ),
+        RoundedWhiteContainer(
+          borderColor: Theme.of(context).extension<StackColors>()!.background,
+          padding: const EdgeInsets.all(0),
+          child: Column(
+            children: [
+              const StepOneItem(
+                label: "Exchange",
+                value: "lol",
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              const StepOneItem(
+                label: "You send",
+                value: "lol",
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              const StepOneItem(
+                label: "You receive",
+                value: "lol",
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              const StepOneItem(
+                label: "Rate",
+                value: "lol",
+              ),
+            ],
+          ),
+        ),
+        Padding(
+          padding: const EdgeInsets.only(
+            top: 20,
+            bottom: 32,
+          ),
+          child: Row(
+            children: [
+              Expanded(
+                child: SecondaryButton(
+                  label: "Back",
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: Navigator.of(context).pop,
+                ),
+              ),
+              const SizedBox(
+                width: 16,
+              ),
+              Expanded(
+                child: PrimaryButton(
+                  label: "Next",
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: () {
+                    // todo
+                  },
+                ),
+              ),
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+}
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
new file mode 100644
index 000000000..c9072cb76
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart
@@ -0,0 +1,66 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+class DesktopStep2 extends StatelessWidget {
+  const DesktopStep2({
+    Key? key,
+    required this.model,
+  }) : super(key: key);
+
+  final IncompleteExchangeModel model;
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Text(
+          "Enter exchange details",
+          style: STextStyles.desktopTextMedium(context),
+        ),
+        const SizedBox(
+          height: 8,
+        ),
+        Text(
+          "Enter your recipient and refund addresses",
+          style: STextStyles.desktopTextExtraExtraSmall(context),
+        ),
+        const SizedBox(
+          height: 20,
+        ),
+        //
+        Padding(
+          padding: const EdgeInsets.only(
+            top: 20,
+            bottom: 32,
+          ),
+          child: Row(
+            children: [
+              Expanded(
+                child: SecondaryButton(
+                  label: "Back",
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: Navigator.of(context).pop,
+                ),
+              ),
+              const SizedBox(
+                width: 16,
+              ),
+              Expanded(
+                child: PrimaryButton(
+                  label: "Next",
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: () {
+                    // todo
+                  },
+                ),
+              ),
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
new file mode 100644
index 000000000..1e2743ef5
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
@@ -0,0 +1,91 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class DesktopStep3 extends StatelessWidget {
+  const DesktopStep3({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Text(
+          "Confirm exchange details",
+          style: STextStyles.desktopTextMedium(context),
+        ),
+        const SizedBox(
+          height: 20,
+        ),
+        RoundedWhiteContainer(
+          borderColor: Theme.of(context).extension<StackColors>()!.background,
+          padding: const EdgeInsets.all(0),
+          child: Column(
+            children: [
+              const StepOneItem(
+                label: "Exchange",
+                value: "lol",
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              const StepOneItem(
+                label: "You send",
+                value: "lol",
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              const StepOneItem(
+                label: "You receive",
+                value: "lol",
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              const StepOneItem(
+                label: "Rate",
+                value: "lol",
+              ),
+            ],
+          ),
+        ),
+        Padding(
+          padding: const EdgeInsets.only(
+            top: 20,
+            bottom: 32,
+          ),
+          child: Row(
+            children: [
+              Expanded(
+                child: SecondaryButton(
+                  label: "Back",
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: Navigator.of(context).pop,
+                ),
+              ),
+              const SizedBox(
+                width: 16,
+              ),
+              Expanded(
+                child: PrimaryButton(
+                  label: "Confirm",
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: () {
+                    // todo
+                  },
+                ),
+              ),
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
new file mode 100644
index 000000000..8604e7c23
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
@@ -0,0 +1,98 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class DesktopStep4 extends StatelessWidget {
+  const DesktopStep4({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        Text(
+          "Confirm amount",
+          style: STextStyles.desktopTextMedium(context),
+        ),
+        const SizedBox(
+          height: 8,
+        ),
+        Text(
+          "Network fees and other exchange charges are included in the rate.",
+          style: STextStyles.desktopTextExtraExtraSmall(context),
+        ),
+        const SizedBox(
+          height: 20,
+        ),
+        RoundedWhiteContainer(
+          borderColor: Theme.of(context).extension<StackColors>()!.background,
+          padding: const EdgeInsets.all(0),
+          child: Column(
+            children: [
+              const StepOneItem(
+                label: "Exchange",
+                value: "lol",
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              const StepOneItem(
+                label: "You send",
+                value: "lol",
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              const StepOneItem(
+                label: "You receive",
+                value: "lol",
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              const StepOneItem(
+                label: "Rate",
+                value: "lol",
+              ),
+            ],
+          ),
+        ),
+        Padding(
+          padding: const EdgeInsets.only(
+            top: 20,
+            bottom: 32,
+          ),
+          child: Row(
+            children: [
+              Expanded(
+                child: SecondaryButton(
+                  label: "Send from Stack Wallet",
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: Navigator.of(context).pop,
+                ),
+              ),
+              const SizedBox(
+                width: 16,
+              ),
+              Expanded(
+                child: PrimaryButton(
+                  label: "Show QR code",
+                  buttonHeight: ButtonHeight.l,
+                  onPressed: () {
+                    // todo
+                  },
+                ),
+              ),
+            ],
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart
new file mode 100644
index 000000000..001383a17
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart
@@ -0,0 +1,38 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+
+class StepOneItem extends StatelessWidget {
+  const StepOneItem({
+    Key? key,
+    required this.label,
+    required this.value,
+    this.padding = const EdgeInsets.all(16),
+  }) : super(key: key);
+
+  final String label;
+  final String value;
+  final EdgeInsets padding;
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: padding,
+      child: Row(
+        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+        children: [
+          Text(
+            label,
+            style: STextStyles.desktopTextExtraExtraSmall(context),
+          ),
+          Text(
+            value,
+            style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+              color: Theme.of(context).extension<StackColors>()!.textDark,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart
index 44831bb4b..ddcd2e6c4 100644
--- a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart
@@ -22,9 +22,9 @@ class DesktopExchangeStepsIndicator extends StatelessWidget {
     }
   }
 
-  static const double verticalSpacing = 4;
+  static const double verticalSpacing = 6;
   static const double horizontalSpacing = 16;
-  static const double barHeight = 6;
+  static const double barHeight = 4;
 
   @override
   Widget build(BuildContext context) {
@@ -35,16 +35,17 @@ class DesktopExchangeStepsIndicator extends StatelessWidget {
             children: [
               Text(
                 "Confirm amount",
-                style: STextStyles.desktopTextSmall(context).copyWith(
-                  color: getColor(context, 0),
+                style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                  color: getColor(context, 1),
                 ),
               ),
               const SizedBox(
                 height: verticalSpacing,
               ),
               RoundedContainer(
-                color: getColor(context, 0),
+                color: getColor(context, 1),
                 height: barHeight,
+                width: double.infinity,
               ),
             ],
           ),
@@ -57,16 +58,17 @@ class DesktopExchangeStepsIndicator extends StatelessWidget {
             children: [
               Text(
                 "Enter details",
-                style: STextStyles.desktopTextSmall(context).copyWith(
-                  color: getColor(context, 1),
+                style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                  color: getColor(context, 2),
                 ),
               ),
               const SizedBox(
                 height: verticalSpacing,
               ),
               RoundedContainer(
-                color: getColor(context, 1),
+                color: getColor(context, 2),
                 height: barHeight,
+                width: double.infinity,
               ),
             ],
           ),
@@ -79,16 +81,17 @@ class DesktopExchangeStepsIndicator extends StatelessWidget {
             children: [
               Text(
                 "Confirm details",
-                style: STextStyles.desktopTextSmall(context).copyWith(
-                  color: getColor(context, 2),
+                style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                  color: getColor(context, 3),
                 ),
               ),
               const SizedBox(
                 height: verticalSpacing,
               ),
               RoundedContainer(
-                color: getColor(context, 2),
+                color: getColor(context, 3),
                 height: barHeight,
+                width: double.infinity,
               ),
             ],
           ),
@@ -101,16 +104,17 @@ class DesktopExchangeStepsIndicator extends StatelessWidget {
             children: [
               Text(
                 "Complete exchange",
-                style: STextStyles.desktopTextSmall(context).copyWith(
-                  color: getColor(context, 3),
+                style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                  color: getColor(context, 4),
                 ),
               ),
               const SizedBox(
                 height: verticalSpacing,
               ),
               RoundedContainer(
-                color: getColor(context, 3),
+                color: getColor(context, 4),
                 height: barHeight,
+                width: double.infinity,
               ),
             ],
           ),

From 11845b8b05b712cc6a9a931f44c5fb0ab7577de7 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 09:23:11 -0600
Subject: [PATCH 351/426] populate desktop step one trade info

---
 .../subwidgets/desktop_step_1.dart            | 29 ++++++++++++-------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
index 7334cae05..1f892dd52 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
@@ -1,13 +1,16 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
+import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart';
+import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-class DesktopStep1 extends StatelessWidget {
+class DesktopStep1 extends ConsumerWidget {
   const DesktopStep1({
     Key? key,
     required this.model,
@@ -16,7 +19,7 @@ class DesktopStep1 extends StatelessWidget {
   final IncompleteExchangeModel model;
 
   @override
-  Widget build(BuildContext context) {
+  Widget build(BuildContext context, WidgetRef ref) {
     return Column(
       children: [
         Text(
@@ -38,33 +41,37 @@ class DesktopStep1 extends StatelessWidget {
           padding: const EdgeInsets.all(0),
           child: Column(
             children: [
-              const StepOneItem(
+              StepOneItem(
                 label: "Exchange",
-                value: "lol",
+                value: ref.watch(currentExchangeNameStateProvider.state).state,
               ),
               Container(
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const StepOneItem(
+              StepOneItem(
                 label: "You send",
-                value: "lol",
+                value:
+                    "${model.sendAmount.toStringAsFixed(8)} ${model.sendTicker.toUpperCase()}",
               ),
               Container(
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const StepOneItem(
+              StepOneItem(
                 label: "You receive",
-                value: "lol",
+                value:
+                    "~${model.receiveAmount.toStringAsFixed(8)} ${model.receiveTicker.toUpperCase()}",
               ),
               Container(
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const StepOneItem(
-                label: "Rate",
-                value: "lol",
+              StepOneItem(
+                label: model.rateType == ExchangeRateType.estimated
+                    ? "Estimated rate"
+                    : "Fixed rate",
+                value: model.rateInfo,
               ),
             ],
           ),

From 2654d50e407b74916ad5ef95b4f27327518247ca Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 09:41:16 -0600
Subject: [PATCH 352/426] populate desktop step two trade info

---
 .../subwidgets/desktop_step_2.dart            | 423 +++++++++++++++++-
 1 file changed, 421 insertions(+), 2 deletions(-)

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 c9072cb76..e1c5a5620 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
@@ -1,16 +1,199 @@
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
+import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
+import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
+import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart';
+import 'package:stackwallet/providers/exchange/exchange_flow_is_active_state_provider.dart';
+import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart';
+import 'package:stackwallet/providers/global/wallets_provider.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/logger.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/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
+import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
+import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-class DesktopStep2 extends StatelessWidget {
+class DesktopStep2 extends ConsumerStatefulWidget {
   const DesktopStep2({
     Key? key,
     required this.model,
+    this.clipboard = const ClipboardWrapper(),
   }) : super(key: key);
 
   final IncompleteExchangeModel model;
+  final ClipboardInterface clipboard;
+
+  @override
+  ConsumerState<DesktopStep2> createState() => _DesktopStep2State();
+}
+
+class _DesktopStep2State extends ConsumerState<DesktopStep2> {
+  late final IncompleteExchangeModel model;
+  late final ClipboardInterface clipboard;
+
+  late final TextEditingController _toController;
+  late final TextEditingController _refundController;
+
+  late final FocusNode _toFocusNode;
+  late final FocusNode _refundFocusNode;
+
+  bool isStackCoin(String ticker) {
+    try {
+      coinFromTickerCaseInsensitive(ticker);
+      return true;
+    } on ArgumentError catch (_) {
+      return false;
+    }
+  }
+
+  void selectRecipientAddressFromStack() {
+    try {
+      final coin = coinFromTickerCaseInsensitive(
+        model.receiveTicker,
+      );
+      Navigator.of(context)
+          .pushNamed(
+        ChooseFromStackView.routeName,
+        arguments: coin,
+      )
+          .then((value) async {
+        if (value is String) {
+          final manager =
+              ref.read(walletsChangeNotifierProvider).getManager(value);
+
+          _toController.text = manager.walletName;
+          model.recipientAddress = await manager.currentReceivingAddress;
+        }
+      });
+    } catch (e, s) {
+      Logging.instance.log("$e\n$s", level: LogLevel.Info);
+    }
+  }
+
+  void selectRefundAddressFromStack() {
+    try {
+      final coin = coinFromTickerCaseInsensitive(
+        model.sendTicker,
+      );
+      Navigator.of(context)
+          .pushNamed(
+        ChooseFromStackView.routeName,
+        arguments: coin,
+      )
+          .then((value) async {
+        if (value is String) {
+          final manager =
+              ref.read(walletsChangeNotifierProvider).getManager(value);
+
+          _refundController.text = manager.walletName;
+          model.refundAddress = await manager.currentReceivingAddress;
+        }
+      });
+    } catch (e, s) {
+      Logging.instance.log("$e\n$s", level: LogLevel.Info);
+    }
+  }
+
+  void selectRecipientFromAddressBook() {
+    ref.read(exchangeFlowIsActiveStateProvider.state).state = true;
+    Navigator.of(context)
+        .pushNamed(
+      AddressBookView.routeName,
+    )
+        .then((_) {
+      ref.read(exchangeFlowIsActiveStateProvider.state).state = false;
+
+      final address =
+          ref.read(exchangeFromAddressBookAddressStateProvider.state).state;
+      if (address.isNotEmpty) {
+        _toController.text = address;
+        model.recipientAddress = _toController.text;
+        ref.read(exchangeFromAddressBookAddressStateProvider.state).state = "";
+      }
+    });
+  }
+
+  void selectRefundFromAddressBook() {
+    ref.read(exchangeFlowIsActiveStateProvider.state).state = true;
+    Navigator.of(context)
+        .pushNamed(
+      AddressBookView.routeName,
+    )
+        .then(
+      (_) {
+        ref.read(exchangeFlowIsActiveStateProvider.state).state = false;
+        final address =
+            ref.read(exchangeFromAddressBookAddressStateProvider.state).state;
+        if (address.isNotEmpty) {
+          _refundController.text = address;
+          model.refundAddress = _refundController.text;
+        }
+      },
+    );
+  }
+
+  @override
+  void initState() {
+    model = widget.model;
+    clipboard = widget.clipboard;
+
+    _toController = TextEditingController();
+    _refundController = TextEditingController();
+
+    _toFocusNode = FocusNode();
+    _refundFocusNode = FocusNode();
+
+    final tuple = ref.read(exchangeSendFromWalletIdStateProvider.state).state;
+    if (tuple != null) {
+      if (model.receiveTicker.toLowerCase() ==
+          tuple.item2.ticker.toLowerCase()) {
+        ref
+            .read(walletsChangeNotifierProvider)
+            .getManager(tuple.item1)
+            .currentReceivingAddress
+            .then((value) {
+          _toController.text = value;
+          model.recipientAddress = _toController.text;
+        });
+      } else {
+        if (model.sendTicker.toUpperCase() ==
+            tuple.item2.ticker.toUpperCase()) {
+          ref
+              .read(walletsChangeNotifierProvider)
+              .getManager(tuple.item1)
+              .currentReceivingAddress
+              .then((value) {
+            _refundController.text = value;
+            model.refundAddress = _refundController.text;
+          });
+        }
+      }
+    }
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _toController.dispose();
+    _refundController.dispose();
+
+    _toFocusNode.dispose();
+    _refundFocusNode.dispose();
+
+    super.dispose();
+  }
 
   @override
   Widget build(BuildContext context) {
@@ -30,7 +213,243 @@ class DesktopStep2 extends StatelessWidget {
         const SizedBox(
           height: 20,
         ),
-        //
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: [
+            Text(
+              "Recipient Wallet",
+              style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldActiveSearchIconRight),
+            ),
+            if (isStackCoin(model.receiveTicker))
+              BlueTextButton(
+                text: "Choose from stack",
+                onTap: selectRecipientAddressFromStack,
+              ),
+          ],
+        ),
+        const SizedBox(
+          height: 4,
+        ),
+        ClipRRect(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
+          ),
+          child: TextField(
+            onTap: () {},
+            key: const Key("recipientExchangeStep2ViewAddressFieldKey"),
+            controller: _toController,
+            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,
+            ),
+            focusNode: _toFocusNode,
+            style: STextStyles.field(context),
+            onChanged: (value) {
+              setState(() {});
+            },
+            decoration: standardInputDecoration(
+              "Enter the ${model.receiveTicker.toUpperCase()} payout address",
+              _toFocusNode,
+              context,
+              desktopMed: true,
+            ).copyWith(
+              contentPadding: const EdgeInsets.only(
+                left: 16,
+                top: 6,
+                bottom: 8,
+                right: 5,
+              ),
+              suffixIcon: Padding(
+                padding: _toController.text.isEmpty
+                    ? const EdgeInsets.only(right: 8)
+                    : const EdgeInsets.only(right: 0),
+                child: UnconstrainedBox(
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceAround,
+                    children: [
+                      _toController.text.isNotEmpty
+                          ? TextFieldIconButton(
+                              key: const Key(
+                                  "sendViewClearAddressFieldButtonKey"),
+                              onTap: () {
+                                _toController.text = "";
+                                model.recipientAddress = _toController.text;
+                                setState(() {});
+                              },
+                              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) {
+                                  final content = data.text!.trim();
+                                  _toController.text = content;
+                                  model.recipientAddress = _toController.text;
+                                  setState(() {});
+                                }
+                              },
+                              child: _toController.text.isEmpty
+                                  ? const ClipboardIcon()
+                                  : const XIcon(),
+                            ),
+                      if (_toController.text.isEmpty)
+                        TextFieldIconButton(
+                          key: const Key("sendViewAddressBookButtonKey"),
+                          onTap: selectRecipientFromAddressBook,
+                          child: const AddressBookIcon(),
+                        ),
+                    ],
+                  ),
+                ),
+              ),
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 6,
+        ),
+        RoundedWhiteContainer(
+          child: Text(
+            "This is the wallet where your ${model.receiveTicker.toUpperCase()} will be sent to.",
+            style: STextStyles.desktopTextExtraExtraSmall(context),
+          ),
+        ),
+        const SizedBox(
+          height: 24,
+        ),
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: [
+            Text(
+              "Refund Wallet (required)",
+              style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .textFieldActiveSearchIconRight),
+            ),
+            if (isStackCoin(model.sendTicker))
+              BlueTextButton(
+                text: "Choose from stack",
+                onTap: selectRefundAddressFromStack,
+              ),
+          ],
+        ),
+        const SizedBox(
+          height: 4,
+        ),
+        ClipRRect(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
+          ),
+          child: TextField(
+            key: const Key("refundExchangeStep2ViewAddressFieldKey"),
+            controller: _refundController,
+            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,
+            ),
+            focusNode: _refundFocusNode,
+            style: STextStyles.field(context),
+            onChanged: (value) {
+              setState(() {});
+            },
+            decoration: standardInputDecoration(
+              "Enter ${model.sendTicker.toUpperCase()} refund address",
+              _refundFocusNode,
+              context,
+            ).copyWith(
+              contentPadding: const EdgeInsets.only(
+                left: 16,
+                top: 6,
+                bottom: 8,
+                right: 5,
+              ),
+              suffixIcon: Padding(
+                padding: _refundController.text.isEmpty
+                    ? const EdgeInsets.only(right: 16)
+                    : const EdgeInsets.only(right: 0),
+                child: UnconstrainedBox(
+                  child: Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceAround,
+                    children: [
+                      _refundController.text.isNotEmpty
+                          ? TextFieldIconButton(
+                              key: const Key(
+                                  "sendViewClearAddressFieldButtonKey"),
+                              onTap: () {
+                                _refundController.text = "";
+                                model.refundAddress = _refundController.text;
+
+                                setState(() {});
+                              },
+                              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) {
+                                  final content = data.text!.trim();
+
+                                  _refundController.text = content;
+                                  model.refundAddress = _refundController.text;
+
+                                  setState(() {});
+                                }
+                              },
+                              child: _refundController.text.isEmpty
+                                  ? const ClipboardIcon()
+                                  : const XIcon(),
+                            ),
+                      if (_refundController.text.isEmpty)
+                        TextFieldIconButton(
+                          key: const Key("sendViewAddressBookButtonKey"),
+                          onTap: selectRefundFromAddressBook,
+                          child: const AddressBookIcon(),
+                        ),
+                    ],
+                  ),
+                ),
+              ),
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 6,
+        ),
+        RoundedWhiteContainer(
+          borderColor: Theme.of(context).extension<StackColors>()!.background,
+          child: Text(
+            "In case something goes wrong during the exchange, we might need a refund address so we can return your coins back to you.",
+            style: STextStyles.desktopTextExtraExtraSmall(context),
+          ),
+        ),
         Padding(
           padding: const EdgeInsets.only(
             top: 20,

From 648c896b9e9a8a38e00faf63762c1bba5c37280d Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 09:49:27 -0600
Subject: [PATCH 353/426] refactor desktop step item

---
 .../subwidgets/desktop_step_1.dart            | 10 ++--
 .../subwidgets/desktop_step_3.dart            | 10 ++--
 .../subwidgets/desktop_step_4.dart            | 10 ++--
 .../subwidgets/desktop_step_item.dart         | 59 +++++++++++++++++++
 .../subwidgets/step_one_item.dart             | 38 ------------
 5 files changed, 74 insertions(+), 53 deletions(-)
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart
 delete mode 100644 lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart

diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
index 1f892dd52..942747ea2 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
-import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -41,7 +41,7 @@ class DesktopStep1 extends ConsumerWidget {
           padding: const EdgeInsets.all(0),
           child: Column(
             children: [
-              StepOneItem(
+              DesktopStepItem(
                 label: "Exchange",
                 value: ref.watch(currentExchangeNameStateProvider.state).state,
               ),
@@ -49,7 +49,7 @@ class DesktopStep1 extends ConsumerWidget {
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              StepOneItem(
+              DesktopStepItem(
                 label: "You send",
                 value:
                     "${model.sendAmount.toStringAsFixed(8)} ${model.sendTicker.toUpperCase()}",
@@ -58,7 +58,7 @@ class DesktopStep1 extends ConsumerWidget {
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              StepOneItem(
+              DesktopStepItem(
                 label: "You receive",
                 value:
                     "~${model.receiveAmount.toStringAsFixed(8)} ${model.receiveTicker.toUpperCase()}",
@@ -67,7 +67,7 @@ class DesktopStep1 extends ConsumerWidget {
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              StepOneItem(
+              DesktopStepItem(
                 label: model.rateType == ExchangeRateType.estimated
                     ? "Estimated rate"
                     : "Fixed rate",
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
index 1e2743ef5..655c3518e 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
@@ -25,7 +25,7 @@ class DesktopStep3 extends StatelessWidget {
           padding: const EdgeInsets.all(0),
           child: Column(
             children: [
-              const StepOneItem(
+              const DesktopStepItem(
                 label: "Exchange",
                 value: "lol",
               ),
@@ -33,7 +33,7 @@ class DesktopStep3 extends StatelessWidget {
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const StepOneItem(
+              const DesktopStepItem(
                 label: "You send",
                 value: "lol",
               ),
@@ -41,7 +41,7 @@ class DesktopStep3 extends StatelessWidget {
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const StepOneItem(
+              const DesktopStepItem(
                 label: "You receive",
                 value: "lol",
               ),
@@ -49,7 +49,7 @@ class DesktopStep3 extends StatelessWidget {
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const StepOneItem(
+              const DesktopStepItem(
                 label: "Rate",
                 value: "lol",
               ),
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
index 8604e7c23..3b3853efb 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
@@ -32,7 +32,7 @@ class DesktopStep4 extends StatelessWidget {
           padding: const EdgeInsets.all(0),
           child: Column(
             children: [
-              const StepOneItem(
+              const DesktopStepItem(
                 label: "Exchange",
                 value: "lol",
               ),
@@ -40,7 +40,7 @@ class DesktopStep4 extends StatelessWidget {
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const StepOneItem(
+              const DesktopStepItem(
                 label: "You send",
                 value: "lol",
               ),
@@ -48,7 +48,7 @@ class DesktopStep4 extends StatelessWidget {
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const StepOneItem(
+              const DesktopStepItem(
                 label: "You receive",
                 value: "lol",
               ),
@@ -56,7 +56,7 @@ class DesktopStep4 extends StatelessWidget {
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const StepOneItem(
+              const DesktopStepItem(
                 label: "Rate",
                 value: "lol",
               ),
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart
new file mode 100644
index 000000000..7c777c2dd
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart
@@ -0,0 +1,59 @@
+import 'package:flutter/material.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
+
+class DesktopStepItem extends StatelessWidget {
+  const DesktopStepItem(
+      {Key? key,
+      required this.label,
+      required this.value,
+      this.padding = const EdgeInsets.all(16),
+      this.vertical = false})
+      : super(key: key);
+
+  final String label;
+  final String value;
+  final EdgeInsets padding;
+  final bool vertical;
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: padding,
+      child: ConditionalParent(
+        condition: vertical,
+        builder: (child) => Column(
+          children: [
+            child,
+            const SizedBox(
+              height: 2,
+            ),
+            Text(
+              value,
+              style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                color: Theme.of(context).extension<StackColors>()!.textDark,
+              ),
+            ),
+          ],
+        ),
+        child: Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: [
+            Text(
+              label,
+              style: STextStyles.desktopTextExtraExtraSmall(context),
+            ),
+            if (!vertical)
+              Text(
+                value,
+                style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
+                  color: Theme.of(context).extension<StackColors>()!.textDark,
+                ),
+              ),
+          ],
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart
deleted file mode 100644
index 001383a17..000000000
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/step_one_item.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:stackwallet/utilities/text_styles.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
-
-class StepOneItem extends StatelessWidget {
-  const StepOneItem({
-    Key? key,
-    required this.label,
-    required this.value,
-    this.padding = const EdgeInsets.all(16),
-  }) : super(key: key);
-
-  final String label;
-  final String value;
-  final EdgeInsets padding;
-
-  @override
-  Widget build(BuildContext context) {
-    return Padding(
-      padding: padding,
-      child: Row(
-        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-        children: [
-          Text(
-            label,
-            style: STextStyles.desktopTextExtraExtraSmall(context),
-          ),
-          Text(
-            value,
-            style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
-              color: Theme.of(context).extension<StackColors>()!.textDark,
-            ),
-          ),
-        ],
-      ),
-    );
-  }
-}

From c9e2c4abb7c3fe41f9ea4c7b8152d5e00f597b76 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 10:14:27 -0600
Subject: [PATCH 354/426] desktop trade steps 3 and 4 mostly laid out

---
 .../exchange_step_views/step_4_view.dart      |   1 -
 .../subwidgets/desktop_step_3.dart            | 170 ++++++++++++++++--
 .../subwidgets/desktop_step_4.dart            | 155 ++++++++++++++--
 3 files changed, 295 insertions(+), 31 deletions(-)

diff --git a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
index 0921f68e0..a8b403dcf 100644
--- a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
+++ b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
@@ -18,7 +18,6 @@ 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/enums/fee_rate_type_enum.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
index 655c3518e..65b6ed2b3 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
@@ -1,13 +1,135 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
+import 'package:stackwallet/models/exchange/response_objects/trade.dart';
+import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_4_view.dart';
+import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
+import 'package:stackwallet/providers/exchange/current_exchange_name_state_provider.dart';
+import 'package:stackwallet/providers/exchange/exchange_provider.dart';
+import 'package:stackwallet/providers/global/trades_service_provider.dart';
+import 'package:stackwallet/services/exchange/exchange_response.dart';
+import 'package:stackwallet/services/notifications_api.dart';
+import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/custom_loading_overlay.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/stack_dialog.dart';
 
-class DesktopStep3 extends StatelessWidget {
-  const DesktopStep3({Key? key}) : super(key: key);
+class DesktopStep3 extends ConsumerStatefulWidget {
+  const DesktopStep3({
+    Key? key,
+    required this.model,
+  }) : super(key: key);
+
+  final IncompleteExchangeModel model;
+
+  @override
+  ConsumerState<DesktopStep3> createState() => _DesktopStep3State();
+}
+
+class _DesktopStep3State extends ConsumerState<DesktopStep3> {
+  late final IncompleteExchangeModel model;
+
+  Future<void> createTrade() async {
+    unawaited(
+      showDialog<void>(
+        context: context,
+        barrierDismissible: false,
+        builder: (_) => WillPopScope(
+          onWillPop: () async => false,
+          child: Container(
+            color: Theme.of(context)
+                .extension<StackColors>()!
+                .overlay
+                .withOpacity(0.6),
+            child: const CustomLoadingOverlay(
+              message: "Creating a trade",
+              eventBus: null,
+            ),
+          ),
+        ),
+      ),
+    );
+
+    final ExchangeResponse<Trade> response =
+        await ref.read(exchangeProvider).createTrade(
+              from: model.sendTicker,
+              to: model.receiveTicker,
+              fixedRate: model.rateType != ExchangeRateType.estimated,
+              amount: model.reversed ? model.receiveAmount : model.sendAmount,
+              addressTo: model.recipientAddress!,
+              extraId: null,
+              addressRefund: model.refundAddress!,
+              refundExtraId: "",
+              rateId: model.rateId,
+              reversed: model.reversed,
+            );
+
+    if (response.value == null) {
+      if (mounted) {
+        Navigator.of(context).pop();
+      }
+
+      unawaited(showDialog<void>(
+        context: context,
+        barrierDismissible: true,
+        builder: (_) => StackDialog(
+          title: "Failed to create trade",
+          message: response.exception?.toString(),
+        ),
+      ));
+      return;
+    }
+
+    // save trade to hive
+    await ref.read(tradesServiceProvider).add(
+          trade: response.value!,
+          shouldNotifyListeners: true,
+        );
+
+    String status = response.value!.status;
+
+    model.trade = response.value!;
+
+    // extra info if status is waiting
+    if (status == "Waiting") {
+      status += " for deposit";
+    }
+
+    if (mounted) {
+      Navigator.of(context).pop();
+    }
+
+    unawaited(NotificationApi.showNotification(
+      changeNowId: model.trade!.tradeId,
+      title: status,
+      body: "Trade ID ${model.trade!.tradeId}",
+      walletId: "",
+      iconAssetName: Assets.svg.arrowRotate,
+      date: model.trade!.timestamp,
+      shouldWatchForUpdates: true,
+      coinName: "coinName",
+    ));
+
+    if (mounted) {
+      unawaited(Navigator.of(context).pushNamed(
+        Step4View.routeName,
+        arguments: model,
+      ));
+    }
+  }
+
+  @override
+  void initState() {
+    model = widget.model;
+    super.initState();
+  }
 
   @override
   Widget build(BuildContext context) {
@@ -25,33 +147,55 @@ class DesktopStep3 extends StatelessWidget {
           padding: const EdgeInsets.all(0),
           child: Column(
             children: [
-              const DesktopStepItem(
+              DesktopStepItem(
                 label: "Exchange",
-                value: "lol",
+                value: ref.watch(currentExchangeNameStateProvider.state).state,
               ),
               Container(
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const DesktopStepItem(
+              DesktopStepItem(
                 label: "You send",
-                value: "lol",
+                value:
+                    "${model.sendAmount.toStringAsFixed(8)} ${model.sendTicker.toUpperCase()}",
               ),
               Container(
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const DesktopStepItem(
+              DesktopStepItem(
                 label: "You receive",
-                value: "lol",
+                value:
+                    "~${model.receiveAmount.toStringAsFixed(8)} ${model.receiveTicker.toUpperCase()}",
               ),
               Container(
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const DesktopStepItem(
-                label: "Rate",
-                value: "lol",
+              DesktopStepItem(
+                label: model.rateType == ExchangeRateType.estimated
+                    ? "Estimated rate"
+                    : "Fixed rate",
+                value: model.rateInfo,
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              DesktopStepItem(
+                vertical: true,
+                label: "Recipient ${model.receiveTicker.toUpperCase()} address",
+                value: model.recipientAddress!,
+              ),
+              Container(
+                height: 1,
+                color: Theme.of(context).extension<StackColors>()!.background,
+              ),
+              DesktopStepItem(
+                vertical: true,
+                label: "Refund ${model.sendTicker.toUpperCase()} address",
+                value: model.refundAddress!,
               ),
             ],
           ),
@@ -77,9 +221,7 @@ class DesktopStep3 extends StatelessWidget {
                 child: PrimaryButton(
                   label: "Confirm",
                   buttonHeight: ButtonHeight.l,
-                  onPressed: () {
-                    // todo
-                  },
+                  onPressed: createTrade,
                 ),
               ),
             ],
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
index 3b3853efb..ba9838086 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
@@ -1,64 +1,187 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
+import 'package:stackwallet/providers/providers.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/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-class DesktopStep4 extends StatelessWidget {
-  const DesktopStep4({Key? key}) : super(key: key);
+class DesktopStep4 extends ConsumerStatefulWidget {
+  const DesktopStep4({
+    Key? key,
+    required this.model,
+  }) : super(key: key);
+
+  final IncompleteExchangeModel model;
+
+  @override
+  ConsumerState<DesktopStep4> createState() => _DesktopStep4State();
+}
+
+class _DesktopStep4State extends ConsumerState<DesktopStep4> {
+  late final IncompleteExchangeModel model;
+
+  String _statusString = "New";
+
+  Timer? _statusTimer;
+
+  bool _isWalletCoinAndHasWallet(String ticker) {
+    try {
+      final coin = coinFromTickerCaseInsensitive(ticker);
+      return ref
+          .read(walletsChangeNotifierProvider)
+          .managers
+          .where((element) => element.coin == coin)
+          .isNotEmpty;
+    } catch (_) {
+      return false;
+    }
+  }
+
+  Future<void> _updateStatus() async {
+    final statusResponse =
+        await ref.read(exchangeProvider).updateTrade(model.trade!);
+    String status = "Waiting";
+    if (statusResponse.value != null) {
+      status = statusResponse.value!.status;
+    }
+
+    // extra info if status is waiting
+    if (status == "Waiting") {
+      status += " for deposit";
+    }
+
+    if (mounted) {
+      setState(() {
+        _statusString = status;
+      });
+    }
+  }
+
+  @override
+  void initState() {
+    model = widget.model;
+
+    _statusTimer = Timer.periodic(const Duration(seconds: 60), (_) {
+      _updateStatus();
+    });
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _statusTimer?.cancel();
+    _statusTimer = null;
+    super.dispose();
+  }
 
   @override
   Widget build(BuildContext context) {
     return Column(
       children: [
         Text(
-          "Confirm amount",
+          "Send ${model.sendTicker.toUpperCase()} to the address below",
           style: STextStyles.desktopTextMedium(context),
         ),
         const SizedBox(
           height: 8,
         ),
         Text(
-          "Network fees and other exchange charges are included in the rate.",
+          "Send ${model.sendTicker.toUpperCase()} to the address below. Once it is received, ${model.trade!.exchangeName} will send the ${model.receiveTicker.toUpperCase()} to the recipient address you provided. You can find this trade details and check its status in the list of trades.",
           style: STextStyles.desktopTextExtraExtraSmall(context),
         ),
         const SizedBox(
           height: 20,
         ),
+        RoundedContainer(
+          color: Theme.of(context).extension<StackColors>()!.warningBackground,
+          child: RichText(
+            text: TextSpan(
+              text:
+                  "You must send at least ${model.sendAmount.toString()} ${model.sendTicker}. ",
+              style: STextStyles.label700(context).copyWith(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .warningForeground,
+                fontSize: 14,
+              ),
+              children: [
+                TextSpan(
+                  text:
+                      "If you send less than ${model.sendAmount.toString()} ${model.sendTicker}, your transaction may not be converted and it may not be refunded.",
+                  style: STextStyles.label(context).copyWith(
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .warningForeground,
+                    fontSize: 14,
+                  ),
+                ),
+              ],
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 20,
+        ),
         RoundedWhiteContainer(
           borderColor: Theme.of(context).extension<StackColors>()!.background,
           padding: const EdgeInsets.all(0),
           child: Column(
             children: [
-              const DesktopStepItem(
-                label: "Exchange",
-                value: "lol",
+              DesktopStepItem(
+                vertical: true,
+                label: "Send ${model.sendTicker.toUpperCase()} to this address",
+                value: model.trade!.payInAddress,
               ),
               Container(
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const DesktopStepItem(
-                label: "You send",
-                value: "lol",
+              DesktopStepItem(
+                label: "Amount",
+                value:
+                    "${model.sendAmount.toString()} ${model.sendTicker.toUpperCase()}",
               ),
               Container(
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const DesktopStepItem(
-                label: "You receive",
-                value: "lol",
+              DesktopStepItem(
+                label: "Trade ID",
+                value: model.trade!.tradeId,
               ),
               Container(
                 height: 1,
                 color: Theme.of(context).extension<StackColors>()!.background,
               ),
-              const DesktopStepItem(
-                label: "Rate",
-                value: "lol",
+              Padding(
+                padding: const EdgeInsets.all(16),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Text(
+                      "Status",
+                      style: STextStyles.desktopTextExtraExtraSmall(context),
+                    ),
+                    Text(
+                      _statusString,
+                      style: STextStyles.desktopTextExtraExtraSmall(context)
+                          .copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .colorForStatus(_statusString),
+                      ),
+                    ),
+                  ],
+                ),
               ),
             ],
           ),

From 78186358b9de2fc28b989575e1d6bee1c62d1f38 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 21 Nov 2022 10:50:53 -0700
Subject: [PATCH 355/426] WIP: wallet will be deleted dialog

---
 .../sub_widgets/delete_wallet_keys_popup.dart | 195 ++++++++++++++++++
 .../desktop_attention_delete_wallet.dart      | 122 +++++++++++
 .../desktop_delete_wallet_dialog.dart         |  90 +-------
 lib/route_generator.dart                      |  47 +++++
 4 files changed, 369 insertions(+), 85 deletions(-)
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
 create mode 100644 lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
new file mode 100644
index 000000000..5f46e0f2f
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
@@ -0,0 +1,195 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+class DeleteWalletKeysPopup extends ConsumerStatefulWidget {
+  const DeleteWalletKeysPopup({
+    Key? key,
+    required this.walletId,
+    required this.words,
+  }) : super(key: key);
+
+  final String walletId;
+  final List<String> words;
+
+  static const String routeName = "/desktopDeleteWalletKeysPopup";
+
+  @override
+  ConsumerState<DeleteWalletKeysPopup> createState() =>
+      _DeleteWalletKeysPopup();
+}
+
+class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 614,
+      maxHeight: double.infinity,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: [
+              Padding(
+                padding: const EdgeInsets.only(
+                  left: 32,
+                ),
+                child: Text(
+                  "Wallet keys",
+                  style: STextStyles.desktopH3(context),
+                ),
+              ),
+              DesktopDialogCloseButton(
+                onPressedOverride: () {
+                  int count = 0;
+                  Navigator.of(context).popUntil((_) => count++ >= 2);
+                },
+              ),
+            ],
+          ),
+          const SizedBox(
+            height: 28,
+          ),
+          Text(
+            "Recovery phrase",
+            style: STextStyles.desktopTextMedium(context),
+          ),
+          const SizedBox(
+            height: 8,
+          ),
+          Center(
+            child: Padding(
+              padding: const EdgeInsets.symmetric(
+                horizontal: 32,
+              ),
+              child: Text(
+                "Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
+                style: STextStyles.desktopTextExtraExtraSmall(context),
+                textAlign: TextAlign.center,
+              ),
+            ),
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: MnemonicTable(
+              words: widget.words,
+              isDesktop: true,
+              itemBorderColor: Theme.of(context)
+                  .extension<StackColors>()!
+                  .buttonBackSecondary,
+            ),
+          ),
+          const SizedBox(
+            height: 24,
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 32,
+            ),
+            child: Row(
+              children: [
+                Expanded(
+                  child: PrimaryButton(
+                    label: "Continue",
+                    onPressed: () async {
+                      int count = 0;
+                      Navigator.of(context).popUntil((_) => count++ >= 2);
+
+                      unawaited(
+                        showDialog(
+                            context: context,
+                            builder: (context) {
+                              return DesktopDialog(
+                                child: Column(
+                                  children: [
+                                    Row(
+                                      mainAxisAlignment: MainAxisAlignment.end,
+                                      children: [
+                                        DesktopDialogCloseButton(
+                                          onPressedOverride: () {
+                                            int count = 0;
+                                            Navigator.of(context)
+                                                .popUntil((_) => count++ >= 2);
+                                          },
+                                        ),
+                                      ],
+                                    ),
+                                    Column(
+                                      children: [
+                                        Text(
+                                          "Thanks! "
+                                          "\n\nYour wallet will be deleted.",
+                                          style: STextStyles.desktopH2(context),
+                                        ),
+                                        const SizedBox(height: 20),
+                                        Row(
+                                          mainAxisAlignment:
+                                              MainAxisAlignment.center,
+                                          children: [
+                                            SecondaryButton(
+                                                width: 250,
+                                                buttonHeight: ButtonHeight.xl,
+                                                label: "Cancel",
+                                                onPressed: () {
+                                                  int count = 0;
+                                                  Navigator.of(context)
+                                                      .popUntil(
+                                                          (_) => count++ >= 2);
+                                                }),
+                                            const SizedBox(width: 16),
+                                            PrimaryButton(
+                                                width: 250,
+                                                buttonHeight: ButtonHeight.xl,
+                                                label: "Continue",
+                                                onPressed: () async {
+                                                  // final walletsInstance =
+                                                  // ref.read(walletsChangeNotifierProvider);
+                                                  // await ref
+                                                  //     .read(walletsServiceChangeNotifierProvider)
+                                                  //     .deleteWallet(walletId, true);
+                                                  //
+                                                  // if (mounted) {
+                                                  //   Navigator.of(context).popUntil(
+                                                  //       ModalRoute.withName(HomeView.routeName));
+                                                  // }
+
+                                                  // // wait for widget tree to dispose of any widgets watching the manager
+                                                  // await Future<void>.delayed(const Duration(seconds: 1));
+                                                  // walletsInstance.removeWallet(walletId: walletId);
+                                                }),
+                                          ],
+                                        )
+                                      ],
+                                    ),
+                                  ],
+                                ),
+                              );
+                            }),
+                      );
+                    },
+                  ),
+                ),
+              ],
+            ),
+          ),
+          const SizedBox(
+            height: 32,
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart
new file mode 100644
index 000000000..30546f60b
--- /dev/null
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart
@@ -0,0 +1,122 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
+import 'package:tuple/tuple.dart';
+
+import 'delete_wallet_keys_popup.dart';
+
+class DesktopAttentionDeleteWallet extends ConsumerStatefulWidget {
+  const DesktopAttentionDeleteWallet({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  static const String routeName = "/desktopAttentionDeleteWallet";
+
+  @override
+  ConsumerState<DesktopAttentionDeleteWallet> createState() =>
+      _DesktopAttentionDeleteWallet();
+}
+
+class _DesktopAttentionDeleteWallet
+    extends ConsumerState<DesktopAttentionDeleteWallet> {
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxWidth: 610,
+      maxHeight: 530,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.end,
+            children: [
+              DesktopDialogCloseButton(
+                onPressedOverride: () {
+                  int count = 0;
+                  Navigator.of(context).popUntil((_) => count++ >= 2);
+                },
+              ),
+            ],
+          ),
+          Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
+            child: Column(
+              children: [
+                Text(
+                  "Attention!",
+                  style: STextStyles.desktopH2(context),
+                ),
+                const SizedBox(
+                  height: 16,
+                ),
+                RoundedContainer(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .snackBarBackError,
+                  child: Padding(
+                    padding: const EdgeInsets.all(10.0),
+                    child: Text(
+                      "You are going to permanently delete you wallet.\n\nIf you delete your wallet, "
+                      "the only way you can have access to your funds is by using your backup key."
+                      "\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet."
+                      "\n\nPLEASE SAVE YOUR BACKUP KEY.",
+                      style: STextStyles.desktopTextExtraExtraSmall(context)
+                          .copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark3,
+                      ),
+                    ),
+                  ),
+                ),
+                const SizedBox(height: 30),
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  children: [
+                    SecondaryButton(
+                      width: 250,
+                      buttonHeight: ButtonHeight.xl,
+                      label: "Cancel",
+                      onPressed: () {
+                        int count = 0;
+                        Navigator.of(context).popUntil((_) => count++ >= 2);
+                      },
+                    ),
+                    const SizedBox(width: 16),
+                    PrimaryButton(
+                      width: 250,
+                      buttonHeight: ButtonHeight.xl,
+                      label: "View Backup Key",
+                      onPressed: () async {
+                        final words = await ref
+                            .read(walletsChangeNotifierProvider)
+                            .getManager(widget.walletId)
+                            .mnemonic;
+
+                        await Navigator.of(context)
+                            .pushNamed(DeleteWalletKeysPopup.routeName,
+                                arguments: Tuple2(
+                                  widget.walletId,
+                                  words,
+                                ));
+                      },
+                    ),
+                  ],
+                )
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
index e2ab4fa86..087629673 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -12,7 +13,6 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
-import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 
 import '../../../../../providers/desktop/storage_crypto_handler_provider.dart';
@@ -41,89 +41,6 @@ class _DesktopDeleteWalletDialog
   bool hidePassword = true;
   bool _continueEnabled = false;
 
-  Future<void> attentionDelete() async {
-    await showDialog<dynamic>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: true,
-      builder: (context) => DesktopDialog(
-        maxWidth: 610,
-        maxHeight: 530,
-        child: Column(
-          children: [
-            Row(
-              mainAxisAlignment: MainAxisAlignment.end,
-              children: [
-                DesktopDialogCloseButton(
-                  onPressedOverride: () {
-                    int count = 0;
-                    Navigator.of(context).popUntil((_) => count++ >= 2);
-                  },
-                ),
-              ],
-            ),
-            Padding(
-              padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 26),
-              child: Column(
-                children: [
-                  Text(
-                    "Attention!",
-                    style: STextStyles.desktopH2(context),
-                  ),
-                  const SizedBox(
-                    height: 16,
-                  ),
-                  RoundedContainer(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .snackBarBackError,
-                    child: Padding(
-                      padding: const EdgeInsets.all(10.0),
-                      child: Text(
-                        "You are going to permanently delete you wallet.\n\nIf you delete your wallet, "
-                        "the only way you can have access to your funds is by using your backup key."
-                        "\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet."
-                        "\n\nPLEASE SAVE YOUR BACKUP KEY.",
-                        style: STextStyles.desktopTextExtraExtraSmall(context)
-                            .copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .textDark3,
-                        ),
-                      ),
-                    ),
-                  ),
-                  const SizedBox(height: 30),
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.center,
-                    children: [
-                      SecondaryButton(
-                        width: 250,
-                        buttonHeight: ButtonHeight.xl,
-                        label: "Cancel",
-                        onPressed: () {
-                          int count = 0;
-                          Navigator.of(context).popUntil((_) => count++ >= 2);
-                        },
-                      ),
-                      const SizedBox(width: 16),
-                      PrimaryButton(
-                        width: 250,
-                        buttonHeight: ButtonHeight.xl,
-                        label: "View Backup Key",
-                        onPressed: () {},
-                      ),
-                    ],
-                  )
-                ],
-              ),
-            ),
-          ],
-        ),
-      ),
-    );
-  }
-
   @override
   void initState() {
     passwordController = TextEditingController();
@@ -273,7 +190,10 @@ class _DesktopDeleteWalletDialog
                                 if (mounted) {
                                   Navigator.of(context).pop();
 
-                                  attentionDelete();
+                                  await Navigator.of(context).pushNamed(
+                                    DesktopAttentionDeleteWallet.routeName,
+                                    arguments: widget.walletId,
+                                  );
                                 }
                               } else {
                                 unawaited(
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 77b5e7d11..cbc4cb343 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -92,6 +92,8 @@ import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
@@ -1193,6 +1195,51 @@ class RouteGenerator {
         }
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
+      case DesktopAttentionDeleteWallet.routeName:
+        if (args is String) {
+          return FadePageRoute(
+            DesktopAttentionDeleteWallet(
+              walletId: args,
+            ),
+            RouteSettings(
+              name: settings.name,
+            ),
+          );
+          // return getRoute(
+          //   shouldUseMaterialRoute: useMaterialPageRoute,
+          //   builder: (_) => WalletKeysDesktopPopup(
+          //     words: args,
+          //   ),
+          //   settings: RouteSettings(
+          //     name: settings.name,
+          //   ),
+          // );
+        }
+        return _routeError("${settings.name} invalid args: ${args.toString()}");
+
+      case DeleteWalletKeysPopup.routeName:
+        if (args is Tuple2<String, List<String>>) {
+          return FadePageRoute(
+            DeleteWalletKeysPopup(
+              walletId: args.item1,
+              words: args.item2,
+            ),
+            RouteSettings(
+              name: settings.name,
+            ),
+          );
+          // return getRoute(
+          //   shouldUseMaterialRoute: useMaterialPageRoute,
+          //   builder: (_) => WalletKeysDesktopPopup(
+          //     words: args,
+          //   ),
+          //   settings: RouteSettings(
+          //     name: settings.name,
+          //   ),
+          // );
+        }
+        return _routeError("${settings.name} invalid args: ${args.toString()}");
+
       case QRCodeDesktopPopupContent.routeName:
         if (args is String) {
           return FadePageRoute(

From 5c7cb8a3c5d033dab7f0614ce090f5d783d53b77 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 21 Nov 2022 12:18:35 -0700
Subject: [PATCH 356/426] WIP: unmounted widget

---
 .../sub_widgets/delete_wallet_keys_popup.dart | 67 +++++++++++++++----
 1 file changed, 53 insertions(+), 14 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
index 5f46e0f2f..f70c2eadf 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
@@ -3,6 +3,9 @@ import 'dart:async';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/providers/global/wallets_service_provider.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -28,6 +31,15 @@ class DeleteWalletKeysPopup extends ConsumerStatefulWidget {
 }
 
 class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
+  late final String _walletId;
+
+  @override
+  void initState() {
+    _walletId = widget.walletId;
+
+    super.initState();
+  }
+
   @override
   Widget build(BuildContext context) {
     return DesktopDialog(
@@ -113,6 +125,7 @@ class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
                             context: context,
                             builder: (context) {
                               return DesktopDialog(
+                                maxHeight: 350,
                                 child: Column(
                                   children: [
                                     Row(
@@ -128,13 +141,16 @@ class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
                                       ],
                                     ),
                                     Column(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.center,
                                       children: [
                                         Text(
                                           "Thanks! "
                                           "\n\nYour wallet will be deleted.",
                                           style: STextStyles.desktopH2(context),
+                                          textAlign: TextAlign.center,
                                         ),
-                                        const SizedBox(height: 20),
+                                        const SizedBox(height: 50),
                                         Row(
                                           mainAxisAlignment:
                                               MainAxisAlignment.center,
@@ -155,20 +171,43 @@ class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
                                                 buttonHeight: ButtonHeight.xl,
                                                 label: "Continue",
                                                 onPressed: () async {
-                                                  // final walletsInstance =
-                                                  // ref.read(walletsChangeNotifierProvider);
-                                                  // await ref
-                                                  //     .read(walletsServiceChangeNotifierProvider)
-                                                  //     .deleteWallet(walletId, true);
-                                                  //
-                                                  // if (mounted) {
-                                                  //   Navigator.of(context).popUntil(
-                                                  //       ModalRoute.withName(HomeView.routeName));
-                                                  // }
+                                                  // int count = 0;
+                                                  // Navigator.of(context)
+                                                  //     .popUntil(
+                                                  //         (_) => count++ >= 2);
 
-                                                  // // wait for widget tree to dispose of any widgets watching the manager
-                                                  // await Future<void>.delayed(const Duration(seconds: 1));
-                                                  // walletsInstance.removeWallet(walletId: walletId);
+                                                  final walletsInstance = ref.read(
+                                                      walletsChangeNotifierProvider);
+                                                  final manager = ref
+                                                      .read(
+                                                          walletsChangeNotifierProvider)
+                                                      .getManager(_walletId);
+
+                                                  final _managerWalletId =
+                                                      manager.walletId;
+
+                                                  await ref
+                                                      .read(
+                                                          walletsServiceChangeNotifierProvider)
+                                                      .deleteWallet(
+                                                          manager.walletName,
+                                                          true);
+
+                                                  if (mounted) {
+                                                    Navigator.of(context)
+                                                        .popUntil(
+                                                            ModalRoute.withName(
+                                                                MyStackView
+                                                                    .routeName));
+                                                  }
+
+                                                  // wait for widget tree to dispose of any widgets watching the manager
+                                                  await Future<void>.delayed(
+                                                      const Duration(
+                                                          seconds: 1));
+                                                  walletsInstance.removeWallet(
+                                                      walletId:
+                                                          _managerWalletId);
                                                 }),
                                           ],
                                         )

From d06c4862b1685b19f48686b8c3c27a7542fedd16 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 11:21:44 -0600
Subject: [PATCH 357/426] desktop exchange coin selection ui

---
 .../fixed_rate_pair_coin_selection_view.dart  | 319 +++++++++---------
 ...floating_rate_currency_selection_view.dart | 317 ++++++++---------
 lib/pages/exchange_view/exchange_form.dart    | 143 +++++++-
 3 files changed, 459 insertions(+), 320 deletions(-)

diff --git a/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart b/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart
index 80bdcda62..779d99306 100644
--- a/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart
+++ b/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart
@@ -8,6 +8,8 @@ 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';
+import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
@@ -16,8 +18,6 @@ import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 import 'package:tuple/tuple.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class FixedRateMarketPairCoinSelectionView extends ConsumerStatefulWidget {
   const FixedRateMarketPairCoinSelectionView({
     Key? key,
@@ -120,95 +120,106 @@ class _FixedRateMarketPairCoinSelectionViewState
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            if (FocusScope.of(context).hasFocus) {
-              FocusScope.of(context).unfocus();
-              await Future<void>.delayed(const Duration(milliseconds: 50));
-            }
-            if (mounted) {
-              Navigator.of(context).pop();
-            }
-          },
-        ),
-        title: Text(
-          "Choose a coin to exchange",
-          style: STextStyles.pageTitleH2(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.symmetric(
-          horizontal: 16,
-        ),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.start,
-          children: [
+    final isDesktop = Util.isDesktop;
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () async {
+                if (FocusScope.of(context).hasFocus) {
+                  FocusScope.of(context).unfocus();
+                  await Future<void>.delayed(const Duration(milliseconds: 50));
+                }
+                if (mounted) {
+                  Navigator.of(context).pop();
+                }
+              },
+            ),
+            title: Text(
+              "Choose a coin to exchange",
+              style: STextStyles.pageTitleH2(context),
+            ),
+          ),
+          body: Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 16,
+            ),
+            child: child,
+          ),
+        );
+      },
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          if (!isDesktop)
             const SizedBox(
               height: 16,
             ),
-            ClipRRect(
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-              child: TextField(
-                autocorrect: Util.isDesktop ? false : true,
-                enableSuggestions: Util.isDesktop ? false : true,
-                controller: _searchController,
-                focusNode: _searchFocusNode,
-                onChanged: filter,
-                style: STextStyles.field(context),
-                decoration: standardInputDecoration(
-                  "Search",
-                  _searchFocusNode,
-                  context,
-                ).copyWith(
-                  prefixIcon: Padding(
-                    padding: const EdgeInsets.symmetric(
-                      horizontal: 10,
-                      vertical: 16,
-                    ),
-                    child: SvgPicture.asset(
-                      Assets.svg.search,
-                      width: 16,
-                      height: 16,
-                    ),
+          ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
+              controller: _searchController,
+              focusNode: _searchFocusNode,
+              onChanged: filter,
+              style: STextStyles.field(context),
+              decoration: standardInputDecoration(
+                "Search",
+                _searchFocusNode,
+                context,
+              ).copyWith(
+                prefixIcon: Padding(
+                  padding: const EdgeInsets.symmetric(
+                    horizontal: 10,
+                    vertical: 16,
+                  ),
+                  child: SvgPicture.asset(
+                    Assets.svg.search,
+                    width: 16,
+                    height: 16,
                   ),
-                  suffixIcon: _searchController.text.isNotEmpty
-                      ? Padding(
-                          padding: const EdgeInsets.only(right: 0),
-                          child: UnconstrainedBox(
-                            child: Row(
-                              children: [
-                                TextFieldIconButton(
-                                  child: const XIcon(),
-                                  onTap: () async {
-                                    setState(() {
-                                      _searchController.text = "";
-                                    });
-                                  },
-                                ),
-                              ],
-                            ),
-                          ),
-                        )
-                      : null,
                 ),
+                suffixIcon: _searchController.text.isNotEmpty
+                    ? Padding(
+                        padding: const EdgeInsets.only(right: 0),
+                        child: UnconstrainedBox(
+                          child: Row(
+                            children: [
+                              TextFieldIconButton(
+                                child: const XIcon(),
+                                onTap: () async {
+                                  setState(() {
+                                    _searchController.text = "";
+                                  });
+                                },
+                              ),
+                            ],
+                          ),
+                        ),
+                      )
+                    : null,
               ),
             ),
-            const SizedBox(
-              height: 10,
-            ),
-            Text(
-              "Popular coins",
-              style: STextStyles.smallMed12(context),
-            ),
-            const SizedBox(
-              height: 12,
-            ),
-            Builder(builder: (context) {
+          ),
+          const SizedBox(
+            height: 10,
+          ),
+          Text(
+            "Popular coins",
+            style: STextStyles.smallMed12(context),
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          Flexible(
+            child: Builder(builder: (context) {
               final items = _markets
                   .where((e) => Coin.values
                       .where((coin) =>
@@ -221,6 +232,7 @@ class _FixedRateMarketPairCoinSelectionViewState
                 padding: const EdgeInsets.all(0),
                 child: ListView.builder(
                   shrinkWrap: true,
+                  primary: isDesktop ? false : null,
                   itemCount: items.length,
                   itemBuilder: (builderContext, index) {
                     final String ticker =
@@ -282,84 +294,85 @@ class _FixedRateMarketPairCoinSelectionViewState
                 ),
               );
             }),
-            const SizedBox(
-              height: 20,
-            ),
-            Text(
-              "All coins",
-              style: STextStyles.smallMed12(context),
-            ),
-            const SizedBox(
-              height: 12,
-            ),
-            Flexible(
-              child: RoundedWhiteContainer(
-                padding: const EdgeInsets.all(0),
-                child: ListView.builder(
-                  shrinkWrap: true,
-                  itemCount: _markets.length,
-                  itemBuilder: (builderContext, index) {
-                    final String ticker =
-                        isFrom ? _markets[index].from : _markets[index].to;
+          ),
+          const SizedBox(
+            height: 20,
+          ),
+          Text(
+            "All coins",
+            style: STextStyles.smallMed12(context),
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          Flexible(
+            child: RoundedWhiteContainer(
+              padding: const EdgeInsets.all(0),
+              child: ListView.builder(
+                shrinkWrap: true,
+                primary: isDesktop ? false : null,
+                itemCount: _markets.length,
+                itemBuilder: (builderContext, index) {
+                  final String ticker =
+                      isFrom ? _markets[index].from : _markets[index].to;
 
-                    final tuple = _imageUrlAndNameFor(ticker);
-                    return Padding(
-                      padding: const EdgeInsets.symmetric(vertical: 4),
-                      child: GestureDetector(
-                        onTap: () {
-                          Navigator.of(context).pop(ticker);
-                        },
-                        child: RoundedWhiteContainer(
-                          child: Row(
-                            children: [
-                              SizedBox(
+                  final tuple = _imageUrlAndNameFor(ticker);
+                  return Padding(
+                    padding: const EdgeInsets.symmetric(vertical: 4),
+                    child: GestureDetector(
+                      onTap: () {
+                        Navigator.of(context).pop(ticker);
+                      },
+                      child: RoundedWhiteContainer(
+                        child: Row(
+                          children: [
+                            SizedBox(
+                              width: 24,
+                              height: 24,
+                              child: SvgPicture.network(
+                                tuple.item1,
                                 width: 24,
                                 height: 24,
-                                child: SvgPicture.network(
-                                  tuple.item1,
-                                  width: 24,
-                                  height: 24,
-                                  placeholderBuilder: (_) =>
-                                      const LoadingIndicator(),
-                                ),
+                                placeholderBuilder: (_) =>
+                                    const LoadingIndicator(),
                               ),
-                              const SizedBox(
-                                width: 10,
+                            ),
+                            const SizedBox(
+                              width: 10,
+                            ),
+                            Expanded(
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    tuple.item2,
+                                    style: STextStyles.largeMedium14(context),
+                                  ),
+                                  const SizedBox(
+                                    height: 2,
+                                  ),
+                                  Text(
+                                    ticker.toUpperCase(),
+                                    style: STextStyles.smallMed12(context)
+                                        .copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textSubtitle1,
+                                    ),
+                                  ),
+                                ],
                               ),
-                              Expanded(
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      tuple.item2,
-                                      style: STextStyles.largeMedium14(context),
-                                    ),
-                                    const SizedBox(
-                                      height: 2,
-                                    ),
-                                    Text(
-                                      ticker.toUpperCase(),
-                                      style: STextStyles.smallMed12(context)
-                                          .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textSubtitle1,
-                                      ),
-                                    ),
-                                  ],
-                                ),
-                              ),
-                            ],
-                          ),
+                            ),
+                          ],
                         ),
                       ),
-                    );
-                  },
-                ),
+                    ),
+                  );
+                },
               ),
             ),
-          ],
-        ),
+          ),
+        ],
       ),
     );
   }
diff --git a/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart b/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart
index e1c1addd2..eb7a99299 100644
--- a/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart
+++ b/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart
@@ -6,6 +6,8 @@ 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';
+import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
@@ -13,8 +15,6 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class FloatingRateCurrencySelectionView extends StatefulWidget {
   const FloatingRateCurrencySelectionView({
     Key? key,
@@ -76,96 +76,109 @@ class _FloatingRateCurrencySelectionViewState
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            if (FocusScope.of(context).hasFocus) {
-              FocusScope.of(context).unfocus();
-              await Future<void>.delayed(const Duration(milliseconds: 50));
-            }
-            if (mounted) {
-              Navigator.of(context).pop();
-            }
-          },
-        ),
-        title: Text(
-          "Choose a coin to exchange",
-          style: STextStyles.pageTitleH2(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.symmetric(
-          horizontal: 16,
-        ),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.start,
-          children: [
+    final isDesktop = Util.isDesktop;
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () async {
+                if (FocusScope.of(context).hasFocus) {
+                  FocusScope.of(context).unfocus();
+                  await Future<void>.delayed(const Duration(milliseconds: 50));
+                }
+                if (mounted) {
+                  Navigator.of(context).pop();
+                }
+              },
+            ),
+            title: Text(
+              "Choose a coin to exchange",
+              style: STextStyles.pageTitleH2(context),
+            ),
+          ),
+          body: Padding(
+            padding: const EdgeInsets.symmetric(
+              horizontal: 16,
+            ),
+            child: child,
+          ),
+        );
+      },
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisSize: isDesktop ? MainAxisSize.min : MainAxisSize.max,
+        children: [
+          if (!isDesktop)
             const SizedBox(
               height: 16,
             ),
-            ClipRRect(
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-              child: TextField(
-                autocorrect: Util.isDesktop ? false : true,
-                enableSuggestions: Util.isDesktop ? false : true,
-                controller: _searchController,
-                focusNode: _searchFocusNode,
-                onChanged: filter,
-                style: STextStyles.field(context),
-                decoration: standardInputDecoration(
-                  "Search",
-                  _searchFocusNode,
-                  context,
-                ).copyWith(
-                  prefixIcon: Padding(
-                    padding: const EdgeInsets.symmetric(
-                      horizontal: 10,
-                      vertical: 16,
-                    ),
-                    child: SvgPicture.asset(
-                      Assets.svg.search,
-                      width: 16,
-                      height: 16,
-                    ),
+          ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              autocorrect: !isDesktop,
+              enableSuggestions: !isDesktop,
+              controller: _searchController,
+              focusNode: _searchFocusNode,
+              onChanged: filter,
+              style: STextStyles.field(context),
+              decoration: standardInputDecoration(
+                "Search",
+                _searchFocusNode,
+                context,
+                desktopMed: isDesktop,
+              ).copyWith(
+                prefixIcon: Padding(
+                  padding: const EdgeInsets.symmetric(
+                    horizontal: 10,
+                    vertical: 16,
+                  ),
+                  child: SvgPicture.asset(
+                    Assets.svg.search,
+                    width: 16,
+                    height: 16,
                   ),
-                  suffixIcon: _searchController.text.isNotEmpty
-                      ? Padding(
-                          padding: const EdgeInsets.only(right: 0),
-                          child: UnconstrainedBox(
-                            child: Row(
-                              children: [
-                                TextFieldIconButton(
-                                  child: const XIcon(),
-                                  onTap: () async {
-                                    setState(() {
-                                      _searchController.text = "";
-                                    });
-                                    filter("");
-                                  },
-                                ),
-                              ],
-                            ),
-                          ),
-                        )
-                      : null,
                 ),
+                suffixIcon: _searchController.text.isNotEmpty
+                    ? Padding(
+                        padding: const EdgeInsets.only(right: 0),
+                        child: UnconstrainedBox(
+                          child: Row(
+                            children: [
+                              TextFieldIconButton(
+                                child: const XIcon(),
+                                onTap: () async {
+                                  setState(() {
+                                    _searchController.text = "";
+                                  });
+                                  filter("");
+                                },
+                              ),
+                            ],
+                          ),
+                        ),
+                      )
+                    : null,
               ),
             ),
-            const SizedBox(
-              height: 10,
-            ),
-            Text(
-              "Popular coins",
-              style: STextStyles.smallMed12(context),
-            ),
-            const SizedBox(
-              height: 12,
-            ),
-            Builder(builder: (context) {
+          ),
+          const SizedBox(
+            height: 10,
+          ),
+          Text(
+            "Popular coins",
+            style: STextStyles.smallMed12(context),
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          Flexible(
+            child: Builder(builder: (context) {
               final items = _currencies
                   .where((e) => Coin.values
                       .where((coin) =>
@@ -177,6 +190,7 @@ class _FloatingRateCurrencySelectionViewState
                 padding: const EdgeInsets.all(0),
                 child: ListView.builder(
                   shrinkWrap: true,
+                  primary: isDesktop ? false : null,
                   itemCount: items.length,
                   itemBuilder: (builderContext, index) {
                     return Padding(
@@ -234,80 +248,81 @@ class _FloatingRateCurrencySelectionViewState
                 ),
               );
             }),
-            const SizedBox(
-              height: 20,
-            ),
-            Text(
-              "All coins",
-              style: STextStyles.smallMed12(context),
-            ),
-            const SizedBox(
-              height: 12,
-            ),
-            Flexible(
-              child: RoundedWhiteContainer(
-                padding: const EdgeInsets.all(0),
-                child: ListView.builder(
-                  shrinkWrap: true,
-                  itemCount: _currencies.length,
-                  itemBuilder: (builderContext, index) {
-                    return Padding(
-                      padding: const EdgeInsets.symmetric(vertical: 4),
-                      child: GestureDetector(
-                        onTap: () {
-                          Navigator.of(context).pop(_currencies[index]);
-                        },
-                        child: RoundedWhiteContainer(
-                          child: Row(
-                            children: [
-                              SizedBox(
+          ),
+          const SizedBox(
+            height: 20,
+          ),
+          Text(
+            "All coins",
+            style: STextStyles.smallMed12(context),
+          ),
+          const SizedBox(
+            height: 12,
+          ),
+          Flexible(
+            child: RoundedWhiteContainer(
+              padding: const EdgeInsets.all(0),
+              child: ListView.builder(
+                shrinkWrap: true,
+                primary: isDesktop ? false : null,
+                itemCount: _currencies.length,
+                itemBuilder: (builderContext, index) {
+                  return Padding(
+                    padding: const EdgeInsets.symmetric(vertical: 4),
+                    child: GestureDetector(
+                      onTap: () {
+                        Navigator.of(context).pop(_currencies[index]);
+                      },
+                      child: RoundedWhiteContainer(
+                        child: Row(
+                          children: [
+                            SizedBox(
+                              width: 24,
+                              height: 24,
+                              child: SvgPicture.network(
+                                _currencies[index].image,
                                 width: 24,
                                 height: 24,
-                                child: SvgPicture.network(
-                                  _currencies[index].image,
-                                  width: 24,
-                                  height: 24,
-                                  placeholderBuilder: (_) =>
-                                      const LoadingIndicator(),
-                                ),
+                                placeholderBuilder: (_) =>
+                                    const LoadingIndicator(),
                               ),
-                              const SizedBox(
-                                width: 10,
+                            ),
+                            const SizedBox(
+                              width: 10,
+                            ),
+                            Expanded(
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Text(
+                                    _currencies[index].name,
+                                    style: STextStyles.largeMedium14(context),
+                                  ),
+                                  const SizedBox(
+                                    height: 2,
+                                  ),
+                                  Text(
+                                    _currencies[index].ticker.toUpperCase(),
+                                    style: STextStyles.smallMed12(context)
+                                        .copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textSubtitle1,
+                                    ),
+                                  ),
+                                ],
                               ),
-                              Expanded(
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      _currencies[index].name,
-                                      style: STextStyles.largeMedium14(context),
-                                    ),
-                                    const SizedBox(
-                                      height: 2,
-                                    ),
-                                    Text(
-                                      _currencies[index].ticker.toUpperCase(),
-                                      style: STextStyles.smallMed12(context)
-                                          .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textSubtitle1,
-                                      ),
-                                    ),
-                                  ],
-                                ),
-                              ),
-                            ],
-                          ),
+                            ),
+                          ],
                         ),
                       ),
-                    );
-                  },
-                ),
+                    ),
+                  );
+                },
               ),
             ),
-          ],
-        ),
+          ),
+        ],
       ),
     );
   }
diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index 148c74920..cdc6f16b9 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -39,6 +39,7 @@ import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/desktop/simple_desktop_dialog.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:tuple/tuple.dart';
 
@@ -410,13 +411,65 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
       }
     }).toList(growable: false);
 
-    final result = await Navigator.of(context).push(
-      MaterialPageRoute<dynamic>(
-        builder: (_) => FloatingRateCurrencySelectionView(
-          currencies: tickers,
-        ),
-      ),
-    );
+    final result = isDesktop
+        ? await showDialog<Currency?>(
+            context: context,
+            builder: (context) {
+              return DesktopDialog(
+                maxHeight: 700,
+                maxWidth: 580,
+                child: Column(
+                  children: [
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Padding(
+                          padding: const EdgeInsets.only(
+                            left: 32,
+                          ),
+                          child: Text(
+                            "Choose a coin to exchange",
+                            style: STextStyles.desktopH3(context),
+                          ),
+                        ),
+                        const DesktopDialogCloseButton(),
+                      ],
+                    ),
+                    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: FloatingRateCurrencySelectionView(
+                                  currencies: tickers,
+                                ),
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+              );
+            })
+        : await Navigator.of(context).push(
+            MaterialPageRoute<dynamic>(
+              builder: (_) => FloatingRateCurrencySelectionView(
+                currencies: tickers,
+              ),
+            ),
+          );
 
     if (mounted && result is Currency) {
       onSelected(result);
@@ -490,15 +543,73 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
           .toList(growable: false);
     }
 
-    final result = await Navigator.of(context).push(
-      MaterialPageRoute<dynamic>(
-        builder: (_) => FixedRateMarketPairCoinSelectionView(
-          markets: marketsThatPairWithExcludedTicker,
-          currencies: ref.read(availableChangeNowCurrenciesProvider).currencies,
-          isFrom: excludedTicker != fromTicker,
-        ),
-      ),
-    );
+    final result = isDesktop
+        ? await showDialog<String?>(
+            context: context,
+            builder: (context) {
+              return DesktopDialog(
+                maxHeight: 700,
+                maxWidth: 580,
+                child: Column(
+                  children: [
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Padding(
+                          padding: const EdgeInsets.only(
+                            left: 32,
+                          ),
+                          child: Text(
+                            "Choose a coin to exchange",
+                            style: STextStyles.desktopH3(context),
+                          ),
+                        ),
+                        const DesktopDialogCloseButton(),
+                      ],
+                    ),
+                    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: FixedRateMarketPairCoinSelectionView(
+                                  markets: marketsThatPairWithExcludedTicker,
+                                  currencies: ref
+                                      .read(
+                                          availableChangeNowCurrenciesProvider)
+                                      .currencies,
+                                  isFrom: excludedTicker != fromTicker,
+                                ),
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ],
+                ),
+              );
+            })
+        : await Navigator.of(context).push(
+            MaterialPageRoute<dynamic>(
+              builder: (_) => FixedRateMarketPairCoinSelectionView(
+                markets: marketsThatPairWithExcludedTicker,
+                currencies:
+                    ref.read(availableChangeNowCurrenciesProvider).currencies,
+                isFrom: excludedTicker != fromTicker,
+              ),
+            ),
+          );
 
     if (mounted && result is String) {
       onSelected(result);

From 3e9039ac90b724cb8886e17e6907c677fcdc36d2 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 11:26:34 -0600
Subject: [PATCH 358/426] show to and from tickers in exchange steps flow

---
 lib/pages/exchange_view/exchange_form.dart                 | 2 ++
 .../desktop_exchange/exchange_steps/step_scaffold.dart     | 7 ++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index cdc6f16b9..7faa83a35 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -1030,6 +1030,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
                 maxHeight: double.infinity,
                 child: StepScaffold(
                   step: 2,
+                  model: model,
                   body: DesktopStep2(
                     model: model,
                   ),
@@ -1057,6 +1058,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
                 maxHeight: double.infinity,
                 child: StepScaffold(
                   step: 1,
+                  model: model,
                   body: DesktopStep1(
                     model: model,
                   ),
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
index 62a293c27..8dbaf9580 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
@@ -1,4 +1,5 @@
 import 'package:flutter/material.dart';
+import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -8,10 +9,12 @@ class StepScaffold extends StatefulWidget {
     Key? key,
     required this.body,
     required this.step,
+    required this.model,
   }) : super(key: key);
 
   final Widget body;
   final int step;
+  final IncompleteExchangeModel model;
 
   @override
   State<StepScaffold> createState() => _StepScaffoldState();
@@ -19,10 +22,12 @@ class StepScaffold extends StatefulWidget {
 
 class _StepScaffoldState extends State<StepScaffold> {
   int currentStep = 0;
+  late final IncompleteExchangeModel model;
 
   @override
   void initState() {
     currentStep = widget.step;
+    model = widget.model;
     super.initState();
   }
 
@@ -38,7 +43,7 @@ class _StepScaffoldState extends State<StepScaffold> {
               iconSize: 23,
             ),
             Text(
-              "Exchange XXX to XXX",
+              "Exchange ${model.sendTicker.toUpperCase()} to ${model.receiveTicker.toUpperCase()}",
               style: STextStyles.desktopH3(context),
             ),
           ],

From 3fca3d8b1e9d7ce15a5610c60342f94363e93cf5 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 12:03:15 -0600
Subject: [PATCH 359/426] desktop exchange flow styling and choose addresses
 from addressbook functionality

---
 .../subwidgets/desktop_step_1.dart            |  23 ++-
 .../subwidgets/desktop_step_2.dart            | 139 +++++++++++++-----
 2 files changed, 121 insertions(+), 41 deletions(-)

diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
index 942747ea2..a97b722ef 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
@@ -2,10 +2,13 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -97,8 +100,24 @@ class DesktopStep1 extends ConsumerWidget {
                 child: PrimaryButton(
                   label: "Next",
                   buttonHeight: ButtonHeight.l,
-                  onPressed: () {
-                    // todo
+                  onPressed: () async {
+                    await showDialog<void>(
+                      context: context,
+                      barrierColor: Colors.transparent,
+                      builder: (context) {
+                        return DesktopDialog(
+                          maxWidth: 720,
+                          maxHeight: double.infinity,
+                          child: StepScaffold(
+                            step: 2,
+                            model: model,
+                            body: DesktopStep2(
+                              model: model,
+                            ),
+                          ),
+                        );
+                      },
+                    );
                   },
                 ),
               ),
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 e1c5a5620..38c01822e 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
@@ -2,10 +2,8 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
-import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
-import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
 import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart';
-import 'package:stackwallet/providers/exchange/exchange_flow_is_active_state_provider.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
 import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
@@ -24,6 +22,10 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
+import '../../../../models/contact_address_entry.dart';
+import '../../../../widgets/desktop/desktop_dialog.dart';
+import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
+
 class DesktopStep2 extends ConsumerStatefulWidget {
   const DesktopStep2({
     Key? key,
@@ -105,42 +107,96 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
     }
   }
 
-  void selectRecipientFromAddressBook() {
-    ref.read(exchangeFlowIsActiveStateProvider.state).state = true;
-    Navigator.of(context)
-        .pushNamed(
-      AddressBookView.routeName,
-    )
-        .then((_) {
-      ref.read(exchangeFlowIsActiveStateProvider.state).state = false;
+  void selectRecipientFromAddressBook() async {
+    final coin = coinFromTickerCaseInsensitive(
+      model.receiveTicker,
+    );
 
-      final address =
-          ref.read(exchangeFromAddressBookAddressStateProvider.state).state;
-      if (address.isNotEmpty) {
-        _toController.text = address;
-        model.recipientAddress = _toController.text;
-        ref.read(exchangeFromAddressBookAddressStateProvider.state).state = "";
-      }
-    });
+    final entry = await showDialog<ContactAddressEntry?>(
+      context: context,
+      barrierColor: Colors.transparent,
+      builder: (context) => DesktopDialog(
+        maxWidth: 720,
+        maxHeight: 670,
+        child: Column(
+          mainAxisSize: MainAxisSize.min,
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.only(
+                    left: 32,
+                  ),
+                  child: Text(
+                    "Address book",
+                    style: STextStyles.desktopH3(context),
+                  ),
+                ),
+                const DesktopDialogCloseButton(),
+              ],
+            ),
+            Expanded(
+              child: AddressBookAddressChooser(
+                coin: coin,
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+
+    if (entry != null) {
+      _toController.text = entry.address;
+      model.recipientAddress = entry.address;
+      setState(() {});
+    }
   }
 
-  void selectRefundFromAddressBook() {
-    ref.read(exchangeFlowIsActiveStateProvider.state).state = true;
-    Navigator.of(context)
-        .pushNamed(
-      AddressBookView.routeName,
-    )
-        .then(
-      (_) {
-        ref.read(exchangeFlowIsActiveStateProvider.state).state = false;
-        final address =
-            ref.read(exchangeFromAddressBookAddressStateProvider.state).state;
-        if (address.isNotEmpty) {
-          _refundController.text = address;
-          model.refundAddress = _refundController.text;
-        }
-      },
+  void selectRefundFromAddressBook() async {
+    final coin = coinFromTickerCaseInsensitive(
+      model.sendTicker,
     );
+
+    final entry = await showDialog<ContactAddressEntry?>(
+      context: context,
+      barrierColor: Colors.transparent,
+      builder: (context) => DesktopDialog(
+        maxWidth: 720,
+        maxHeight: 670,
+        child: Column(
+          mainAxisSize: MainAxisSize.min,
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.only(
+                    left: 32,
+                  ),
+                  child: Text(
+                    "Address book",
+                    style: STextStyles.desktopH3(context),
+                  ),
+                ),
+                const DesktopDialogCloseButton(),
+              ],
+            ),
+            Expanded(
+              child: AddressBookAddressChooser(
+                coin: coin,
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+
+    if (entry != null) {
+      _refundController.text = entry.address;
+      model.refundAddress = entry.address;
+      setState(() {});
+    }
   }
 
   @override
@@ -198,10 +254,12 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
   @override
   Widget build(BuildContext context) {
     return Column(
+      crossAxisAlignment: CrossAxisAlignment.stretch,
       children: [
         Text(
           "Enter exchange details",
           style: STextStyles.desktopTextMedium(context),
+          textAlign: TextAlign.center,
         ),
         const SizedBox(
           height: 8,
@@ -209,6 +267,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
         Text(
           "Enter your recipient and refund addresses",
           style: STextStyles.desktopTextExtraExtraSmall(context),
+          textAlign: TextAlign.center,
         ),
         const SizedBox(
           height: 20,
@@ -231,7 +290,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
           ],
         ),
         const SizedBox(
-          height: 4,
+          height: 10,
         ),
         ClipRRect(
           borderRadius: BorderRadius.circular(
@@ -321,9 +380,10 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
           ),
         ),
         const SizedBox(
-          height: 6,
+          height: 10,
         ),
         RoundedWhiteContainer(
+          borderColor: Theme.of(context).extension<StackColors>()!.background,
           child: Text(
             "This is the wallet where your ${model.receiveTicker.toUpperCase()} will be sent to.",
             style: STextStyles.desktopTextExtraExtraSmall(context),
@@ -350,7 +410,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
           ],
         ),
         const SizedBox(
-          height: 4,
+          height: 10,
         ),
         ClipRRect(
           borderRadius: BorderRadius.circular(
@@ -380,6 +440,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
               "Enter ${model.sendTicker.toUpperCase()} refund address",
               _refundFocusNode,
               context,
+              desktopMed: true,
             ).copyWith(
               contentPadding: const EdgeInsets.only(
                 left: 16,
@@ -441,7 +502,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
           ),
         ),
         const SizedBox(
-          height: 6,
+          height: 10,
         ),
         RoundedWhiteContainer(
           borderColor: Theme.of(context).extension<StackColors>()!.background,

From 7e8f0db96726f509bfb9f20ef18de7b1a5021ed8 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 12:07:15 -0600
Subject: [PATCH 360/426] long address layout fix

---
 .../sub_widgets/contact_list_item.dart        | 68 +++++++++++--------
 1 file changed, 40 insertions(+), 28 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
index 7acfaae9e..d7bfefb1f 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
@@ -87,35 +87,47 @@ class _ContactListItemState extends ConsumerState<ContactListItem> {
                         child: Row(
                           mainAxisAlignment: MainAxisAlignment.spaceBetween,
                           children: [
-                            Row(
-                              children: [
-                                WalletInfoCoinIcon(coin: e.coin),
-                                const SizedBox(
-                                  width: 12,
-                                ),
-                                Column(
-                                  mainAxisSize: MainAxisSize.min,
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "${contactId == "default" ? e.other! : e.label} (${e.coin.ticker})",
-                                      style: STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textDark,
-                                      ),
+                            Flexible(
+                              child: Row(
+                                children: [
+                                  WalletInfoCoinIcon(coin: e.coin),
+                                  const SizedBox(
+                                    width: 12,
+                                  ),
+                                  Flexible(
+                                    child: Column(
+                                      mainAxisSize: MainAxisSize.min,
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        Text(
+                                          "${contactId == "default" ? e.other! : e.label} (${e.coin.ticker})",
+                                          style: STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              .copyWith(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark,
+                                          ),
+                                        ),
+                                        Row(
+                                          children: [
+                                            Flexible(
+                                              child: Text(
+                                                e.address,
+                                                style: STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context),
+                                              ),
+                                            ),
+                                          ],
+                                        ),
+                                      ],
                                     ),
-                                    Text(
-                                      e.address,
-                                      style: STextStyles
-                                          .desktopTextExtraExtraSmall(context),
-                                    ),
-                                  ],
-                                ),
-                              ],
+                                  ),
+                                ],
+                              ),
                             ),
                             BlueTextButton(
                               text: "Select wallet",

From 04b982fb250156d3d96e3b44e955a2bd890dfd02 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 13:21:52 -0600
Subject: [PATCH 361/426] desktop exchange choose from stack address ui

---
 .../subwidgets/desktop_step_2.dart            |  50 ++-
 .../subwidgets/desktop_choose_from_stack.dart | 329 ++++++++++++++++++
 2 files changed, 364 insertions(+), 15 deletions(-)
 create mode 100644 lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart

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 38c01822e..270b98fc7 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
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
-import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
 import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
@@ -64,12 +64,21 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
       final coin = coinFromTickerCaseInsensitive(
         model.receiveTicker,
       );
-      Navigator.of(context)
-          .pushNamed(
-        ChooseFromStackView.routeName,
-        arguments: coin,
-      )
-          .then((value) async {
+
+      showDialog<String?>(
+        context: context,
+        barrierColor: Colors.transparent,
+        builder: (context) => DesktopDialog(
+          maxWidth: 720,
+          maxHeight: 670,
+          child: Padding(
+            padding: const EdgeInsets.all(32),
+            child: DesktopChooseFromStack(
+              coin: coin,
+            ),
+          ),
+        ),
+      ).then((value) async {
         if (value is String) {
           final manager =
               ref.read(walletsChangeNotifierProvider).getManager(value);
@@ -88,12 +97,21 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
       final coin = coinFromTickerCaseInsensitive(
         model.sendTicker,
       );
-      Navigator.of(context)
-          .pushNamed(
-        ChooseFromStackView.routeName,
-        arguments: coin,
-      )
-          .then((value) async {
+
+      showDialog<String?>(
+        context: context,
+        barrierColor: Colors.transparent,
+        builder: (context) => DesktopDialog(
+          maxWidth: 720,
+          maxHeight: 670,
+          child: Padding(
+            padding: const EdgeInsets.all(32),
+            child: DesktopChooseFromStack(
+              coin: coin,
+            ),
+          ),
+        ),
+      ).then((value) async {
         if (value is String) {
           final manager =
               ref.read(walletsChangeNotifierProvider).getManager(value);
@@ -366,7 +384,8 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
                                   ? const ClipboardIcon()
                                   : const XIcon(),
                             ),
-                      if (_toController.text.isEmpty)
+                      if (_toController.text.isEmpty &&
+                          isStackCoin(model.receiveTicker))
                         TextFieldIconButton(
                           key: const Key("sendViewAddressBookButtonKey"),
                           onTap: selectRecipientFromAddressBook,
@@ -488,7 +507,8 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
                                   ? const ClipboardIcon()
                                   : const XIcon(),
                             ),
-                      if (_refundController.text.isEmpty)
+                      if (_refundController.text.isEmpty &&
+                          isStackCoin(model.sendTicker))
                         TextFieldIconButton(
                           key: const Key("sendViewAddressBookButtonKey"),
                           onTap: selectRefundFromAddressBook,
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
new file mode 100644
index 000000000..a3fb91f61
--- /dev/null
+++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart
@@ -0,0 +1,329 @@
+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/providers/providers.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/format.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/animated_text.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/x_icon.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+import 'package:stackwallet/widgets/textfield_icon_button.dart';
+import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
+
+class DesktopChooseFromStack extends ConsumerStatefulWidget {
+  const DesktopChooseFromStack({
+    Key? key,
+    required this.coin,
+  }) : super(key: key);
+
+  final Coin coin;
+
+  @override
+  ConsumerState<DesktopChooseFromStack> createState() =>
+      _DesktopChooseFromStackState();
+}
+
+class _DesktopChooseFromStackState
+    extends ConsumerState<DesktopChooseFromStack> {
+  late final TextEditingController _searchController;
+  late final FocusNode searchFieldFocusNode;
+
+  String _searchTerm = "";
+
+  List<String> filter(List<String> walletIds, String searchTerm) {
+    if (searchTerm.isEmpty) {
+      return walletIds;
+    }
+
+    final List<String> result = [];
+    for (final walletId in walletIds) {
+      final manager =
+          ref.read(walletsChangeNotifierProvider).getManager(walletId);
+
+      if (manager.walletName.toLowerCase().contains(searchTerm.toLowerCase())) {
+        result.add(walletId);
+      }
+    }
+
+    return result;
+  }
+
+  @override
+  void initState() {
+    searchFieldFocusNode = FocusNode();
+    _searchController = TextEditingController();
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _searchController.dispose();
+    searchFieldFocusNode.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Text(
+          "Choose from Stack",
+          style: STextStyles.desktopH3(context),
+        ),
+        const SizedBox(
+          height: 28,
+        ),
+        ClipRRect(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
+          ),
+          child: TextField(
+            autocorrect: false,
+            enableSuggestions: false,
+            controller: _searchController,
+            focusNode: searchFieldFocusNode,
+            onChanged: (value) {
+              setState(() {
+                _searchTerm = value;
+              });
+            },
+            style: STextStyles.desktopTextExtraSmall(context).copyWith(
+              color: Theme.of(context)
+                  .extension<StackColors>()!
+                  .textFieldActiveText,
+              height: 1.8,
+            ),
+            decoration: standardInputDecoration(
+              "Search",
+              searchFieldFocusNode,
+              context,
+              desktopMed: true,
+            ).copyWith(
+              prefixIcon: Padding(
+                padding: const EdgeInsets.symmetric(
+                  horizontal: 12,
+                  vertical: 18,
+                ),
+                child: SvgPicture.asset(
+                  Assets.svg.search,
+                  width: 20,
+                  height: 20,
+                ),
+              ),
+              suffixIcon: _searchController.text.isNotEmpty
+                  ? Padding(
+                      padding: const EdgeInsets.only(right: 0),
+                      child: UnconstrainedBox(
+                        child: Row(
+                          children: [
+                            TextFieldIconButton(
+                              child: const XIcon(),
+                              onTap: () async {
+                                setState(() {
+                                  _searchController.text = "";
+                                  _searchTerm = "";
+                                });
+                              },
+                            ),
+                          ],
+                        ),
+                      ),
+                    )
+                  : null,
+            ),
+          ),
+        ),
+        const SizedBox(
+          height: 16,
+        ),
+        Flexible(
+          child: Builder(
+            builder: (context) {
+              List<String> walletIds = ref.watch(
+                walletsChangeNotifierProvider.select(
+                  (value) => value.getWalletIdsFor(coin: widget.coin),
+                ),
+              );
+
+              if (walletIds.isEmpty) {
+                return Column(
+                  children: [
+                    RoundedWhiteContainer(
+                      borderColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .background,
+                      child: Center(
+                        child: Text(
+                          "No ${widget.coin.ticker.toUpperCase()} wallets",
+                          style:
+                              STextStyles.desktopTextExtraExtraSmall(context),
+                        ),
+                      ),
+                    ),
+                  ],
+                );
+              }
+
+              walletIds = filter(walletIds, _searchTerm);
+
+              return ListView.separated(
+                primary: false,
+                itemCount: walletIds.length,
+                separatorBuilder: (_, __) => const SizedBox(
+                  height: 5,
+                ),
+                itemBuilder: (context, index) {
+                  final manager = ref.watch(walletsChangeNotifierProvider
+                      .select((value) => value.getManager(walletIds[index])));
+
+                  return RoundedWhiteContainer(
+                    borderColor:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 20,
+                      vertical: 14,
+                    ),
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.end,
+                      children: [
+                        Row(
+                          children: [
+                            WalletInfoCoinIcon(coin: widget.coin),
+                            const SizedBox(
+                              width: 12,
+                            ),
+                            Text(
+                              manager.walletName,
+                              style: STextStyles.desktopTextExtraExtraSmall(
+                                      context)
+                                  .copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              ),
+                            ),
+                          ],
+                        ),
+                        const Spacer(),
+                        BalanceDisplay(
+                          walletId: walletIds[index],
+                        ),
+                        const SizedBox(
+                          width: 80,
+                        ),
+                        BlueTextButton(
+                          text: "Select wallet",
+                          onTap: () {
+                            Navigator.of(context).pop(manager.walletId);
+                          },
+                        ),
+                      ],
+                    ),
+                  );
+                },
+              );
+            },
+          ),
+        ),
+        const SizedBox(
+          height: 20,
+        ),
+        Row(
+          children: [
+            const Spacer(),
+            const SizedBox(
+              width: 16,
+            ),
+            Expanded(
+              child: SecondaryButton(
+                label: "Cancel",
+                buttonHeight: ButtonHeight.l,
+                onPressed: Navigator.of(context).pop,
+              ),
+            ),
+          ],
+        )
+      ],
+    );
+  }
+}
+
+class BalanceDisplay extends ConsumerStatefulWidget {
+  const BalanceDisplay({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  @override
+  ConsumerState<BalanceDisplay> createState() => _BalanceDisplayState();
+}
+
+class _BalanceDisplayState extends ConsumerState<BalanceDisplay> {
+  late final String walletId;
+
+  Decimal? _cachedBalance;
+
+  static const loopedText = [
+    "Loading balance   ",
+    "Loading balance.  ",
+    "Loading balance.. ",
+    "Loading balance..."
+  ];
+
+  @override
+  void initState() {
+    walletId = widget.walletId;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final manager = ref.watch(walletsChangeNotifierProvider
+        .select((value) => value.getManager(walletId)));
+    final locale = ref.watch(
+        localeServiceChangeNotifierProvider.select((value) => value.locale));
+
+    return FutureBuilder(
+      future: manager.availableBalance,
+      builder: (context, AsyncSnapshot<Decimal> snapshot) {
+        if (snapshot.connectionState == ConnectionState.done &&
+            snapshot.hasData &&
+            snapshot.data != null) {
+          _cachedBalance = snapshot.data;
+        }
+
+        if (_cachedBalance == null) {
+          return AnimatedText(
+            stringsToLoopThrough: loopedText,
+            style: STextStyles.desktopTextExtraSmall(context).copyWith(
+              color: Theme.of(context).extension<StackColors>()!.textSubtitle1,
+            ),
+          );
+        } else {
+          return Text(
+            "${Format.localizedStringAsFixed(
+              value: _cachedBalance!,
+              locale: locale,
+              decimalPlaces: 8,
+            )} ${manager.coin.ticker}",
+            style: STextStyles.desktopTextExtraSmall(context).copyWith(
+              color: Theme.of(context).extension<StackColors>()!.textSubtitle1,
+            ),
+            textAlign: TextAlign.right,
+          );
+        }
+      },
+    );
+  }
+}

From f75e4ea2faf8e71c385aa05732ace062ee90a324 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 14:52:41 -0600
Subject: [PATCH 362/426] desktop delete routing fixes

---
 .../sub_widgets/delete_wallet_button.dart     | 113 ++++++++--
 .../sub_widgets/delete_wallet_keys_popup.dart | 204 +++++++++---------
 .../desktop_attention_delete_wallet.dart      |  27 ++-
 3 files changed, 207 insertions(+), 137 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
index 54f991c37..fd401d613 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
@@ -1,13 +1,13 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
-import 'desktop_delete_wallet_dialog.dart';
-
 class DeleteWalletButton extends ConsumerStatefulWidget {
   const DeleteWalletButton({
     Key? key,
@@ -26,8 +26,6 @@ class _DeleteWalletButton extends ConsumerState<DeleteWalletButton> {
   @override
   void initState() {
     walletId = widget.walletId;
-    final managerProvider =
-        ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
 
     super.initState();
   }
@@ -38,25 +36,45 @@ class _DeleteWalletButton extends ConsumerState<DeleteWalletButton> {
       shape: RoundedRectangleBorder(
         borderRadius: BorderRadius.circular(1000),
       ),
-      onPressed: () {
-        showDialog<void>(
+      onPressed: () async {
+        final shouldOpenDeleteDialog = await showDialog<bool?>(
           context: context,
-          barrierDismissible: false,
-          builder: (context) => Navigator(
-            initialRoute: DesktopDeleteWalletDialog.routeName,
-            onGenerateRoute: RouteGenerator.generateRoute,
-            onGenerateInitialRoutes: (_, __) {
-              return [
-                RouteGenerator.generateRoute(
-                  RouteSettings(
-                    name: DesktopDeleteWalletDialog.routeName,
-                    arguments: walletId,
-                  ),
-                )
-              ];
-            },
-          ),
+          barrierColor: Colors.transparent,
+          builder: (context) {
+            return DeletePopupButton(
+              onTap: () async {
+                Navigator.of(context).pop(true);
+              },
+            );
+          },
         );
+
+        if (shouldOpenDeleteDialog == true) {
+          final result = await showDialog<bool?>(
+            context: context,
+            barrierDismissible: false,
+            builder: (context) => Navigator(
+              initialRoute: DesktopDeleteWalletDialog.routeName,
+              onGenerateRoute: RouteGenerator.generateRoute,
+              onGenerateInitialRoutes: (_, __) {
+                return [
+                  RouteGenerator.generateRoute(
+                    RouteSettings(
+                      name: DesktopDeleteWalletDialog.routeName,
+                      arguments: walletId,
+                    ),
+                  ),
+                ];
+              },
+            ),
+          );
+
+          if (result == true) {
+            if (mounted) {
+              Navigator.of(context).pop();
+            }
+          }
+        }
       },
       child: Padding(
         padding: const EdgeInsets.symmetric(
@@ -79,3 +97,54 @@ class _DeleteWalletButton extends ConsumerState<DeleteWalletButton> {
     );
   }
 }
+
+class DeletePopupButton extends StatefulWidget {
+  const DeletePopupButton({
+    Key? key,
+    this.onTap,
+  }) : super(key: key);
+
+  final VoidCallback? onTap;
+
+  @override
+  State<DeletePopupButton> createState() => _DeletePopupButtonState();
+}
+
+class _DeletePopupButtonState extends State<DeletePopupButton> {
+  @override
+  Widget build(BuildContext context) {
+    return Stack(
+      children: [
+        Positioned(
+          top: 24,
+          left: MediaQuery.of(context).size.width - 234,
+          child: MouseRegion(
+            cursor: SystemMouseCursors.click,
+            child: GestureDetector(
+              onTap: widget.onTap,
+              child: Container(
+                width: 210,
+                height: 70,
+                decoration: BoxDecoration(
+                  borderRadius: BorderRadius.circular(
+                    Constants.size.circularBorderRadius,
+                  ),
+                  color: Colors.red,
+                  boxShadow: [
+                    Theme.of(context)
+                        .extension<StackColors>()!
+                        .standardBoxShadow,
+                  ],
+                ),
+                child: Text(
+                  "Delete",
+                  style: STextStyles.desktopButtonSecondaryEnabled(context),
+                ),
+              ),
+            ),
+          ),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
index f70c2eadf..6b638bb75 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
@@ -1,11 +1,9 @@
-import 'dart:async';
-
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
-import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/providers/global/wallets_service_provider.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -61,8 +59,10 @@ class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
               ),
               DesktopDialogCloseButton(
                 onPressedOverride: () {
-                  int count = 0;
-                  Navigator.of(context).popUntil((_) => count++ >= 2);
+                  Navigator.of(
+                    context,
+                    rootNavigator: true,
+                  ).pop();
                 },
               ),
             ],
@@ -117,106 +117,17 @@ class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
                   child: PrimaryButton(
                     label: "Continue",
                     onPressed: () async {
-                      int count = 0;
-                      Navigator.of(context).popUntil((_) => count++ >= 2);
-
-                      unawaited(
-                        showDialog(
-                            context: context,
-                            builder: (context) {
-                              return DesktopDialog(
-                                maxHeight: 350,
-                                child: Column(
-                                  children: [
-                                    Row(
-                                      mainAxisAlignment: MainAxisAlignment.end,
-                                      children: [
-                                        DesktopDialogCloseButton(
-                                          onPressedOverride: () {
-                                            int count = 0;
-                                            Navigator.of(context)
-                                                .popUntil((_) => count++ >= 2);
-                                          },
-                                        ),
-                                      ],
-                                    ),
-                                    Column(
-                                      crossAxisAlignment:
-                                          CrossAxisAlignment.center,
-                                      children: [
-                                        Text(
-                                          "Thanks! "
-                                          "\n\nYour wallet will be deleted.",
-                                          style: STextStyles.desktopH2(context),
-                                          textAlign: TextAlign.center,
-                                        ),
-                                        const SizedBox(height: 50),
-                                        Row(
-                                          mainAxisAlignment:
-                                              MainAxisAlignment.center,
-                                          children: [
-                                            SecondaryButton(
-                                                width: 250,
-                                                buttonHeight: ButtonHeight.xl,
-                                                label: "Cancel",
-                                                onPressed: () {
-                                                  int count = 0;
-                                                  Navigator.of(context)
-                                                      .popUntil(
-                                                          (_) => count++ >= 2);
-                                                }),
-                                            const SizedBox(width: 16),
-                                            PrimaryButton(
-                                                width: 250,
-                                                buttonHeight: ButtonHeight.xl,
-                                                label: "Continue",
-                                                onPressed: () async {
-                                                  // int count = 0;
-                                                  // Navigator.of(context)
-                                                  //     .popUntil(
-                                                  //         (_) => count++ >= 2);
-
-                                                  final walletsInstance = ref.read(
-                                                      walletsChangeNotifierProvider);
-                                                  final manager = ref
-                                                      .read(
-                                                          walletsChangeNotifierProvider)
-                                                      .getManager(_walletId);
-
-                                                  final _managerWalletId =
-                                                      manager.walletId;
-
-                                                  await ref
-                                                      .read(
-                                                          walletsServiceChangeNotifierProvider)
-                                                      .deleteWallet(
-                                                          manager.walletName,
-                                                          true);
-
-                                                  if (mounted) {
-                                                    Navigator.of(context)
-                                                        .popUntil(
-                                                            ModalRoute.withName(
-                                                                MyStackView
-                                                                    .routeName));
-                                                  }
-
-                                                  // wait for widget tree to dispose of any widgets watching the manager
-                                                  await Future<void>.delayed(
-                                                      const Duration(
-                                                          seconds: 1));
-                                                  walletsInstance.removeWallet(
-                                                      walletId:
-                                                          _managerWalletId);
-                                                }),
-                                          ],
-                                        )
-                                      ],
-                                    ),
-                                  ],
-                                ),
-                              );
-                            }),
+                      await Navigator.of(context).push(
+                        RouteGenerator.getRoute(
+                          builder: (context) {
+                            return ConfirmDelete(
+                              walletId: _walletId,
+                            );
+                          },
+                          settings: const RouteSettings(
+                            name: "/desktopConfirmDelete",
+                          ),
+                        ),
                       );
                     },
                   ),
@@ -232,3 +143,86 @@ class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
     );
   }
 }
+
+class ConfirmDelete extends ConsumerStatefulWidget {
+  const ConfirmDelete({
+    Key? key,
+    required this.walletId,
+  }) : super(key: key);
+
+  final String walletId;
+
+  @override
+  ConsumerState<ConfirmDelete> createState() => _ConfirmDeleteState();
+}
+
+class _ConfirmDeleteState extends ConsumerState<ConfirmDelete> {
+  @override
+  Widget build(BuildContext context) {
+    return DesktopDialog(
+      maxHeight: 350,
+      child: Column(
+        children: [
+          Row(
+            mainAxisAlignment: MainAxisAlignment.end,
+            children: const [
+              DesktopDialogCloseButton(),
+            ],
+          ),
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              Text(
+                "Thanks! "
+                "\n\nYour wallet will be deleted.",
+                style: STextStyles.desktopH2(context),
+                textAlign: TextAlign.center,
+              ),
+              const SizedBox(height: 50),
+              Row(
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: [
+                  SecondaryButton(
+                    width: 250,
+                    buttonHeight: ButtonHeight.xl,
+                    label: "Cancel",
+                    onPressed: () {
+                      Navigator.of(context, rootNavigator: true).pop();
+                    },
+                  ),
+                  const SizedBox(width: 16),
+                  PrimaryButton(
+                    width: 250,
+                    buttonHeight: ButtonHeight.xl,
+                    label: "Continue",
+                    onPressed: () async {
+                      final walletsInstance =
+                          ref.read(walletsChangeNotifierProvider);
+                      final manager = ref
+                          .read(walletsChangeNotifierProvider)
+                          .getManager(widget.walletId);
+
+                      final _managerWalletId = manager.walletId;
+                      //
+                      await ref
+                          .read(walletsServiceChangeNotifierProvider)
+                          .deleteWallet(manager.walletName, true);
+
+                      if (mounted) {
+                        Navigator.of(context, rootNavigator: true).pop(true);
+                      }
+
+                      // wait for widget tree to dispose of any widgets watching the manager
+                      await Future<void>.delayed(const Duration(seconds: 1));
+                      walletsInstance.removeWallet(walletId: _managerWalletId);
+                    },
+                  ),
+                ],
+              ),
+            ],
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart
index 30546f60b..6eb04502e 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart
@@ -41,8 +41,10 @@ class _DesktopAttentionDeleteWallet
             children: [
               DesktopDialogCloseButton(
                 onPressedOverride: () {
-                  int count = 0;
-                  Navigator.of(context).popUntil((_) => count++ >= 2);
+                  Navigator.of(
+                    context,
+                    rootNavigator: true,
+                  ).pop();
                 },
               ),
             ],
@@ -87,8 +89,10 @@ class _DesktopAttentionDeleteWallet
                       buttonHeight: ButtonHeight.xl,
                       label: "Cancel",
                       onPressed: () {
-                        int count = 0;
-                        Navigator.of(context).popUntil((_) => count++ >= 2);
+                        Navigator.of(
+                          context,
+                          rootNavigator: true,
+                        ).pop();
                       },
                     ),
                     const SizedBox(width: 16),
@@ -102,12 +106,15 @@ class _DesktopAttentionDeleteWallet
                             .getManager(widget.walletId)
                             .mnemonic;
 
-                        await Navigator.of(context)
-                            .pushNamed(DeleteWalletKeysPopup.routeName,
-                                arguments: Tuple2(
-                                  widget.walletId,
-                                  words,
-                                ));
+                        if (mounted) {
+                          await Navigator.of(context).pushNamed(
+                            DeleteWalletKeysPopup.routeName,
+                            arguments: Tuple2(
+                              widget.walletId,
+                              words,
+                            ),
+                          );
+                        }
                       },
                     ),
                   ],

From 8a6025db4b308756eaf5cf91d50cdbd1e545a801 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 15:29:09 -0600
Subject: [PATCH 363/426] place node url and port on their own line

---
 .../add_edit_node_view.dart                   | 195 +++++++++---------
 1 file changed, 93 insertions(+), 102 deletions(-)

diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 606c4481f..9062314f0 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -494,6 +494,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
         condition: isDesktop,
         builder: (child) => DesktopDialog(
           maxWidth: 580,
+          maxHeight: 500,
           child: Column(
             mainAxisSize: MainAxisSize.min,
             children: [
@@ -830,110 +831,100 @@ class _NodeFormState extends ConsumerState<NodeForm> {
         const SizedBox(
           height: 8,
         ),
-        Row(
-          children: [
-            Expanded(
-              child: ClipRRect(
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius,
-                ),
-                child: TextField(
-                  autocorrect: Util.isDesktop ? false : true,
-                  enableSuggestions: Util.isDesktop ? false : true,
-                  key: const Key("addCustomNodeNodeAddressFieldKey"),
-                  readOnly: widget.readOnly,
-                  enabled: enableField(_hostController),
-                  controller: _hostController,
-                  focusNode: _hostFocusNode,
-                  style: STextStyles.field(context),
-                  decoration: standardInputDecoration(
-                    (widget.coin != Coin.monero &&
-                            widget.coin != Coin.wownero &&
-                            widget.coin != Coin.epicCash)
-                        ? "IP address"
-                        : "Url",
-                    _hostFocusNode,
-                    context,
-                  ).copyWith(
-                    suffixIcon:
-                        !widget.readOnly && _hostController.text.isNotEmpty
-                            ? Padding(
-                                padding: const EdgeInsets.only(right: 0),
-                                child: UnconstrainedBox(
-                                  child: Row(
-                                    children: [
-                                      TextFieldIconButton(
-                                        child: const XIcon(),
-                                        onTap: () async {
-                                          _hostController.text = "";
-                                          _updateState();
-                                        },
-                                      ),
-                                    ],
-                                  ),
-                                ),
-                              )
-                            : null,
-                  ),
-                  onChanged: (newValue) {
-                    _updateState();
-                    setState(() {});
-                  },
-                ),
-              ),
+        ClipRRect(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
+          ),
+          child: TextField(
+            autocorrect: Util.isDesktop ? false : true,
+            enableSuggestions: Util.isDesktop ? false : true,
+            key: const Key("addCustomNodeNodeAddressFieldKey"),
+            readOnly: widget.readOnly,
+            enabled: enableField(_hostController),
+            controller: _hostController,
+            focusNode: _hostFocusNode,
+            style: STextStyles.field(context),
+            decoration: standardInputDecoration(
+              (widget.coin != Coin.monero &&
+                      widget.coin != Coin.wownero &&
+                      widget.coin != Coin.epicCash)
+                  ? "IP address"
+                  : "Url",
+              _hostFocusNode,
+              context,
+            ).copyWith(
+              suffixIcon: !widget.readOnly && _hostController.text.isNotEmpty
+                  ? Padding(
+                      padding: const EdgeInsets.only(right: 0),
+                      child: UnconstrainedBox(
+                        child: Row(
+                          children: [
+                            TextFieldIconButton(
+                              child: const XIcon(),
+                              onTap: () async {
+                                _hostController.text = "";
+                                _updateState();
+                              },
+                            ),
+                          ],
+                        ),
+                      ),
+                    )
+                  : null,
             ),
-            const SizedBox(
-              width: 12,
+            onChanged: (newValue) {
+              _updateState();
+              setState(() {});
+            },
+          ),
+        ),
+        const SizedBox(
+          height: 8,
+        ),
+        ClipRRect(
+          borderRadius: BorderRadius.circular(
+            Constants.size.circularBorderRadius,
+          ),
+          child: TextField(
+            autocorrect: Util.isDesktop ? false : true,
+            enableSuggestions: Util.isDesktop ? false : true,
+            key: const Key("addCustomNodeNodePortFieldKey"),
+            readOnly: widget.readOnly,
+            enabled: enableField(_portController),
+            controller: _portController,
+            focusNode: _portFocusNode,
+            inputFormatters: [FilteringTextInputFormatter.digitsOnly],
+            keyboardType: TextInputType.number,
+            style: STextStyles.field(context),
+            decoration: standardInputDecoration(
+              "Port",
+              _portFocusNode,
+              context,
+            ).copyWith(
+              suffixIcon: !widget.readOnly && _portController.text.isNotEmpty
+                  ? Padding(
+                      padding: const EdgeInsets.only(right: 0),
+                      child: UnconstrainedBox(
+                        child: Row(
+                          children: [
+                            TextFieldIconButton(
+                              child: const XIcon(),
+                              onTap: () async {
+                                _portController.text = "";
+                                _updateState();
+                              },
+                            ),
+                          ],
+                        ),
+                      ),
+                    )
+                  : null,
             ),
-            Expanded(
-              child: ClipRRect(
-                borderRadius: BorderRadius.circular(
-                  Constants.size.circularBorderRadius,
-                ),
-                child: TextField(
-                  autocorrect: Util.isDesktop ? false : true,
-                  enableSuggestions: Util.isDesktop ? false : true,
-                  key: const Key("addCustomNodeNodePortFieldKey"),
-                  readOnly: widget.readOnly,
-                  enabled: enableField(_portController),
-                  controller: _portController,
-                  focusNode: _portFocusNode,
-                  inputFormatters: [FilteringTextInputFormatter.digitsOnly],
-                  keyboardType: TextInputType.number,
-                  style: STextStyles.field(context),
-                  decoration: standardInputDecoration(
-                    "Port",
-                    _portFocusNode,
-                    context,
-                  ).copyWith(
-                    suffixIcon:
-                        !widget.readOnly && _portController.text.isNotEmpty
-                            ? Padding(
-                                padding: const EdgeInsets.only(right: 0),
-                                child: UnconstrainedBox(
-                                  child: Row(
-                                    children: [
-                                      TextFieldIconButton(
-                                        child: const XIcon(),
-                                        onTap: () async {
-                                          _portController.text = "";
-                                          _updateState();
-                                        },
-                                      ),
-                                    ],
-                                  ),
-                                ),
-                              )
-                            : null,
-                  ),
-                  onChanged: (newValue) {
-                    _updateState();
-                    setState(() {});
-                  },
-                ),
-              ),
-            ),
-          ],
+            onChanged: (newValue) {
+              _updateState();
+              setState(() {});
+            },
+          ),
         ),
         const SizedBox(
           height: 8,

From 66950ccc5059bbf04187180fb7c60665cd892c41 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 21 Nov 2022 14:40:11 -0700
Subject: [PATCH 364/426] delete popup styled

---
 .../sub_widgets/delete_wallet_button.dart     | 22 +++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
index fd401d613..f2553c2da 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
@@ -129,16 +129,30 @@ class _DeletePopupButtonState extends State<DeletePopupButton> {
                   borderRadius: BorderRadius.circular(
                     Constants.size.circularBorderRadius,
                   ),
-                  color: Colors.red,
+                  color: Theme.of(context).extension<StackColors>()!.popupBG,
                   boxShadow: [
                     Theme.of(context)
                         .extension<StackColors>()!
                         .standardBoxShadow,
                   ],
                 ),
-                child: Text(
-                  "Delete",
-                  style: STextStyles.desktopButtonSecondaryEnabled(context),
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.start,
+                  children: [
+                    const SizedBox(width: 24),
+                    SvgPicture.asset(
+                      Assets.svg.trash,
+                    ),
+                    const SizedBox(width: 14),
+                    Text(
+                      "Delete wallet",
+                      style: STextStyles.desktopTextExtraExtraSmall(context)
+                          .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark),
+                    ),
+                  ],
                 ),
               ),
             ),

From e099089d04a3154fbb1cd61fc331d0435e6aeba4 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 21 Nov 2022 14:58:03 -0700
Subject: [PATCH 365/426] loading indicator and delay

---
 .../desktop_delete_wallet_dialog.dart         | 39 +++++++++++++++++--
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
index 087629673..6729d33b9 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
@@ -13,6 +13,7 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 
 import '../../../../../providers/desktop/storage_crypto_handler_provider.dart';
@@ -177,11 +178,35 @@ class _DesktopDeleteWalletDialog
                       label: "Continue",
                       onPressed: _continueEnabled
                           ? () async {
+                              // add loading indicator
+                              unawaited(
+                                showDialog(
+                                  context: context,
+                                  builder: (context) => Column(
+                                    mainAxisAlignment: MainAxisAlignment.center,
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.center,
+                                    children: const [
+                                      LoadingIndicator(
+                                        width: 200,
+                                        height: 200,
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              );
+
+                              await Future<void>.delayed(
+                                  const Duration(seconds: 1));
+
                               final verified = await ref
                                   .read(storageCryptoHandlerProvider)
                                   .verifyPassphrase(passwordController.text);
 
                               if (verified) {
+                                Navigator.of(context, rootNavigator: true)
+                                    .pop();
+
                                 final words = await ref
                                     .read(walletsChangeNotifierProvider)
                                     .getManager(widget.walletId)
@@ -190,12 +215,20 @@ class _DesktopDeleteWalletDialog
                                 if (mounted) {
                                   Navigator.of(context).pop();
 
-                                  await Navigator.of(context).pushNamed(
-                                    DesktopAttentionDeleteWallet.routeName,
-                                    arguments: widget.walletId,
+                                  unawaited(
+                                    Navigator.of(context).pushNamed(
+                                      DesktopAttentionDeleteWallet.routeName,
+                                      arguments: widget.walletId,
+                                    ),
                                   );
                                 }
                               } else {
+                                Navigator.of(context, rootNavigator: true)
+                                    .pop();
+
+                                await Future<void>.delayed(
+                                    const Duration(milliseconds: 300));
+
                                 unawaited(
                                   showFloatingFlushBar(
                                     type: FlushBarType.warning,

From c935c590c7c5635487503e4587f34d94e8f0ae77 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 21 Nov 2022 16:00:00 -0600
Subject: [PATCH 366/426] desktop exchange flow tweaks and show QR code

---
 lib/pages/exchange_view/exchange_form.dart    |  2 +
 .../subwidgets/desktop_step_1.dart            |  1 +
 .../subwidgets/desktop_step_2.dart            | 30 +++++++--
 .../subwidgets/desktop_step_3.dart            | 67 ++++++++++++-------
 .../subwidgets/desktop_step_4.dart            | 49 +++++++++++++-
 .../subwidgets/desktop_step_item.dart         |  1 +
 .../subwidgets/desktop_trade_history.dart     |  2 +
 7 files changed, 121 insertions(+), 31 deletions(-)

diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index 7faa83a35..7f0d9b5d2 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -1024,6 +1024,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
         if (isDesktop) {
           await showDialog<void>(
             context: context,
+            barrierDismissible: false,
             builder: (context) {
               return DesktopDialog(
                 maxWidth: 720,
@@ -1052,6 +1053,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
         if (isDesktop) {
           await showDialog<void>(
             context: context,
+            barrierDismissible: false,
             builder: (context) {
               return DesktopDialog(
                 maxWidth: 720,
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
index a97b722ef..031dc0649 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart
@@ -104,6 +104,7 @@ class DesktopStep1 extends ConsumerWidget {
                     await showDialog<void>(
                       context: context,
                       barrierColor: Colors.transparent,
+                      barrierDismissible: false,
                       builder: (context) {
                         return DesktopDialog(
                           maxWidth: 720,
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 270b98fc7..525d561fc 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
@@ -1,7 +1,10 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/models/contact_address_entry.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
 import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart';
@@ -13,6 +16,8 @@ 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/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
@@ -22,10 +27,6 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-import '../../../../models/contact_address_entry.dart';
-import '../../../../widgets/desktop/desktop_dialog.dart';
-import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
-
 class DesktopStep2 extends ConsumerStatefulWidget {
   const DesktopStep2({
     Key? key,
@@ -552,8 +553,25 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
                 child: PrimaryButton(
                   label: "Next",
                   buttonHeight: ButtonHeight.l,
-                  onPressed: () {
-                    // todo
+                  onPressed: () async {
+                    await showDialog<void>(
+                      context: context,
+                      barrierColor: Colors.transparent,
+                      barrierDismissible: false,
+                      builder: (context) {
+                        return DesktopDialog(
+                          maxWidth: 720,
+                          maxHeight: double.infinity,
+                          child: StepScaffold(
+                            step: 3,
+                            model: model,
+                            body: DesktopStep3(
+                              model: model,
+                            ),
+                          ),
+                        );
+                      },
+                    );
                   },
                 ),
               ),
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
index 65b6ed2b3..284416545 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart
@@ -4,8 +4,9 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
 import 'package:stackwallet/models/exchange/response_objects/trade.dart';
-import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_4_view.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
 import 'package:stackwallet/providers/exchange/current_exchange_name_state_provider.dart';
 import 'package:stackwallet/providers/exchange/exchange_provider.dart';
@@ -16,10 +17,11 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/custom_loading_overlay.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/desktop/simple_desktop_dialog.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
-import 'package:stackwallet/widgets/stack_dialog.dart';
 
 class DesktopStep3 extends ConsumerStatefulWidget {
   const DesktopStep3({
@@ -76,14 +78,15 @@ class _DesktopStep3State extends ConsumerState<DesktopStep3> {
         Navigator.of(context).pop();
       }
 
-      unawaited(showDialog<void>(
-        context: context,
-        barrierDismissible: true,
-        builder: (_) => StackDialog(
-          title: "Failed to create trade",
-          message: response.exception?.toString(),
+      unawaited(
+        showDialog<void>(
+          context: context,
+          barrierDismissible: true,
+          builder: (_) => SimpleDesktopDialog(
+              title: "Failed to create trade",
+              message: response.exception?.toString() ?? ""),
         ),
-      ));
+      );
       return;
     }
 
@@ -106,22 +109,40 @@ class _DesktopStep3State extends ConsumerState<DesktopStep3> {
       Navigator.of(context).pop();
     }
 
-    unawaited(NotificationApi.showNotification(
-      changeNowId: model.trade!.tradeId,
-      title: status,
-      body: "Trade ID ${model.trade!.tradeId}",
-      walletId: "",
-      iconAssetName: Assets.svg.arrowRotate,
-      date: model.trade!.timestamp,
-      shouldWatchForUpdates: true,
-      coinName: "coinName",
-    ));
+    unawaited(
+      NotificationApi.showNotification(
+        changeNowId: model.trade!.tradeId,
+        title: status,
+        body: "Trade ID ${model.trade!.tradeId}",
+        walletId: "",
+        iconAssetName: Assets.svg.arrowRotate,
+        date: model.trade!.timestamp,
+        shouldWatchForUpdates: true,
+        coinName: "coinName",
+      ),
+    );
 
     if (mounted) {
-      unawaited(Navigator.of(context).pushNamed(
-        Step4View.routeName,
-        arguments: model,
-      ));
+      unawaited(
+        showDialog<void>(
+          context: context,
+          barrierColor: Colors.transparent,
+          barrierDismissible: false,
+          builder: (context) {
+            return DesktopDialog(
+              maxWidth: 720,
+              maxHeight: double.infinity,
+              child: StepScaffold(
+                step: 4,
+                model: model,
+                body: DesktopStep4(
+                  model: model,
+                ),
+              ),
+            );
+          },
+        ),
+      );
     }
   }
 
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
index ba9838086..7747f570f 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
@@ -2,12 +2,14 @@ import 'dart:async';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:qr_flutter/qr_flutter.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
 import 'package:stackwallet/providers/providers.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/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
@@ -148,7 +150,7 @@ class _DesktopStep4State extends ConsumerState<DesktopStep4> {
               DesktopStepItem(
                 label: "Amount",
                 value:
-                    "${model.sendAmount.toString()} ${model.sendTicker.toUpperCase()}",
+                    "${model.sendAmount.toStringAsFixed(8)} ${model.sendTicker.toUpperCase()}",
               ),
               Container(
                 height: 1,
@@ -208,7 +210,50 @@ class _DesktopStep4State extends ConsumerState<DesktopStep4> {
                   label: "Show QR code",
                   buttonHeight: ButtonHeight.l,
                   onPressed: () {
-                    // todo
+                    showDialog<dynamic>(
+                      context: context,
+                      barrierColor: Colors.transparent,
+                      barrierDismissible: true,
+                      builder: (_) {
+                        return DesktopDialog(
+                          maxHeight: 720,
+                          maxWidth: 720,
+                          child: Column(
+                            mainAxisAlignment: MainAxisAlignment.center,
+                            crossAxisAlignment: CrossAxisAlignment.center,
+                            children: [
+                              Text(
+                                "Send ${model.sendAmount.toStringAsFixed(8)} ${model.sendTicker} to this address",
+                                style: STextStyles.desktopH3(context),
+                              ),
+                              const SizedBox(
+                                height: 48,
+                              ),
+                              Center(
+                                child: QrImage(
+                                  // TODO: grab coin uri scheme from somewhere
+                                  // data: "${coin.uriScheme}:$receivingAddress",
+                                  data: model.trade!.payInAddress,
+                                  size: 290,
+                                  foregroundColor: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .accentColorDark,
+                                ),
+                              ),
+                              const SizedBox(
+                                height: 48,
+                              ),
+                              SecondaryButton(
+                                label: "Cancel",
+                                width: 310,
+                                buttonHeight: ButtonHeight.l,
+                                onPressed: Navigator.of(context).pop,
+                              ),
+                            ],
+                          ),
+                        );
+                      },
+                    );
                   },
                 ),
               ),
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart
index 7c777c2dd..323517e13 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart
@@ -24,6 +24,7 @@ class DesktopStepItem extends StatelessWidget {
       child: ConditionalParent(
         condition: vertical,
         builder: (child) => Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
           children: [
             child,
             const SizedBox(
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 40eeb8c1b..41bf4246a 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
@@ -31,6 +31,8 @@ class _DesktopTradeHistoryState extends ConsumerState<DesktopTradeHistory> {
 
     if (hasHistory) {
       return ListView.separated(
+        shrinkWrap: true,
+        primary: false,
         itemBuilder: (context, index) {
           return TradeCard(
             key: Key("tradeCard_${trades[index].uuid}"),

From a10958b12d02f0073354cb4402504f46ec75efa9 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 21 Nov 2022 15:08:31 -0700
Subject: [PATCH 367/426] delete popup rounded corner fix

---
 .../wallet_view/sub_widgets/delete_wallet_button.dart           | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
index f2553c2da..a2071e7d6 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_button.dart
@@ -127,7 +127,7 @@ class _DeletePopupButtonState extends State<DeletePopupButton> {
                 height: 70,
                 decoration: BoxDecoration(
                   borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
+                    Constants.size.circularBorderRadius * 2,
                   ),
                   color: Theme.of(context).extension<StackColors>()!.popupBG,
                   boxShadow: [

From 7a650c78d39006620e6ba4f96069feb42f6e1153 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 21 Nov 2022 15:17:26 -0700
Subject: [PATCH 368/426] loading indicator and delay for wallet keys

---
 .../unlock_wallet_keys_desktop.dart           | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
index 23360c98c..739a3ebc4 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
@@ -16,6 +16,7 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 
 class UnlockWalletKeysDesktop extends ConsumerStatefulWidget {
@@ -201,11 +202,32 @@ class _UnlockWalletKeysDesktopState
                     enabled: continueEnabled,
                     onPressed: continueEnabled
                         ? () async {
+                            unawaited(
+                              showDialog(
+                                context: context,
+                                builder: (context) => Column(
+                                  mainAxisAlignment: MainAxisAlignment.center,
+                                  crossAxisAlignment: CrossAxisAlignment.center,
+                                  children: const [
+                                    LoadingIndicator(
+                                      width: 200,
+                                      height: 200,
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            );
+
+                            await Future<void>.delayed(
+                                const Duration(seconds: 1));
+
                             final verified = await ref
                                 .read(storageCryptoHandlerProvider)
                                 .verifyPassphrase(passwordController.text);
 
                             if (verified) {
+                              Navigator.of(context, rootNavigator: true).pop();
+
                               final words = await ref
                                   .read(walletsChangeNotifierProvider)
                                   .getManager(widget.walletId)
@@ -219,6 +241,11 @@ class _UnlockWalletKeysDesktopState
                                 );
                               }
                             } else {
+                              Navigator.of(context, rootNavigator: true).pop();
+
+                              await Future<void>.delayed(
+                                  const Duration(milliseconds: 300));
+
                               unawaited(
                                 showFloatingFlushBar(
                                   type: FlushBarType.warning,

From 675977c787d9d987819852199fefe32882e7bfe6 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 21 Nov 2022 20:33:38 -0700
Subject: [PATCH 369/426] copy to clipboard added to wallet keys dialog

---
 .../sub_widgets/delete_wallet_keys_popup.dart | 40 ++++++++++++++++---
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
index 6b638bb75..70f4a3e13 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
@@ -1,9 +1,15 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/providers/global/wallets_service_provider.dart';
 import 'package:stackwallet/route_generator.dart';
+import 'package:stackwallet/utilities/assets.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/desktop/desktop_dialog.dart';
@@ -16,10 +22,12 @@ class DeleteWalletKeysPopup extends ConsumerStatefulWidget {
     Key? key,
     required this.walletId,
     required this.words,
+    this.clipboardInterface = const ClipboardWrapper(),
   }) : super(key: key);
 
   final String walletId;
   final List<String> words;
+  final ClipboardInterface clipboardInterface;
 
   static const String routeName = "/desktopDeleteWalletKeysPopup";
 
@@ -30,10 +38,14 @@ class DeleteWalletKeysPopup extends ConsumerStatefulWidget {
 
 class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
   late final String _walletId;
+  late final List<String> _words;
+  late final ClipboardInterface _clipboardInterface;
 
   @override
   void initState() {
     _walletId = widget.walletId;
+    _words = widget.words;
+    _clipboardInterface = widget.clipboardInterface;
 
     super.initState();
   }
@@ -96,12 +108,28 @@ class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
             padding: const EdgeInsets.symmetric(
               horizontal: 32,
             ),
-            child: MnemonicTable(
-              words: widget.words,
-              isDesktop: true,
-              itemBorderColor: Theme.of(context)
-                  .extension<StackColors>()!
-                  .buttonBackSecondary,
+            child: RawMaterialButton(
+              hoverColor: Colors.transparent,
+              onPressed: () async {
+                await _clipboardInterface.setData(
+                  ClipboardData(text: _words.join(" ")),
+                );
+                unawaited(
+                  showFloatingFlushBar(
+                    type: FlushBarType.info,
+                    message: "Copied to clipboard",
+                    iconAsset: Assets.svg.copy,
+                    context: context,
+                  ),
+                );
+              },
+              child: MnemonicTable(
+                words: widget.words,
+                isDesktop: true,
+                itemBorderColor: Theme.of(context)
+                    .extension<StackColors>()!
+                    .buttonBackSecondary,
+              ),
             ),
           ),
           const SizedBox(

From 6384d66308066645500f516eca9784163a8285d0 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 21 Nov 2022 20:34:36 -0700
Subject: [PATCH 370/426] added delays for floatingFlushBar in settings change
 password

---
 .../home/settings_menu/security_settings.dart             | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
index f6762afa1..ff7537126 100644
--- a/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/security_settings.dart
@@ -61,6 +61,8 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
 
     if (verified) {
       if (pwNew != pwNewRepeat) {
+        await Future<void>.delayed(const Duration(seconds: 1));
+
         unawaited(
           showFloatingFlushBar(
             type: FlushBarType.warning,
@@ -77,6 +79,8 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
                 );
 
         if (success) {
+          await Future<void>.delayed(const Duration(seconds: 1));
+
           unawaited(
             showFloatingFlushBar(
               type: FlushBarType.success,
@@ -86,6 +90,8 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
           );
           return true;
         } else {
+          await Future<void>.delayed(const Duration(seconds: 1));
+
           unawaited(
             showFloatingFlushBar(
               type: FlushBarType.warning,
@@ -97,6 +103,8 @@ class _SecuritySettings extends ConsumerState<SecuritySettings> {
         }
       }
     } else {
+      await Future<void>.delayed(const Duration(seconds: 1));
+
       unawaited(
         showFloatingFlushBar(
           type: FlushBarType.warning,

From b32e15a3ea1176eb4f77920fa97b46f1d95c3828 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 07:13:03 -0600
Subject: [PATCH 371/426] desktop login on enter pressed

---
 lib/pages_desktop_specific/desktop_login_view.dart | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index f865fad47..eb5dec18a 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -165,6 +165,12 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
                     obscureText: hidePassword,
                     enableSuggestions: false,
                     autocorrect: false,
+                    autofocus: true,
+                    onSubmitted: (_) {
+                      if (_continueEnabled) {
+                        login();
+                      }
+                    },
                     decoration: standardInputDecoration(
                       "Enter password",
                       passwordFocusNode,

From b512b2cefb4663a0075b749c2cc2d4126060717b Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 07:15:08 -0600
Subject: [PATCH 372/426] consistent decimal places on firo balance selection
 sheet

---
 .../firo_balance_selection_sheet.dart         |  4 ++--
 .../wallet_balance_toggle_sheet.dart          | 11 ++++-----
 lib/utilities/constants.dart                  | 24 +++++++++++++++++++
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/lib/pages/send_view/sub_widgets/firo_balance_selection_sheet.dart b/lib/pages/send_view/sub_widgets/firo_balance_selection_sheet.dart
index e639a8cf8..d6de3c6ee 100644
--- a/lib/pages/send_view/sub_widgets/firo_balance_selection_sheet.dart
+++ b/lib/pages/send_view/sub_widgets/firo_balance_selection_sheet.dart
@@ -161,7 +161,7 @@ class _FiroBalanceSelectionSheetState
                                           ConnectionState.done &&
                                       snapshot.hasData) {
                                     return Text(
-                                      "${snapshot.data!} ${manager.coin.ticker}",
+                                      "${snapshot.data!.toStringAsFixed(8)} ${manager.coin.ticker}",
                                       style: STextStyles.itemSubtitle(context),
                                       textAlign: TextAlign.left,
                                     );
@@ -251,7 +251,7 @@ class _FiroBalanceSelectionSheetState
                                           ConnectionState.done &&
                                       snapshot.hasData) {
                                     return Text(
-                                      "${snapshot.data!} ${manager.coin.ticker}",
+                                      "${snapshot.data!.toStringAsFixed(8)} ${manager.coin.ticker}",
                                       style: STextStyles.itemSubtitle(context),
                                       textAlign: TextAlign.left,
                                     );
diff --git a/lib/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart b/lib/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart
index c9ff64393..74308f2e8 100644
--- a/lib/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart
+++ b/lib/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart
@@ -3,14 +3,13 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
+import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
-import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
-
 class WalletBalanceToggleSheet extends ConsumerWidget {
   const WalletBalanceToggleSheet({
     Key? key,
@@ -153,7 +152,7 @@ class WalletBalanceToggleSheet extends ConsumerWidget {
                                       snapshot.hasData &&
                                       snapshot.data != null) {
                                     return Text(
-                                      "${snapshot.data!}",
+                                      "${snapshot.data!.toStringAsFixed(Constants.decimalPlacesForCoin(coin))} ${coin.ticker}",
                                       style: STextStyles.itemSubtitle12(context)
                                           .copyWith(
                                         color: Theme.of(context)
@@ -195,7 +194,7 @@ class WalletBalanceToggleSheet extends ConsumerWidget {
                                       snapshot.hasData &&
                                       snapshot.data != null) {
                                     return Text(
-                                      "${snapshot.data!}",
+                                      "${snapshot.data!.toStringAsFixed(Constants.decimalPlacesForCoin(coin))} ${coin.ticker}",
                                       style: STextStyles.itemSubtitle12(context)
                                           .copyWith(
                                         color: Theme.of(context)
@@ -287,7 +286,7 @@ class WalletBalanceToggleSheet extends ConsumerWidget {
                                       snapshot.hasData &&
                                       snapshot.data != null) {
                                     return Text(
-                                      "${snapshot.data!}",
+                                      "${snapshot.data!.toStringAsFixed(Constants.decimalPlacesForCoin(coin))} ${coin.ticker}",
                                       style: STextStyles.itemSubtitle12(context)
                                           .copyWith(
                                         color: Theme.of(context)
@@ -329,7 +328,7 @@ class WalletBalanceToggleSheet extends ConsumerWidget {
                                       snapshot.hasData &&
                                       snapshot.data != null) {
                                     return Text(
-                                      "${snapshot.data!}",
+                                      "${snapshot.data!.toStringAsFixed(Constants.decimalPlacesForCoin(coin))} ${coin.ticker}",
                                       style: STextStyles.itemSubtitle12(context)
                                           .copyWith(
                                         color: Theme.of(context)
diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart
index e27fbaa3d..0a062de67 100644
--- a/lib/utilities/constants.dart
+++ b/lib/utilities/constants.dart
@@ -40,6 +40,30 @@ abstract class Constants {
 
   static const int currentHiveDbVersion = 3;
 
+  static int decimalPlacesForCoin(Coin coin) {
+    switch (coin) {
+      case Coin.bitcoin:
+      case Coin.litecoin:
+      case Coin.litecoinTestNet:
+      case Coin.bitcoincash:
+      case Coin.bitcoincashTestnet:
+      case Coin.dogecoin:
+      case Coin.firo:
+      case Coin.bitcoinTestNet:
+      case Coin.dogecoinTestNet:
+      case Coin.firoTestNet:
+      case Coin.epicCash:
+      case Coin.namecoin:
+        return decimalPlaces;
+
+      case Coin.wownero:
+        return decimalPlacesWownero;
+
+      case Coin.monero:
+        return decimalPlacesMonero;
+    }
+  }
+
   static List<int> possibleLengthsForCoin(Coin coin) {
     final List<int> values = [];
     switch (coin) {

From 7afe6940f9dc5f20f08eb59e606d8e4cbb452cd4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 08:07:22 -0600
Subject: [PATCH 373/426] desktop trade history details updated

---
 .../exchange_view/trade_details_view.dart     | 186 ++++++++++++++----
 .../subwidgets/desktop_trade_history.dart     | 124 +++++++++++-
 lib/widgets/trade_card.dart                   | 134 +++++++------
 3 files changed, 335 insertions(+), 109 deletions(-)

diff --git a/lib/pages/exchange_view/trade_details_view.dart b/lib/pages/exchange_view/trade_details_view.dart
index 602d588da..f28d1d617 100644
--- a/lib/pages/exchange_view/trade_details_view.dart
+++ b/lib/pages/exchange_view/trade_details_view.dart
@@ -206,16 +206,57 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
               padding: const EdgeInsets.only(
                 right: 12,
               ),
-              child: RoundedWhiteContainer(
-                borderColor: isDesktop
-                    ? Theme.of(context).extension<StackColors>()!.background
-                    : null,
-                padding: const EdgeInsets.all(0),
-                child: ListView(
-                  primary: false,
-                  shrinkWrap: true,
-                  children: children,
-                ),
+              child: Column(
+                mainAxisSize: MainAxisSize.min,
+                children: [
+                  RoundedWhiteContainer(
+                    borderColor:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    padding: const EdgeInsets.all(0),
+                    child: ListView(
+                      primary: false,
+                      shrinkWrap: true,
+                      children: children,
+                    ),
+                  ),
+                  if (isStackCoin(trade.payInCurrency) &&
+                      (trade.status == "New" ||
+                          trade.status == "new" ||
+                          trade.status == "waiting" ||
+                          trade.status == "Waiting"))
+                    const SizedBox(
+                      height: 32,
+                    ),
+                  if (isStackCoin(trade.payInCurrency) &&
+                      (trade.status == "New" ||
+                          trade.status == "new" ||
+                          trade.status == "waiting" ||
+                          trade.status == "Waiting"))
+                    SecondaryButton(
+                      label: "Send from Stack",
+                      buttonHeight: ButtonHeight.l,
+                      onPressed: () {
+                        final amount = sendAmount;
+                        final address = trade.payInAddress;
+
+                        final coin =
+                            coinFromTickerCaseInsensitive(trade.payInCurrency);
+
+                        Navigator.of(context).pushNamed(
+                          SendFromView.routeName,
+                          arguments: Tuple4(
+                            coin,
+                            amount,
+                            address,
+                            trade,
+                          ),
+                        );
+                      },
+                    ),
+                  const SizedBox(
+                    height: 32,
+                  ),
+                ],
               ),
             ),
           ),
@@ -350,33 +391,94 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                 padding: isDesktop
                     ? const EdgeInsets.all(16)
                     : const EdgeInsets.all(12),
-                color: Theme.of(context)
-                    .extension<StackColors>()!
-                    .warningBackground,
-                child: RichText(
-                  text: TextSpan(
-                      text:
-                          "You must send at least ${sendAmount.toStringAsFixed(
-                        trade.payInCurrency.toLowerCase() == "xmr" ? 12 : 8,
-                      )} ${trade.payInCurrency.toUpperCase()}. ",
-                      style: STextStyles.label700(context).copyWith(
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .warningForeground,
-                      ),
-                      children: [
-                        TextSpan(
-                          text:
-                              "If you send less than ${sendAmount.toStringAsFixed(
-                            trade.payInCurrency.toLowerCase() == "xmr" ? 12 : 8,
-                          )} ${trade.payInCurrency.toUpperCase()}, your transaction may not be converted and it may not be refunded.",
-                          style: STextStyles.label(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .warningForeground,
+                color: isDesktop
+                    ? Theme.of(context).extension<StackColors>()!.popupBG
+                    : Theme.of(context)
+                        .extension<StackColors>()!
+                        .warningBackground,
+                child: ConditionalParent(
+                  condition: isDesktop,
+                  builder: (child) => Column(
+                    mainAxisSize: MainAxisSize.min,
+                    children: [
+                      Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
+                            children: [
+                              Text(
+                                "Amount",
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                    context),
+                              ),
+                              const SizedBox(
+                                height: 2,
+                              ),
+                              Text(
+                                "${trade.payInAmount} ${trade.payInCurrency.toUpperCase()}",
+                                style: STextStyles.desktopTextExtraExtraSmall(
+                                        context)
+                                    .copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .textDark,
+                                ),
+                              ),
+                            ],
                           ),
-                        ),
-                      ]),
+                          IconCopyButton(
+                            data: trade.payInAmount,
+                          ),
+                        ],
+                      ),
+                      const SizedBox(
+                        height: 6,
+                      ),
+                      child,
+                    ],
+                  ),
+                  child: RichText(
+                    text: TextSpan(
+                        text:
+                            "You must send at least ${sendAmount.toStringAsFixed(
+                          trade.payInCurrency.toLowerCase() == "xmr" ? 12 : 8,
+                        )} ${trade.payInCurrency.toUpperCase()}. ",
+                        style: isDesktop
+                            ? STextStyles.desktopTextExtraExtraSmall(context)
+                                .copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorRed)
+                            : STextStyles.label(context).copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .warningForeground,
+                              ),
+                        children: [
+                          TextSpan(
+                            text:
+                                "If you send less than ${sendAmount.toStringAsFixed(
+                              trade.payInCurrency.toLowerCase() == "xmr"
+                                  ? 12
+                                  : 8,
+                            )} ${trade.payInCurrency.toUpperCase()}, your transaction may not be converted and it may not be refunded.",
+                            style: isDesktop
+                                ? STextStyles.desktopTextExtraExtraSmall(
+                                        context)
+                                    .copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .accentColorRed)
+                                : STextStyles.label(context).copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .warningForeground,
+                                  ),
+                          ),
+                        ]),
+                  ),
                 ),
               ),
             if (sentFromStack)
@@ -1035,12 +1137,12 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                 ],
               ),
             ),
-            isDesktop
-                ? const _Divider()
-                : const SizedBox(
-                    height: 12,
-                  ),
-            if (isStackCoin(trade.payInCurrency) &&
+            if (!isDesktop)
+              const SizedBox(
+                height: 12,
+              ),
+            if (!isDesktop &&
+                isStackCoin(trade.payInCurrency) &&
                 (trade.status == "New" ||
                     trade.status == "new" ||
                     trade.status == "waiting" ||
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 41bf4246a..a8f825911 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
@@ -10,7 +10,10 @@ import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/trade_card.dart';
-import 'package:tuple/tuple.dart';
+
+import '../../../route_generator.dart';
+import '../../../widgets/desktop/desktop_dialog.dart';
+import '../../../widgets/desktop/desktop_dialog_close_button.dart';
 
 class DesktopTradeHistory extends ConsumerStatefulWidget {
   const DesktopTradeHistory({Key? key}) : super(key: key);
@@ -64,19 +67,122 @@ class _DesktopTradeHistoryState extends ConsumerState<DesktopTradeHistory> {
                 final tx = txData.getAllTransactions()[txid];
 
                 if (mounted) {
-                  unawaited(
-                    Navigator.of(context).pushNamed(
-                      TradeDetailsView.routeName,
-                      arguments: Tuple4(
-                          tradeId, tx, walletIds.first, manager.walletName),
+                  await showDialog<void>(
+                    context: context,
+                    builder: (context) => Navigator(
+                      initialRoute: TradeDetailsView.routeName,
+                      onGenerateRoute: RouteGenerator.generateRoute,
+                      onGenerateInitialRoutes: (_, __) {
+                        return [
+                          FadePageRoute(
+                            DesktopDialog(
+                              // maxHeight:
+                              //     MediaQuery.of(context).size.height - 64,
+                              maxHeight: double.infinity,
+                              maxWidth: 580,
+                              child: Column(
+                                mainAxisSize: MainAxisSize.min,
+                                children: [
+                                  Padding(
+                                    padding: const EdgeInsets.only(
+                                      left: 32,
+                                      bottom: 16,
+                                    ),
+                                    child: Row(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceBetween,
+                                      children: [
+                                        Text(
+                                          "Trade details",
+                                          style: STextStyles.desktopH3(context),
+                                        ),
+                                        DesktopDialogCloseButton(
+                                          onPressedOverride: Navigator.of(
+                                            context,
+                                            rootNavigator: true,
+                                          ).pop,
+                                        ),
+                                      ],
+                                    ),
+                                  ),
+                                  Flexible(
+                                    child: TradeDetailsView(
+                                      tradeId: tradeId,
+                                      transactionIfSentFromStack: tx,
+                                      walletName: manager.walletName,
+                                      walletId: walletIds.first,
+                                    ),
+                                  ),
+                                ],
+                              ),
+                            ),
+                            const RouteSettings(
+                              name: TradeDetailsView.routeName,
+                            ),
+                          ),
+                        ];
+                      },
                     ),
                   );
                 }
               } else {
                 unawaited(
-                  Navigator.of(context).pushNamed(
-                    TradeDetailsView.routeName,
-                    arguments: Tuple4(tradeId, null, walletIds?.first, null),
+                  showDialog<void>(
+                    context: context,
+                    builder: (context) => Navigator(
+                      initialRoute: TradeDetailsView.routeName,
+                      onGenerateRoute: RouteGenerator.generateRoute,
+                      onGenerateInitialRoutes: (_, __) {
+                        return [
+                          FadePageRoute(
+                            DesktopDialog(
+                              // maxHeight:
+                              //     MediaQuery.of(context).size.height - 64,
+                              maxHeight: double.infinity,
+                              maxWidth: 580,
+                              child: Column(
+                                mainAxisSize: MainAxisSize.min,
+                                children: [
+                                  Padding(
+                                    padding: const EdgeInsets.only(
+                                      left: 32,
+                                      bottom: 16,
+                                    ),
+                                    child: Row(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceBetween,
+                                      children: [
+                                        Text(
+                                          "Trade details",
+                                          style: STextStyles.desktopH3(context),
+                                        ),
+                                        DesktopDialogCloseButton(
+                                          onPressedOverride: Navigator.of(
+                                            context,
+                                            rootNavigator: true,
+                                          ).pop,
+                                        ),
+                                      ],
+                                    ),
+                                  ),
+                                  Flexible(
+                                    child: TradeDetailsView(
+                                      tradeId: tradeId,
+                                      transactionIfSentFromStack: null,
+                                      walletName: null,
+                                      walletId: walletIds?.first,
+                                    ),
+                                  ),
+                                ],
+                              ),
+                            ),
+                            const RouteSettings(
+                              name: TradeDetailsView.routeName,
+                            ),
+                          ),
+                        ];
+                      },
+                    ),
                   ),
                 );
               }
diff --git a/lib/widgets/trade_card.dart b/lib/widgets/trade_card.dart
index 0ac8e9346..5a14a0777 100644
--- a/lib/widgets/trade_card.dart
+++ b/lib/widgets/trade_card.dart
@@ -8,6 +8,7 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class TradeCard extends ConsumerWidget {
@@ -49,68 +50,85 @@ class TradeCard extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    return GestureDetector(
-      onTap: onTap,
-      child: RoundedWhiteContainer(
-        child: Row(
-          children: [
-            Container(
-              width: 32,
-              height: 32,
-              decoration: BoxDecoration(
-                borderRadius: BorderRadius.circular(32),
-              ),
-              child: Center(
-                child: SvgPicture.asset(
-                  _fetchIconAssetForStatus(
-                    trade.status,
-                    context,
+    final isDesktop = Util.isDesktop;
+
+    return ConditionalParent(
+      condition: isDesktop,
+      builder: (child) => MouseRegion(
+        cursor: SystemMouseCursors.click,
+        child: child,
+      ),
+      child: GestureDetector(
+        onTap: onTap,
+        child: RoundedWhiteContainer(
+          padding:
+              isDesktop ? const EdgeInsets.all(16) : const EdgeInsets.all(12),
+          child: Row(
+            children: [
+              Container(
+                width: 32,
+                height: 32,
+                decoration: BoxDecoration(
+                  borderRadius: BorderRadius.circular(32),
+                ),
+                child: Center(
+                  child: SvgPicture.asset(
+                    _fetchIconAssetForStatus(
+                      trade.status,
+                      context,
+                    ),
+                    width: 32,
+                    height: 32,
                   ),
-                  width: 32,
-                  height: 32,
                 ),
               ),
-            ),
-            const SizedBox(
-              width: 12,
-            ),
-            Expanded(
-              child: Column(
-                children: [
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "${trade.payInCurrency.toUpperCase()} → ${trade.payOutCurrency.toUpperCase()}",
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
-                      Text(
-                        "${Util.isDesktop ? "-" : ""}${Decimal.tryParse(trade.payInAmount) ?? "..."} ${trade.payInCurrency.toUpperCase()}",
-                        style: STextStyles.itemSubtitle12(context),
-                      ),
-                    ],
-                  ),
-                  const SizedBox(
-                    height: 2,
-                  ),
-                  Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        trade.exchangeName,
-                        style: STextStyles.label(context),
-                      ),
-                      Text(
-                        Format.extractDateFrom(
-                            trade.timestamp.millisecondsSinceEpoch ~/ 1000),
-                        style: STextStyles.label(context),
-                      ),
-                    ],
-                  ),
-                ],
+              const SizedBox(
+                width: 12,
               ),
-            )
-          ],
+              Expanded(
+                child: Column(
+                  children: [
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Text(
+                          "${trade.payInCurrency.toUpperCase()} → ${trade.payOutCurrency.toUpperCase()}",
+                          style: STextStyles.itemSubtitle12(context),
+                        ),
+                        Text(
+                          "${isDesktop ? "-" : ""}${Decimal.tryParse(trade.payInAmount) ?? "..."} ${trade.payInCurrency.toUpperCase()}",
+                          style: STextStyles.itemSubtitle12(context),
+                        ),
+                      ],
+                    ),
+                    const SizedBox(
+                      height: 2,
+                    ),
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        if (!isDesktop)
+                          Text(
+                            trade.exchangeName,
+                            style: STextStyles.label(context),
+                          ),
+                        Text(
+                          Format.extractDateFrom(
+                              trade.timestamp.millisecondsSinceEpoch ~/ 1000),
+                          style: STextStyles.label(context),
+                        ),
+                        if (isDesktop)
+                          Text(
+                            trade.exchangeName,
+                            style: STextStyles.label(context),
+                          ),
+                      ],
+                    ),
+                  ],
+                ),
+              )
+            ],
+          ),
         ),
       ),
     );

From 6552fc913db3d66782eddc02c54f6eb155e7a730 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 09:11:18 -0600
Subject: [PATCH 374/426] WIP send auth for trade transactions

---
 lib/pages/exchange_view/send_from_view.dart   | 281 ++++++++++++++++--
 .../send_view/confirm_transaction_view.dart   |  17 +-
 .../sub_widgets/desktop_auth_send.dart        |  32 +-
 3 files changed, 301 insertions(+), 29 deletions(-)

diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart
index c87175955..59675e4e4 100644
--- a/lib/pages/exchange_view/send_from_view.dart
+++ b/lib/pages/exchange_view/send_from_view.dart
@@ -7,6 +7,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/exchange/response_objects/trade.dart';
 import 'package:stackwallet/pages/exchange_view/confirm_change_now_send.dart';
 import 'package:stackwallet/pages/home_view/home_view.dart';
+import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/route_generator.dart';
@@ -19,13 +20,18 @@ import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/format.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/animated_text.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/expandable.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
+import '../../pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart';
+
 class SendFromView extends ConsumerStatefulWidget {
   const SendFromView({
     Key? key,
@@ -90,21 +96,68 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
     final walletIds = ref.watch(walletsChangeNotifierProvider
         .select((value) => value.getWalletIdsFor(coin: coin)));
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    final isDesktop = Util.isDesktop;
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
+            ),
+            title: Text(
+              "Send from",
+              style: STextStyles.navBarTitle(context),
+            ),
+          ),
+          body: Padding(
+            padding: const EdgeInsets.all(16),
+            child: child,
+          ),
+        );
+      },
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) => DesktopDialog(
+          maxHeight: double.infinity,
+          child: Column(
+            children: [
+              Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Padding(
+                    padding: const EdgeInsets.only(
+                      left: 32,
+                    ),
+                    child: Text(
+                      "Send from Stack",
+                      style: STextStyles.desktopH3(context),
+                    ),
+                  ),
+                  DesktopDialogCloseButton(
+                    onPressedOverride: Navigator.of(
+                      context,
+                      rootNavigator: false,
+                    ).pop,
+                  ),
+                ],
+              ),
+              Padding(
+                padding: const EdgeInsets.only(
+                  left: 32,
+                  right: 32,
+                  bottom: 32,
+                ),
+                child: child,
+              ),
+            ],
+          ),
         ),
-        title: Text(
-          "Send from",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
         child: Column(
           mainAxisAlignment: MainAxisAlignment.start,
           children: [
@@ -112,15 +165,23 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
               children: [
                 Text(
                   "You need to send ${formatAmount(amount, coin)} ${coin.ticker}",
-                  style: STextStyles.itemSubtitle(context),
+                  style: isDesktop
+                      ? STextStyles.desktopTextExtraExtraSmall(context)
+                      : STextStyles.itemSubtitle(context),
                 ),
               ],
             ),
             const SizedBox(
               height: 16,
             ),
-            Expanded(
+            ConditionalParent(
+              condition: !isDesktop,
+              builder: (child) => Expanded(
+                child: child,
+              ),
               child: ListView.builder(
+                primary: isDesktop ? false : null,
+                shrinkWrap: isDesktop,
                 itemCount: walletIds.length,
                 itemBuilder: (context, index) {
                   return Padding(
@@ -339,10 +400,67 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
                     Constants.size.circularBorderRadius,
                   ),
                 ),
-                onPressed: () => _send(
-                  manager,
-                  shouldSendPublicFiroFunds: false,
-                ),
+                onPressed: () async {
+                  final dynamic unlocked;
+
+                  if (Util.isDesktop) {
+                    unlocked = await showDialog<bool?>(
+                      context: context,
+                      builder: (context) => DesktopDialog(
+                        maxWidth: 580,
+                        maxHeight: double.infinity,
+                        child: Column(
+                          mainAxisSize: MainAxisSize.min,
+                          children: [
+                            Row(
+                              mainAxisAlignment: MainAxisAlignment.end,
+                              children: const [
+                                DesktopDialogCloseButton(),
+                              ],
+                            ),
+                            const Padding(
+                              padding: EdgeInsets.only(
+                                left: 32,
+                                right: 32,
+                                bottom: 32,
+                              ),
+                              child: DesktopAuthSend(),
+                            ),
+                          ],
+                        ),
+                      ),
+                    );
+                  } else {
+                    unlocked = await Navigator.push(
+                      context,
+                      RouteGenerator.getRoute(
+                        shouldUseMaterialRoute:
+                            RouteGenerator.useMaterialPageRoute,
+                        builder: (_) => const LockscreenView(
+                          showBackButton: true,
+                          popOnSuccess: true,
+                          routeOnSuccessArguments: true,
+                          routeOnSuccess: "",
+                          biometricsCancelButtonString: "CANCEL",
+                          biometricsLocalizedReason:
+                              "Authenticate to send transaction",
+                          biometricsAuthenticationTitle: "Confirm Transaction",
+                        ),
+                        settings:
+                            const RouteSettings(name: "/confirmsendlockscreen"),
+                      ),
+                    );
+                  }
+
+                  if (unlocked is bool && unlocked && mounted) {
+                    unawaited(
+                      _send(
+                        manager,
+                        shouldSendPublicFiroFunds: false,
+                      ),
+                    );
+                  }
+                },
                 child: Container(
                   color: Colors.transparent,
                   child: Padding(
@@ -418,10 +536,67 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
                     Constants.size.circularBorderRadius,
                   ),
                 ),
-                onPressed: () => _send(
-                  manager,
-                  shouldSendPublicFiroFunds: true,
-                ),
+                onPressed: () async {
+                  final dynamic unlocked;
+
+                  if (Util.isDesktop) {
+                    unlocked = await showDialog<bool?>(
+                      context: context,
+                      builder: (context) => DesktopDialog(
+                        maxWidth: 580,
+                        maxHeight: double.infinity,
+                        child: Column(
+                          mainAxisSize: MainAxisSize.min,
+                          children: [
+                            Row(
+                              mainAxisAlignment: MainAxisAlignment.end,
+                              children: const [
+                                DesktopDialogCloseButton(),
+                              ],
+                            ),
+                            const Padding(
+                              padding: EdgeInsets.only(
+                                left: 32,
+                                right: 32,
+                                bottom: 32,
+                              ),
+                              child: DesktopAuthSend(),
+                            ),
+                          ],
+                        ),
+                      ),
+                    );
+                  } else {
+                    unlocked = await Navigator.push(
+                      context,
+                      RouteGenerator.getRoute(
+                        shouldUseMaterialRoute:
+                            RouteGenerator.useMaterialPageRoute,
+                        builder: (_) => const LockscreenView(
+                          showBackButton: true,
+                          popOnSuccess: true,
+                          routeOnSuccessArguments: true,
+                          routeOnSuccess: "",
+                          biometricsCancelButtonString: "CANCEL",
+                          biometricsLocalizedReason:
+                              "Authenticate to send transaction",
+                          biometricsAuthenticationTitle: "Confirm Transaction",
+                        ),
+                        settings:
+                            const RouteSettings(name: "/confirmsendlockscreen"),
+                      ),
+                    );
+                  }
+
+                  if (unlocked is bool && unlocked && mounted) {
+                    unawaited(
+                      _send(
+                        manager,
+                        shouldSendPublicFiroFunds: true,
+                      ),
+                    );
+                  }
+                },
                 child: Container(
                   color: Colors.transparent,
                   child: Padding(
@@ -504,7 +679,63 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
                 Constants.size.circularBorderRadius,
               ),
             ),
-            onPressed: () => _send(manager),
+            onPressed: () async {
+              final dynamic unlocked;
+
+              if (Util.isDesktop) {
+                unlocked = await showDialog<bool?>(
+                  context: context,
+                  builder: (context) => DesktopDialog(
+                    maxWidth: 580,
+                    maxHeight: double.infinity,
+                    child: Column(
+                      mainAxisSize: MainAxisSize.min,
+                      children: [
+                        Row(
+                          mainAxisAlignment: MainAxisAlignment.end,
+                          children: const [
+                            DesktopDialogCloseButton(),
+                          ],
+                        ),
+                        const Padding(
+                          padding: EdgeInsets.only(
+                            left: 32,
+                            right: 32,
+                            bottom: 32,
+                          ),
+                          child: DesktopAuthSend(),
+                        ),
+                      ],
+                    ),
+                  ),
+                );
+              } else {
+                unlocked = await Navigator.push(
+                  context,
+                  RouteGenerator.getRoute(
+                    shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
+                    builder: (_) => const LockscreenView(
+                      showBackButton: true,
+                      popOnSuccess: true,
+                      routeOnSuccessArguments: true,
+                      routeOnSuccess: "",
+                      biometricsCancelButtonString: "CANCEL",
+                      biometricsLocalizedReason:
+                          "Authenticate to send transaction",
+                      biometricsAuthenticationTitle: "Confirm Transaction",
+                    ),
+                    settings:
+                        const RouteSettings(name: "/confirmsendlockscreen"),
+                  ),
+                );
+              }
+
+              if (unlocked is bool && unlocked && mounted) {
+                unawaited(
+                  _send(manager),
+                );
+              }
+            },
             child: child,
           ),
           child: Row(
diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index 8f7afb0bb..276203804 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -37,6 +37,7 @@ class ConfirmTransactionView extends ConsumerStatefulWidget {
     required this.transactionInfo,
     required this.walletId,
     this.routeOnSuccessName = WalletView.routeName,
+    this.isTradeTransaction = false,
   }) : super(key: key);
 
   static const String routeName = "/confirmTransactionView";
@@ -44,6 +45,7 @@ class ConfirmTransactionView extends ConsumerStatefulWidget {
   final Map<String, dynamic> transactionInfo;
   final String walletId;
   final String routeOnSuccessName;
+  final bool isTradeTransaction;
 
   @override
   ConsumerState<ConfirmTransactionView> createState() =>
@@ -833,8 +835,19 @@ class _ConfirmTransactionViewState
                     );
                   }
 
-                  if (unlocked is bool && unlocked && mounted) {
-                    unawaited(_attemptSend(context));
+                  if (mounted) {
+                    if (unlocked == true) {
+                      unawaited(_attemptSend(context));
+                    } else {
+                      unawaited(
+                        showFloatingFlushBar(
+                            type: FlushBarType.warning,
+                            message: Util.isDesktop
+                                ? "Invalid passphrase"
+                                : "Invalid PIN",
+                            context: context),
+                      );
+                    }
                   }
                 },
               ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
index 9f863c8a4..a8d1ea497 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
@@ -10,6 +12,9 @@ import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 
+import '../../../../../notifications/show_flush_bar.dart';
+import '../../../../../widgets/loading_indicator.dart';
+
 class DesktopAuthSend extends ConsumerStatefulWidget {
   const DesktopAuthSend({Key? key}) : super(key: key);
 
@@ -155,12 +160,35 @@ class _DesktopAuthSendState extends ConsumerState<DesktopAuthSend> {
                 label: "Confirm",
                 buttonHeight: ButtonHeight.l,
                 onPressed: () async {
-                  // TODO show spinner while verifying passphrase
+                  unawaited(
+                    showDialog<void>(
+                      context: context,
+                      builder: (context) => Column(
+                        mainAxisAlignment: MainAxisAlignment.center,
+                        crossAxisAlignment: CrossAxisAlignment.center,
+                        children: const [
+                          LoadingIndicator(
+                            width: 200,
+                            height: 200,
+                          ),
+                        ],
+                      ),
+                    ),
+                  );
+
+                  await Future<void>.delayed(const Duration(seconds: 1));
 
                   final passwordIsValid = await verifyPassphrase();
 
                   if (mounted) {
-                    Navigator.of(context).pop(passwordIsValid);
+                    Navigator.of(context).pop();
+                    Navigator.of(
+                      context,
+                      rootNavigator: true,
+                    ).pop(passwordIsValid);
+                    await Future<void>.delayed(const Duration(
+                      milliseconds: 100,
+                    ));
                   }
                 },
               ),

From 0bdf337ffbeed8c7ebb8a3aa00271c6ccadbacf1 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 11:21:43 -0600
Subject: [PATCH 375/426] WIP send from stack desktop trade transaction
 navigation

---
 .../confirm_change_now_send.dart              | 842 ++++++++++++------
 lib/pages/exchange_view/send_from_view.dart   | 196 +---
 .../exchange_view/trade_details_view.dart     |   7 +-
 .../subwidgets/desktop_step_2.dart            |  92 +-
 .../subwidgets/desktop_step_4.dart            |  36 +-
 5 files changed, 700 insertions(+), 473 deletions(-)

diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index e99cf2df4..9f62bd8ec 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -7,15 +7,23 @@ import 'package:stackwallet/models/trade_wallet_lookup.dart';
 import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/sending_transaction_dialog.dart';
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart';
 import 'package:stackwallet/providers/exchange/trade_sent_from_stack_lookup_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
+import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -52,14 +60,16 @@ class _ConfirmChangeNowSendViewState
   late final Trade trade;
 
   Future<void> _attemptSend(BuildContext context) async {
-    unawaited(showDialog<void>(
-      context: context,
-      useSafeArea: false,
-      barrierDismissible: false,
-      builder: (context) {
-        return const SendingTransactionDialog();
-      },
-    ));
+    unawaited(
+      showDialog<void>(
+        context: context,
+        useSafeArea: false,
+        barrierDismissible: false,
+        builder: (context) {
+          return const SendingTransactionDialog();
+        },
+      ),
+    );
 
     final String note = transactionInfo["note"] as String? ?? "";
     final manager =
@@ -93,6 +103,9 @@ class _ConfirmChangeNowSendViewState
 
       // pop back to wallet
       if (mounted) {
+        if (Util.isDesktop) {
+          Navigator.of(context, rootNavigator: true).pop();
+        }
         Navigator.of(context).popUntil(ModalRoute.withName(routeOnSuccessName));
       }
     } catch (e) {
@@ -129,6 +142,60 @@ class _ConfirmChangeNowSendViewState
     }
   }
 
+  Future<void> _confirmSend() async {
+    final dynamic unlocked;
+
+    if (Util.isDesktop) {
+      unlocked = await showDialog<bool?>(
+        context: context,
+        builder: (context) => DesktopDialog(
+          maxWidth: 580,
+          maxHeight: double.infinity,
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              Row(
+                mainAxisAlignment: MainAxisAlignment.end,
+                children: const [
+                  DesktopDialogCloseButton(),
+                ],
+              ),
+              const Padding(
+                padding: EdgeInsets.only(
+                  left: 32,
+                  right: 32,
+                  bottom: 32,
+                ),
+                child: DesktopAuthSend(),
+              ),
+            ],
+          ),
+        ),
+      );
+    } else {
+      unlocked = await Navigator.push(
+        context,
+        RouteGenerator.getRoute(
+          shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
+          builder: (_) => const LockscreenView(
+            showBackButton: true,
+            popOnSuccess: true,
+            routeOnSuccessArguments: true,
+            routeOnSuccess: "",
+            biometricsCancelButtonString: "CANCEL",
+            biometricsLocalizedReason: "Authenticate to send transaction",
+            biometricsAuthenticationTitle: "Confirm Transaction",
+          ),
+          settings: const RouteSettings(name: "/confirmsendlockscreen"),
+        ),
+      );
+    }
+
+    if (unlocked is bool && unlocked && mounted) {
+      await _attemptSend(context);
+    }
+  }
+
   @override
   void initState() {
     transactionInfo = widget.transactionInfo;
@@ -142,280 +209,503 @@ class _ConfirmChangeNowSendViewState
   Widget build(BuildContext context) {
     final managerProvider = ref.watch(walletsChangeNotifierProvider
         .select((value) => value.getManagerProvider(walletId)));
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: 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(Duration(milliseconds: 50));
-            // }
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Confirm transaction",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (builderContext, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        Text(
-                          "Send ${ref.watch(managerProvider.select((value) => value.coin)).ticker}",
-                          style: STextStyles.pageTitleH1(context),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.stretch,
-                            children: [
-                              Text(
-                                "Send from",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              Text(
-                                ref
-                                    .watch(walletsChangeNotifierProvider)
-                                    .getManager(walletId)
-                                    .walletName,
-                                style: STextStyles.itemSubtitle12(context),
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.stretch,
-                            children: [
-                              Text(
-                                "${trade.exchangeName} address",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              Text(
-                                "${transactionInfo["address"] ?? "ERROR"}",
-                                style: STextStyles.itemSubtitle12(context),
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "Amount",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              Text(
-                                "${Format.satoshiAmountToPrettyString(
-                                  transactionInfo["recipientAmt"] as int,
-                                  ref.watch(
-                                    localeServiceChangeNotifierProvider
-                                        .select((value) => value.locale),
-                                  ),
-                                )} ${ref.watch(
-                                      managerProvider
-                                          .select((value) => value.coin),
-                                    ).ticker}",
-                                style: STextStyles.itemSubtitle12(context),
-                                textAlign: TextAlign.right,
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "Transaction fee",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              Text(
-                                "${Format.satoshiAmountToPrettyString(
-                                  transactionInfo["fee"] as int,
-                                  ref.watch(
-                                    localeServiceChangeNotifierProvider
-                                        .select((value) => value.locale),
-                                  ),
-                                )} ${ref.watch(
-                                      managerProvider
-                                          .select((value) => value.coin),
-                                    ).ticker}",
-                                style: STextStyles.itemSubtitle12(context),
-                                textAlign: TextAlign.right,
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.stretch,
-                            children: [
-                              Text(
-                                "Note",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              Text(
-                                transactionInfo["note"] as String? ?? "",
-                                style: STextStyles.itemSubtitle12(context),
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "Trade ID",
-                                style: STextStyles.smallMed12(context),
-                              ),
-                              Text(
-                                trade.tradeId,
-                                style: STextStyles.itemSubtitle12(context),
-                                textAlign: TextAlign.right,
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedContainer(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .snackBarBackSuccess,
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "Total amount",
-                                style:
-                                    STextStyles.titleBold12(context).copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textConfirmTotalAmount,
-                                ),
-                              ),
-                              Text(
-                                "${Format.satoshiAmountToPrettyString(
-                                  (transactionInfo["fee"] as int) +
-                                      (transactionInfo["recipientAmt"] as int),
-                                  ref.watch(
-                                    localeServiceChangeNotifierProvider
-                                        .select((value) => value.locale),
-                                  ),
-                                )} ${ref.watch(
-                                      managerProvider
-                                          .select((value) => value.coin),
-                                    ).ticker}",
-                                style: STextStyles.itemSubtitle12(context)
-                                    .copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textConfirmTotalAmount,
-                                ),
-                                textAlign: TextAlign.right,
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        const Spacer(),
-                        TextButton(
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context),
-                          onPressed: () async {
-                            final unlocked = await Navigator.push(
-                              context,
-                              RouteGenerator.getRoute(
-                                shouldUseMaterialRoute:
-                                    RouteGenerator.useMaterialPageRoute,
-                                builder: (_) => const LockscreenView(
-                                  showBackButton: true,
-                                  popOnSuccess: true,
-                                  routeOnSuccessArguments: true,
-                                  routeOnSuccess: "",
-                                  biometricsCancelButtonString: "CANCEL",
-                                  biometricsLocalizedReason:
-                                      "Authenticate to send transaction",
-                                  biometricsAuthenticationTitle:
-                                      "Confirm Transaction",
-                                ),
-                                settings: const RouteSettings(
-                                    name: "/confirmsendlockscreen"),
-                              ),
-                            );
 
-                            if (unlocked is bool && unlocked && mounted) {
-                              await _attemptSend(context);
-                            }
-                          },
-                          child: Text(
-                            "Send",
-                            style: STextStyles.button(context),
-                          ),
-                        ),
-                      ],
+    final isDesktop = Util.isDesktop;
+
+    return ConditionalParent(
+      condition: !isDesktop,
+      builder: (child) {
+        return Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: 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(Duration(milliseconds: 50));
+                // }
+                Navigator.of(context).pop();
+              },
+            ),
+            title: Text(
+              "Confirm transaction",
+              style: STextStyles.navBarTitle(context),
+            ),
+          ),
+          body: LayoutBuilder(
+            builder: (builderContext, constraints) {
+              return Padding(
+                padding: const EdgeInsets.only(
+                  left: 12,
+                  top: 12,
+                  right: 12,
+                ),
+                child: SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight - 24,
+                    ),
+                    child: IntrinsicHeight(
+                      child: Padding(
+                        padding: const EdgeInsets.all(4),
+                        child: child,
+                      ),
                     ),
                   ),
                 ),
+              );
+            },
+          ),
+        );
+      },
+      child: ConditionalParent(
+        condition: isDesktop,
+        builder: (child) => DesktopDialog(
+          maxHeight: double.infinity,
+          maxWidth: 580,
+          child: Column(
+            children: [
+              Row(
+                children: [
+                  const SizedBox(
+                    width: 6,
+                  ),
+                  const AppBarBackButton(
+                    isCompact: true,
+                    iconSize: 23,
+                  ),
+                  const SizedBox(
+                    width: 12,
+                  ),
+                  Text(
+                    "Confirm ${ref.watch(managerProvider.select((value) => value.coin)).ticker} transaction",
+                    style: STextStyles.desktopH3(context),
+                  )
+                ],
+              ),
+              Padding(
+                padding: const EdgeInsets.only(
+                  left: 32,
+                  right: 32,
+                  bottom: 32,
+                ),
+                child: Column(
+                  children: [
+                    RoundedWhiteContainer(
+                      padding: const EdgeInsets.all(0),
+                      borderColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .background,
+                      child: child,
+                    ),
+                    const SizedBox(
+                      height: 16,
+                    ),
+                    Row(
+                      children: [
+                        Text(
+                          "Transaction fee",
+                          style:
+                              STextStyles.desktopTextExtraExtraSmall(context),
+                        ),
+                      ],
+                    ),
+                    const SizedBox(
+                      height: 10,
+                    ),
+                    RoundedContainer(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textFieldDefaultBG,
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.end,
+                        children: [
+                          Text(
+                            "${Format.satoshiAmountToPrettyString(
+                              (transactionInfo["fee"] as int),
+                              ref.watch(
+                                localeServiceChangeNotifierProvider
+                                    .select((value) => value.locale),
+                              ),
+                            )} ${ref.watch(
+                                  managerProvider.select((value) => value.coin),
+                                ).ticker}",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context)
+                                    .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark,
+                            ),
+                          ),
+                        ],
+                      ),
+                    ),
+                    const SizedBox(
+                      height: 16,
+                    ),
+                    RoundedContainer(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .snackBarBackSuccess,
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          Text(
+                            "Total amount",
+                            style: STextStyles.titleBold12(context).copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textConfirmTotalAmount,
+                            ),
+                          ),
+                          Text(
+                            "${Format.satoshiAmountToPrettyString(
+                              (transactionInfo["fee"] as int) +
+                                  (transactionInfo["recipientAmt"] as int),
+                              ref.watch(
+                                localeServiceChangeNotifierProvider
+                                    .select((value) => value.locale),
+                              ),
+                            )} ${ref.watch(
+                                  managerProvider.select((value) => value.coin),
+                                ).ticker}",
+                            style: STextStyles.itemSubtitle12(context).copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textConfirmTotalAmount,
+                            ),
+                            textAlign: TextAlign.right,
+                          ),
+                        ],
+                      ),
+                    ),
+                    const SizedBox(
+                      height: 16,
+                    ),
+                    Row(
+                      children: [
+                        Expanded(
+                          child: SecondaryButton(
+                            label: "Cancel",
+                            buttonHeight: ButtonHeight.l,
+                            onPressed: Navigator.of(context).pop,
+                          ),
+                        ),
+                        const SizedBox(
+                          width: 16,
+                        ),
+                        Expanded(
+                          child: PrimaryButton(
+                            label: "Send",
+                            buttonHeight: isDesktop ? ButtonHeight.l : null,
+                            onPressed: _confirmSend,
+                          ),
+                        ),
+                      ],
+                    )
+                  ],
+                ),
+              ),
+            ],
+          ),
+        ),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: [
+            ConditionalParent(
+              condition: isDesktop,
+              builder: (child) => Container(
+                decoration: BoxDecoration(
+                  color: Theme.of(context).extension<StackColors>()!.background,
+                  borderRadius: BorderRadius.vertical(
+                    top: Radius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
+                  ),
+                ),
+                child: Padding(
+                  padding: const EdgeInsets.all(12),
+                  child: Row(
+                    children: [
+                      child,
+                    ],
+                  ),
+                ),
+              ),
+              child: Text(
+                "Send ${ref.watch(managerProvider.select((value) => value.coin)).ticker}",
+                style: isDesktop
+                    ? STextStyles.desktopTextMedium(context)
+                    : STextStyles.pageTitleH1(context),
               ),
             ),
-          );
-        },
+            isDesktop
+                ? Container(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    height: 1,
+                  )
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: [
+                  Text(
+                    "Send from",
+                    style: STextStyles.smallMed12(context),
+                  ),
+                  const SizedBox(
+                    height: 4,
+                  ),
+                  Text(
+                    ref
+                        .watch(walletsChangeNotifierProvider)
+                        .getManager(walletId)
+                        .walletName,
+                    style: STextStyles.itemSubtitle12(context),
+                  ),
+                ],
+              ),
+            ),
+            isDesktop
+                ? Container(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    height: 1,
+                  )
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: [
+                  Text(
+                    "${trade.exchangeName} address",
+                    style: STextStyles.smallMed12(context),
+                  ),
+                  const SizedBox(
+                    height: 4,
+                  ),
+                  Text(
+                    "${transactionInfo["address"] ?? "ERROR"}",
+                    style: STextStyles.itemSubtitle12(context),
+                  ),
+                ],
+              ),
+            ),
+            isDesktop
+                ? Container(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    height: 1,
+                  )
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Text(
+                    "Amount",
+                    style: STextStyles.smallMed12(context),
+                  ),
+                  ConditionalParent(
+                    condition: isDesktop,
+                    builder: (child) => Row(
+                      children: [
+                        child,
+                        Builder(builder: (context) {
+                          final coin = ref.watch(
+                              walletsChangeNotifierProvider.select(
+                                  (value) => value.getManager(walletId).coin));
+                          final price = ref.watch(
+                              priceAnd24hChangeNotifierProvider
+                                  .select((value) => value.getPrice(coin)));
+                          final amount = Format.satoshisToAmount(
+                            transactionInfo["recipientAmt"] as int,
+                            coin: coin,
+                          );
+                          final value = price.item1 * amount;
+                          final currency = ref.watch(prefsChangeNotifierProvider
+                              .select((value) => value.currency));
+
+                          return Text(
+                            " | ${value.toStringAsFixed(Constants.decimalPlacesForCoin(coin))} $currency",
+                            style:
+                                STextStyles.desktopTextExtraExtraSmall(context)
+                                    .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textSubtitle2,
+                            ),
+                          );
+                        })
+                      ],
+                    ),
+                    child: Text(
+                      "${Format.satoshiAmountToPrettyString(
+                        transactionInfo["recipientAmt"] as int,
+                        ref.watch(
+                          localeServiceChangeNotifierProvider
+                              .select((value) => value.locale),
+                        ),
+                      )} ${ref.watch(
+                            managerProvider.select((value) => value.coin),
+                          ).ticker}",
+                      style: STextStyles.itemSubtitle12(context),
+                      textAlign: TextAlign.right,
+                    ),
+                  ),
+                ],
+              ),
+            ),
+            isDesktop
+                ? Container(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    height: 1,
+                  )
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Text(
+                    "Transaction fee",
+                    style: STextStyles.smallMed12(context),
+                  ),
+                  Text(
+                    "${Format.satoshiAmountToPrettyString(
+                      transactionInfo["fee"] as int,
+                      ref.watch(
+                        localeServiceChangeNotifierProvider
+                            .select((value) => value.locale),
+                      ),
+                    )} ${ref.watch(
+                          managerProvider.select((value) => value.coin),
+                        ).ticker}",
+                    style: STextStyles.itemSubtitle12(context),
+                    textAlign: TextAlign.right,
+                  ),
+                ],
+              ),
+            ),
+            isDesktop
+                ? Container(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    height: 1,
+                  )
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: [
+                  Text(
+                    "Note",
+                    style: STextStyles.smallMed12(context),
+                  ),
+                  const SizedBox(
+                    height: 4,
+                  ),
+                  Text(
+                    transactionInfo["note"] as String? ?? "",
+                    style: STextStyles.itemSubtitle12(context),
+                  ),
+                ],
+              ),
+            ),
+            isDesktop
+                ? Container(
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    height: 1,
+                  )
+                : const SizedBox(
+                    height: 12,
+                  ),
+            RoundedWhiteContainer(
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                children: [
+                  Text(
+                    "Trade ID",
+                    style: STextStyles.smallMed12(context),
+                  ),
+                  Text(
+                    trade.tradeId,
+                    style: STextStyles.itemSubtitle12(context),
+                    textAlign: TextAlign.right,
+                  ),
+                ],
+              ),
+            ),
+            if (!isDesktop)
+              const SizedBox(
+                height: 12,
+              ),
+            if (!isDesktop)
+              RoundedContainer(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .snackBarBackSuccess,
+                child: Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Text(
+                      "Total amount",
+                      style: STextStyles.titleBold12(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textConfirmTotalAmount,
+                      ),
+                    ),
+                    Text(
+                      "${Format.satoshiAmountToPrettyString(
+                        (transactionInfo["fee"] as int) +
+                            (transactionInfo["recipientAmt"] as int),
+                        ref.watch(
+                          localeServiceChangeNotifierProvider
+                              .select((value) => value.locale),
+                        ),
+                      )} ${ref.watch(
+                            managerProvider.select((value) => value.coin),
+                          ).ticker}",
+                      style: STextStyles.itemSubtitle12(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textConfirmTotalAmount,
+                      ),
+                      textAlign: TextAlign.right,
+                    ),
+                  ],
+                ),
+              ),
+            if (!isDesktop)
+              const SizedBox(
+                height: 16,
+              ),
+            if (!isDesktop) const Spacer(),
+            if (!isDesktop)
+              PrimaryButton(
+                label: "Send",
+                buttonHeight: isDesktop ? ButtonHeight.l : null,
+                onPressed: _confirmSend,
+              ),
+          ],
+        ),
       ),
     );
   }
diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart
index 59675e4e4..7cbf38384 100644
--- a/lib/pages/exchange_view/send_from_view.dart
+++ b/lib/pages/exchange_view/send_from_view.dart
@@ -7,8 +7,8 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/exchange/response_objects/trade.dart';
 import 'package:stackwallet/pages/exchange_view/confirm_change_now_send.dart';
 import 'package:stackwallet/pages/home_view/home_view.dart';
-import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart';
 import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart';
+import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
@@ -30,8 +30,6 @@ import 'package:stackwallet/widgets/expandable.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
-import '../../pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart';
-
 class SendFromView extends ConsumerStatefulWidget {
   const SendFromView({
     Key? key,
@@ -39,6 +37,7 @@ class SendFromView extends ConsumerStatefulWidget {
     required this.trade,
     required this.amount,
     required this.address,
+    this.shouldPopRoot = false,
   }) : super(key: key);
 
   static const String routeName = "/sendFrom";
@@ -47,6 +46,7 @@ class SendFromView extends ConsumerStatefulWidget {
   final Decimal amount;
   final String address;
   final Trade trade;
+  final bool shouldPopRoot;
 
   @override
   ConsumerState<SendFromView> createState() => _SendFromViewState();
@@ -142,7 +142,7 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
                   DesktopDialogCloseButton(
                     onPressedOverride: Navigator.of(
                       context,
-                      rootNavigator: false,
+                      rootNavigator: widget.shouldPopRoot,
                     ).pop,
                   ),
                 ],
@@ -239,12 +239,23 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
           useSafeArea: false,
           barrierDismissible: false,
           builder: (context) {
-            return BuildingTransactionDialog(
-              onCancel: () {
-                wasCancelled = true;
+            return ConditionalParent(
+              condition: Util.isDesktop,
+              builder: (child) => DesktopDialog(
+                maxWidth: 400,
+                maxHeight: double.infinity,
+                child: Padding(
+                  padding: const EdgeInsets.all(32),
+                  child: child,
+                ),
+              ),
+              child: BuildingTransactionDialog(
+                onCancel: () {
+                  wasCancelled = true;
 
-                Navigator.of(context).pop();
-              },
+                  Navigator.of(context).pop();
+                },
+              ),
             );
           },
         ),
@@ -290,7 +301,10 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
         // pop building dialog
 
         if (mounted) {
-          Navigator.of(context).pop();
+          Navigator.of(
+            context,
+            rootNavigator: Util.isDesktop,
+          ).pop();
         }
 
         txData["note"] =
@@ -304,7 +318,9 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
               builder: (_) => ConfirmChangeNowSendView(
                 transactionInfo: txData,
                 walletId: walletId,
-                routeOnSuccessName: HomeView.routeName,
+                routeOnSuccessName: Util.isDesktop
+                    ? DesktopExchangeView.routeName
+                    : HomeView.routeName,
                 trade: trade,
                 shouldSendPublicFiroFunds: shouldSendPublicFiroFunds,
               ),
@@ -401,58 +417,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
                   ),
                 ),
                 onPressed: () async {
-                  final dynamic unlocked;
-
-                  if (Util.isDesktop) {
-                    unlocked = await showDialog<bool?>(
-                      context: context,
-                      builder: (context) => DesktopDialog(
-                        maxWidth: 580,
-                        maxHeight: double.infinity,
-                        child: Column(
-                          mainAxisSize: MainAxisSize.min,
-                          children: [
-                            Row(
-                              mainAxisAlignment: MainAxisAlignment.end,
-                              children: const [
-                                DesktopDialogCloseButton(),
-                              ],
-                            ),
-                            const Padding(
-                              padding: EdgeInsets.only(
-                                left: 32,
-                                right: 32,
-                                bottom: 32,
-                              ),
-                              child: DesktopAuthSend(),
-                            ),
-                          ],
-                        ),
-                      ),
-                    );
-                  } else {
-                    unlocked = await Navigator.push(
-                      context,
-                      RouteGenerator.getRoute(
-                        shouldUseMaterialRoute:
-                            RouteGenerator.useMaterialPageRoute,
-                        builder: (_) => const LockscreenView(
-                          showBackButton: true,
-                          popOnSuccess: true,
-                          routeOnSuccessArguments: true,
-                          routeOnSuccess: "",
-                          biometricsCancelButtonString: "CANCEL",
-                          biometricsLocalizedReason:
-                              "Authenticate to send transaction",
-                          biometricsAuthenticationTitle: "Confirm Transaction",
-                        ),
-                        settings:
-                            const RouteSettings(name: "/confirmsendlockscreen"),
-                      ),
-                    );
-                  }
-
-                  if (unlocked is bool && unlocked && mounted) {
+                  if (mounted) {
                     unawaited(
                       _send(
                         manager,
@@ -537,58 +502,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
                   ),
                 ),
                 onPressed: () async {
-                  final dynamic unlocked;
-
-                  if (Util.isDesktop) {
-                    unlocked = await showDialog<bool?>(
-                      context: context,
-                      builder: (context) => DesktopDialog(
-                        maxWidth: 580,
-                        maxHeight: double.infinity,
-                        child: Column(
-                          mainAxisSize: MainAxisSize.min,
-                          children: [
-                            Row(
-                              mainAxisAlignment: MainAxisAlignment.end,
-                              children: const [
-                                DesktopDialogCloseButton(),
-                              ],
-                            ),
-                            const Padding(
-                              padding: EdgeInsets.only(
-                                left: 32,
-                                right: 32,
-                                bottom: 32,
-                              ),
-                              child: DesktopAuthSend(),
-                            ),
-                          ],
-                        ),
-                      ),
-                    );
-                  } else {
-                    unlocked = await Navigator.push(
-                      context,
-                      RouteGenerator.getRoute(
-                        shouldUseMaterialRoute:
-                            RouteGenerator.useMaterialPageRoute,
-                        builder: (_) => const LockscreenView(
-                          showBackButton: true,
-                          popOnSuccess: true,
-                          routeOnSuccessArguments: true,
-                          routeOnSuccess: "",
-                          biometricsCancelButtonString: "CANCEL",
-                          biometricsLocalizedReason:
-                              "Authenticate to send transaction",
-                          biometricsAuthenticationTitle: "Confirm Transaction",
-                        ),
-                        settings:
-                            const RouteSettings(name: "/confirmsendlockscreen"),
-                      ),
-                    );
-                  }
-
-                  if (unlocked is bool && unlocked && mounted) {
+                  if (mounted) {
                     unawaited(
                       _send(
                         manager,
@@ -680,57 +594,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
               ),
             ),
             onPressed: () async {
-              final dynamic unlocked;
-
-              if (Util.isDesktop) {
-                unlocked = await showDialog<bool?>(
-                  context: context,
-                  builder: (context) => DesktopDialog(
-                    maxWidth: 580,
-                    maxHeight: double.infinity,
-                    child: Column(
-                      mainAxisSize: MainAxisSize.min,
-                      children: [
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.end,
-                          children: const [
-                            DesktopDialogCloseButton(),
-                          ],
-                        ),
-                        const Padding(
-                          padding: EdgeInsets.only(
-                            left: 32,
-                            right: 32,
-                            bottom: 32,
-                          ),
-                          child: DesktopAuthSend(),
-                        ),
-                      ],
-                    ),
-                  ),
-                );
-              } else {
-                unlocked = await Navigator.push(
-                  context,
-                  RouteGenerator.getRoute(
-                    shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
-                    builder: (_) => const LockscreenView(
-                      showBackButton: true,
-                      popOnSuccess: true,
-                      routeOnSuccessArguments: true,
-                      routeOnSuccess: "",
-                      biometricsCancelButtonString: "CANCEL",
-                      biometricsLocalizedReason:
-                          "Authenticate to send transaction",
-                      biometricsAuthenticationTitle: "Confirm Transaction",
-                    ),
-                    settings:
-                        const RouteSettings(name: "/confirmsendlockscreen"),
-                  ),
-                );
-              }
-
-              if (unlocked is bool && unlocked && mounted) {
+              if (mounted) {
                 unawaited(
                   _send(manager),
                 );
diff --git a/lib/pages/exchange_view/trade_details_view.dart b/lib/pages/exchange_view/trade_details_view.dart
index f28d1d617..0b7f4b502 100644
--- a/lib/pages/exchange_view/trade_details_view.dart
+++ b/lib/pages/exchange_view/trade_details_view.dart
@@ -219,7 +219,8 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                       children: children,
                     ),
                   ),
-                  if (isStackCoin(trade.payInCurrency) &&
+                  if (!hasTx &&
+                      isStackCoin(trade.payInCurrency) &&
                       (trade.status == "New" ||
                           trade.status == "new" ||
                           trade.status == "waiting" ||
@@ -227,7 +228,8 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                     const SizedBox(
                       height: 32,
                     ),
-                  if (isStackCoin(trade.payInCurrency) &&
+                  if (!hasTx &&
+                      isStackCoin(trade.payInCurrency) &&
                       (trade.status == "New" ||
                           trade.status == "new" ||
                           trade.status == "waiting" ||
@@ -1142,6 +1144,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                 height: 12,
               ),
             if (!isDesktop &&
+                !hasTx &&
                 isStackCoin(trade.payInCurrency) &&
                 (trade.status == "New" ||
                     trade.status == "new" ||
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 525d561fc..7b793210c 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
@@ -51,6 +51,8 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
   late final FocusNode _toFocusNode;
   late final FocusNode _refundFocusNode;
 
+  bool enableNext = false;
+
   bool isStackCoin(String ticker) {
     try {
       coinFromTickerCaseInsensitive(ticker);
@@ -60,13 +62,13 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
     }
   }
 
-  void selectRecipientAddressFromStack() {
+  void selectRecipientAddressFromStack() async {
     try {
       final coin = coinFromTickerCaseInsensitive(
         model.receiveTicker,
       );
 
-      showDialog<String?>(
+      final address = await showDialog<String?>(
         context: context,
         barrierColor: Colors.transparent,
         builder: (context) => DesktopDialog(
@@ -79,27 +81,31 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
             ),
           ),
         ),
-      ).then((value) async {
-        if (value is String) {
-          final manager =
-              ref.read(walletsChangeNotifierProvider).getManager(value);
+      );
 
-          _toController.text = manager.walletName;
-          model.recipientAddress = await manager.currentReceivingAddress;
-        }
-      });
+      if (address is String) {
+        final manager =
+            ref.read(walletsChangeNotifierProvider).getManager(address);
+
+        _toController.text = manager.walletName;
+        model.recipientAddress = await manager.currentReceivingAddress;
+      }
     } catch (e, s) {
       Logging.instance.log("$e\n$s", level: LogLevel.Info);
     }
+    setState(() {
+      enableNext =
+          _toController.text.isNotEmpty && _refundController.text.isNotEmpty;
+    });
   }
 
-  void selectRefundAddressFromStack() {
+  void selectRefundAddressFromStack() async {
     try {
       final coin = coinFromTickerCaseInsensitive(
         model.sendTicker,
       );
 
-      showDialog<String?>(
+      final address = await showDialog<String?>(
         context: context,
         barrierColor: Colors.transparent,
         builder: (context) => DesktopDialog(
@@ -112,18 +118,21 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
             ),
           ),
         ),
-      ).then((value) async {
-        if (value is String) {
-          final manager =
-              ref.read(walletsChangeNotifierProvider).getManager(value);
+      );
+      if (address is String) {
+        final manager =
+            ref.read(walletsChangeNotifierProvider).getManager(address);
 
-          _refundController.text = manager.walletName;
-          model.refundAddress = await manager.currentReceivingAddress;
-        }
-      });
+        _refundController.text = manager.walletName;
+        model.refundAddress = await manager.currentReceivingAddress;
+      }
     } catch (e, s) {
       Logging.instance.log("$e\n$s", level: LogLevel.Info);
     }
+    setState(() {
+      enableNext =
+          _toController.text.isNotEmpty && _refundController.text.isNotEmpty;
+    });
   }
 
   void selectRecipientFromAddressBook() async {
@@ -168,7 +177,10 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
     if (entry != null) {
       _toController.text = entry.address;
       model.recipientAddress = entry.address;
-      setState(() {});
+      setState(() {
+        enableNext =
+            _toController.text.isNotEmpty && _refundController.text.isNotEmpty;
+      });
     }
   }
 
@@ -214,7 +226,10 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
     if (entry != null) {
       _refundController.text = entry.address;
       model.refundAddress = entry.address;
-      setState(() {});
+      setState(() {
+        enableNext =
+            _toController.text.isNotEmpty && _refundController.text.isNotEmpty;
+      });
     }
   }
 
@@ -334,7 +349,10 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
             focusNode: _toFocusNode,
             style: STextStyles.field(context),
             onChanged: (value) {
-              setState(() {});
+              setState(() {
+                enableNext = _toController.text.isNotEmpty &&
+                    _refundController.text.isNotEmpty;
+              });
             },
             decoration: standardInputDecoration(
               "Enter the ${model.receiveTicker.toUpperCase()} payout address",
@@ -363,7 +381,10 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
                               onTap: () {
                                 _toController.text = "";
                                 model.recipientAddress = _toController.text;
-                                setState(() {});
+                                setState(() {
+                                  enableNext = _toController.text.isNotEmpty &&
+                                      _refundController.text.isNotEmpty;
+                                });
                               },
                               child: const XIcon(),
                             )
@@ -378,7 +399,11 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
                                   final content = data.text!.trim();
                                   _toController.text = content;
                                   model.recipientAddress = _toController.text;
-                                  setState(() {});
+                                  setState(() {
+                                    enableNext =
+                                        _toController.text.isNotEmpty &&
+                                            _refundController.text.isNotEmpty;
+                                  });
                                 }
                               },
                               child: _toController.text.isEmpty
@@ -454,7 +479,10 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
             focusNode: _refundFocusNode,
             style: STextStyles.field(context),
             onChanged: (value) {
-              setState(() {});
+              setState(() {
+                enableNext = _toController.text.isNotEmpty &&
+                    _refundController.text.isNotEmpty;
+              });
             },
             decoration: standardInputDecoration(
               "Enter ${model.sendTicker.toUpperCase()} refund address",
@@ -484,7 +512,10 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
                                 _refundController.text = "";
                                 model.refundAddress = _refundController.text;
 
-                                setState(() {});
+                                setState(() {
+                                  enableNext = _toController.text.isNotEmpty &&
+                                      _refundController.text.isNotEmpty;
+                                });
                               },
                               child: const XIcon(),
                             )
@@ -501,7 +532,11 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
                                   _refundController.text = content;
                                   model.refundAddress = _refundController.text;
 
-                                  setState(() {});
+                                  setState(() {
+                                    enableNext =
+                                        _toController.text.isNotEmpty &&
+                                            _refundController.text.isNotEmpty;
+                                  });
                                 }
                               },
                               child: _refundController.text.isEmpty
@@ -552,6 +587,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
               Expanded(
                 child: PrimaryButton(
                   label: "Next",
+                  enabled: enableNext,
                   buttonHeight: ButtonHeight.l,
                   onPressed: () async {
                     await showDialog<void>(
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
index 7747f570f..c86713a76 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
@@ -1,11 +1,14 @@
 import 'dart:async';
 
+import 'package:decimal/decimal.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:qr_flutter/qr_flutter.dart';
 import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
+import 'package:stackwallet/pages/exchange_view/send_from_view.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -199,7 +202,38 @@ class _DesktopStep4State extends ConsumerState<DesktopStep4> {
                 child: SecondaryButton(
                   label: "Send from Stack Wallet",
                   buttonHeight: ButtonHeight.l,
-                  onPressed: Navigator.of(context).pop,
+                  onPressed: () {
+                    final trade = model.trade!;
+                    final amount = Decimal.parse(trade.payInAmount);
+                    final address = trade.payInAddress;
+
+                    final coin =
+                        coinFromTickerCaseInsensitive(trade.payInCurrency);
+
+                    showDialog<void>(
+                      context: context,
+                      builder: (context) => Navigator(
+                        initialRoute: SendFromView.routeName,
+                        onGenerateRoute: RouteGenerator.generateRoute,
+                        onGenerateInitialRoutes: (_, __) {
+                          return [
+                            FadePageRoute(
+                              SendFromView(
+                                coin: coin,
+                                trade: trade,
+                                amount: amount,
+                                address: address,
+                                shouldPopRoot: true,
+                              ),
+                              const RouteSettings(
+                                name: SendFromView.routeName,
+                              ),
+                            ),
+                          ];
+                        },
+                      ),
+                    );
+                  },
                 ),
               ),
               const SizedBox(

From c5c0443d000d425b86056d27dda575a3b895fde6 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 22 Nov 2022 08:57:05 -0700
Subject: [PATCH 376/426] button sizing fix

---
 .../home/settings_menu/currency_settings/currency_settings.dart | 2 +-
 .../home/settings_menu/language_settings/language_settings.dart | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
index d9c20d8fa..9f5f42b7c 100644
--- a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -107,7 +107,7 @@ class _CurrencySettings extends ConsumerState<CurrencySettings> {
                         10,
                       ),
                       child: PrimaryButton(
-                        width: 210,
+                        width: 200,
                         buttonHeight: ButtonHeight.m,
                         enabled: true,
                         label: "Change currency",
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
index acddcb055..3c511236c 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
@@ -84,7 +84,7 @@ class _LanguageOptionSettings extends ConsumerState<LanguageOptionSettings> {
                         10,
                       ),
                       child: PrimaryButton(
-                        width: 210,
+                        width: 200,
                         buttonHeight: ButtonHeight.m,
                         enabled: true,
                         label: "Change language",

From 9a47ce349e52a12d2be80ab7f48ede2b9ca7f379 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 22 Nov 2022 11:48:47 -0700
Subject: [PATCH 377/426] submit on enter passphrase

---
 .../desktop_attention_delete_wallet.dart      |   3 +-
 .../desktop_delete_wallet_dialog.dart         | 126 +++++++++---------
 2 files changed, 66 insertions(+), 63 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart
index 6eb04502e..a614be3a6 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -10,8 +11,6 @@ import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:tuple/tuple.dart';
 
-import 'delete_wallet_keys_popup.dart';
-
 class DesktopAttentionDeleteWallet extends ConsumerStatefulWidget {
   const DesktopAttentionDeleteWallet({
     Key? key,
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
index 6729d33b9..e8d9c2dc5 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_delete_wallet_dialog.dart
@@ -5,6 +5,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_attention_delete_wallet.dart';
+import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -16,9 +18,6 @@ import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 
-import '../../../../../providers/desktop/storage_crypto_handler_provider.dart';
-import '../../../../../providers/global/wallets_provider.dart';
-
 class DesktopDeleteWalletDialog extends ConsumerStatefulWidget {
   const DesktopDeleteWalletDialog({
     Key? key,
@@ -42,6 +41,62 @@ class _DesktopDeleteWalletDialog
   bool hidePassword = true;
   bool _continueEnabled = false;
 
+  Future<void> enterPassphrase() async {
+    unawaited(
+      showDialog(
+        context: context,
+        builder: (context) => Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: const [
+            LoadingIndicator(
+              width: 200,
+              height: 200,
+            ),
+          ],
+        ),
+      ),
+    );
+
+    await Future<void>.delayed(const Duration(seconds: 1));
+
+    final verified = await ref
+        .read(storageCryptoHandlerProvider)
+        .verifyPassphrase(passwordController.text);
+
+    if (verified) {
+      Navigator.of(context, rootNavigator: true).pop();
+
+      final words = await ref
+          .read(walletsChangeNotifierProvider)
+          .getManager(widget.walletId)
+          .mnemonic;
+
+      if (mounted) {
+        Navigator.of(context).pop();
+
+        unawaited(
+          Navigator.of(context).pushNamed(
+            DesktopAttentionDeleteWallet.routeName,
+            arguments: widget.walletId,
+          ),
+        );
+      }
+    } else {
+      Navigator.of(context, rootNavigator: true).pop();
+
+      await Future<void>.delayed(const Duration(milliseconds: 300));
+
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "Invalid passphrase!",
+          context: context,
+        ),
+      );
+    }
+  }
+
   @override
   void initState() {
     passwordController = TextEditingController();
@@ -106,6 +161,12 @@ class _DesktopDeleteWalletDialog
                     obscureText: hidePassword,
                     enableSuggestions: false,
                     autocorrect: false,
+                    autofocus: true,
+                    onSubmitted: (_) {
+                      if (_continueEnabled) {
+                        enterPassphrase();
+                      }
+                    },
                     decoration: standardInputDecoration(
                       "Enter password",
                       passwordFocusNode,
@@ -179,64 +240,7 @@ class _DesktopDeleteWalletDialog
                       onPressed: _continueEnabled
                           ? () async {
                               // add loading indicator
-                              unawaited(
-                                showDialog(
-                                  context: context,
-                                  builder: (context) => Column(
-                                    mainAxisAlignment: MainAxisAlignment.center,
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.center,
-                                    children: const [
-                                      LoadingIndicator(
-                                        width: 200,
-                                        height: 200,
-                                      ),
-                                    ],
-                                  ),
-                                ),
-                              );
-
-                              await Future<void>.delayed(
-                                  const Duration(seconds: 1));
-
-                              final verified = await ref
-                                  .read(storageCryptoHandlerProvider)
-                                  .verifyPassphrase(passwordController.text);
-
-                              if (verified) {
-                                Navigator.of(context, rootNavigator: true)
-                                    .pop();
-
-                                final words = await ref
-                                    .read(walletsChangeNotifierProvider)
-                                    .getManager(widget.walletId)
-                                    .mnemonic;
-
-                                if (mounted) {
-                                  Navigator.of(context).pop();
-
-                                  unawaited(
-                                    Navigator.of(context).pushNamed(
-                                      DesktopAttentionDeleteWallet.routeName,
-                                      arguments: widget.walletId,
-                                    ),
-                                  );
-                                }
-                              } else {
-                                Navigator.of(context, rootNavigator: true)
-                                    .pop();
-
-                                await Future<void>.delayed(
-                                    const Duration(milliseconds: 300));
-
-                                unawaited(
-                                  showFloatingFlushBar(
-                                    type: FlushBarType.warning,
-                                    message: "Invalid passphrase!",
-                                    context: context,
-                                  ),
-                                );
-                              }
+                              enterPassphrase();
                             }
                           : null,
                     ),

From 8e2ff3883d3516ee561d9acb36a89a5de94a0400 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 14:42:24 -0600
Subject: [PATCH 378/426] exchange amount field re style

---
 lib/pages/exchange_view/exchange_form.dart    | 362 ++---------------
 .../textfields/exchange_textfield.dart        | 384 ++++++++++++++++++
 2 files changed, 424 insertions(+), 322 deletions(-)
 create mode 100644 lib/widgets/textfields/exchange_textfield.dart

diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index 7f0d9b5d2..921b35bf0 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -2,7 +2,6 @@ import 'dart:async';
 
 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:flutter_svg/svg.dart';
@@ -25,6 +24,7 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
 import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
 import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -37,10 +37,10 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/desktop/simple_desktop_dialog.dart';
-import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
+import 'package:stackwallet/widgets/textfields/exchange_textfield.dart';
 import 'package:tuple/tuple.dart';
 
 class ExchangeForm extends ConsumerStatefulWidget {
@@ -1226,146 +1226,33 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
         SizedBox(
           height: isDesktop ? 10 : 4,
         ),
-        TextFormField(
-          style: STextStyles.smallMed14(context).copyWith(
+        ExchangeTextField(
+          controller: _sendController,
+          focusNode: _sendFocusNode,
+          textStyle: STextStyles.smallMed14(context).copyWith(
             color: Theme.of(context).extension<StackColors>()!.textDark,
           ),
-          focusNode: _sendFocusNode,
-          controller: _sendController,
-          textAlign: TextAlign.right,
-          enableSuggestions: false,
-          autocorrect: false,
+          buttonColor:
+              Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
+          borderRadius: Constants.size.circularBorderRadius,
+          background:
+              Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
           onTap: () {
             if (_sendController.text == "-") {
               _sendController.text = "";
             }
           },
           onChanged: sendFieldOnChanged,
-          keyboardType: const TextInputType.numberWithOptions(
-            signed: false,
-            decimal: true,
-          ),
-          inputFormatters: [
-            // regex to validate a crypto amount with 8 decimal places
-            TextInputFormatter.withFunction((oldValue, newValue) =>
-                RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
-                        .hasMatch(newValue.text)
-                    ? newValue
-                    : oldValue),
-          ],
-          decoration: InputDecoration(
-            contentPadding: const EdgeInsets.only(
-              top: 12,
-              right: 12,
-            ),
-            hintText: "0",
-            hintStyle: STextStyles.fieldLabel(context).copyWith(
-              fontSize: 14,
-            ),
-            prefixIcon: FittedBox(
-              fit: BoxFit.scaleDown,
-              alignment: Alignment.centerLeft,
-              child: GestureDetector(
-                onTap: selectSendCurrency,
-                child: Container(
-                  color: Colors.transparent,
-                  child: Padding(
-                    padding: const EdgeInsets.all(12),
-                    child: Row(
-                      children: [
-                        Container(
-                          width: 18,
-                          height: 18,
-                          decoration: BoxDecoration(
-                            borderRadius: BorderRadius.circular(18),
-                          ),
-                          child: Builder(
-                            builder: (context) {
-                              final image = _fetchIconUrlFromTicker(ref.watch(
-                                  exchangeFormStateProvider
-                                      .select((value) => value.fromTicker)));
-
-                              if (image != null && image.isNotEmpty) {
-                                return Center(
-                                  child: SvgPicture.network(
-                                    image,
-                                    height: 18,
-                                    placeholderBuilder: (_) => Container(
-                                      width: 18,
-                                      height: 18,
-                                      decoration: BoxDecoration(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textFieldDefaultBG,
-                                        borderRadius: BorderRadius.circular(
-                                          18,
-                                        ),
-                                      ),
-                                      child: ClipRRect(
-                                        borderRadius: BorderRadius.circular(
-                                          18,
-                                        ),
-                                        child: const LoadingIndicator(),
-                                      ),
-                                    ),
-                                  ),
-                                );
-                              } else {
-                                return Container(
-                                  width: 18,
-                                  height: 18,
-                                  decoration: BoxDecoration(
-                                    // color: Theme.of(context).extension<StackColors>()!.accentColorDark
-                                    borderRadius: BorderRadius.circular(18),
-                                  ),
-                                  child: SvgPicture.asset(
-                                    Assets.svg.circleQuestion,
-                                    width: 18,
-                                    height: 18,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textFieldDefaultBG,
-                                  ),
-                                );
-                              }
-                            },
-                          ),
-                        ),
-                        const SizedBox(
-                          width: 6,
-                        ),
-                        Text(
-                          ref.watch(exchangeFormStateProvider.select((value) =>
-                                  value.fromTicker?.toUpperCase())) ??
-                              "-",
-                          style: STextStyles.smallMed14(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark,
-                          ),
-                        ),
-                        if (!isWalletCoin(coin, true))
-                          const SizedBox(
-                            width: 6,
-                          ),
-                        if (!isWalletCoin(coin, true))
-                          SvgPicture.asset(
-                            Assets.svg.chevronDown,
-                            width: 5,
-                            height: 2.5,
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark,
-                          ),
-                      ],
-                    ),
-                  ),
-                ),
-              ),
-            ),
-          ),
+          onButtonTap: selectSendCurrency,
+          isWalletCoin: isWalletCoin(coin, true),
+          image: _fetchIconUrlFromTicker(ref.watch(
+              exchangeFormStateProvider.select((value) => value.fromTicker))),
+          ticker: ref.watch(
+              exchangeFormStateProvider.select((value) => value.fromTicker)),
+        ),
+        SizedBox(
+          height: isDesktop ? 10 : 4,
         ),
-
         SizedBox(
           height: isDesktop ? 10 : 4,
         ),
@@ -1422,79 +1309,20 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
             ),
           ],
         ),
-        // Stack(
-        //   children: [
-        //     Positioned.fill(
-        //       child: Align(
-        //         alignment: Alignment.bottomLeft,
-        //         child: Text(
-        //           "You will receive",
-        //           style: STextStyles.itemSubtitle(context).copyWith(
-        //             color:
-        //                 Theme.of(context).extension<StackColors>()!.textDark3,
-        //           ),
-        //         ),
-        //       ),
-        //     ),
-        //     Center(
-        //       child: Column(
-        //         children: [
-        //           const SizedBox(
-        //             height: 6,
-        //           ),
-        //           GestureDetector(
-        //             onTap: () async {
-        //               await _swap();
-        //             },
-        //             child: Padding(
-        //               padding: const EdgeInsets.all(4),
-        //               child: SvgPicture.asset(
-        //                 Assets.svg.swap,
-        //                 width: 20,
-        //                 height: 20,
-        //                 color: Theme.of(context)
-        //                     .extension<StackColors>()!
-        //                     .accentColorDark,
-        //               ),
-        //             ),
-        //           ),
-        //           const SizedBox(
-        //             height: 6,
-        //           ),
-        //         ],
-        //       ),
-        //     ),
-        //     Positioned.fill(
-        //       child: Align(
-        //         alignment: ref.watch(exchangeFormStateProvider
-        //                 .select((value) => value.reversed))
-        //             ? Alignment.bottomRight
-        //             : Alignment.topRight,
-        //         child: Text(
-        //           ref.watch(exchangeFormStateProvider
-        //               .select((value) => value.warning)),
-        //           style: STextStyles.errorSmall(context),
-        //         ),
-        //       ),
-        //     ),
-        //   ],
-        // ),
         SizedBox(
           height: isDesktop ? 10 : 4,
         ),
-        TextFormField(
-          style: STextStyles.smallMed14(context).copyWith(
-            color: Theme.of(context).extension<StackColors>()!.textDark,
-          ),
+        ExchangeTextField(
           focusNode: _receiveFocusNode,
           controller: _receiveController,
-          enableSuggestions: false,
-          autocorrect: false,
-          readOnly: ref.watch(prefsChangeNotifierProvider
-                      .select((value) => value.exchangeRateType)) ==
-                  ExchangeRateType.estimated ||
-              ref.watch(exchangeProvider).name ==
-                  SimpleSwapExchange.exchangeName,
+          textStyle: STextStyles.smallMed14(context).copyWith(
+            color: Theme.of(context).extension<StackColors>()!.textDark,
+          ),
+          buttonColor:
+              Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
+          borderRadius: Constants.size.circularBorderRadius,
+          background:
+              Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
           onTap: () {
             if (!(ref.read(prefsChangeNotifierProvider).exchangeRateType ==
                     ExchangeRateType.estimated) &&
@@ -1503,127 +1331,17 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
             }
           },
           onChanged: receiveFieldOnChanged,
-          textAlign: TextAlign.right,
-          keyboardType: const TextInputType.numberWithOptions(
-            signed: false,
-            decimal: true,
-          ),
-          inputFormatters: [
-            // regex to validate a crypto amount with 8 decimal places
-            TextInputFormatter.withFunction((oldValue, newValue) =>
-                RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
-                        .hasMatch(newValue.text)
-                    ? newValue
-                    : oldValue),
-          ],
-          decoration: InputDecoration(
-            contentPadding: const EdgeInsets.only(
-              top: 12,
-              right: 12,
-            ),
-            hintText: "0",
-            hintStyle: STextStyles.fieldLabel(context).copyWith(
-              fontSize: 14,
-            ),
-            prefixIcon: FittedBox(
-              fit: BoxFit.scaleDown,
-              child: GestureDetector(
-                onTap: selectReceiveCurrency,
-                child: Container(
-                  color: Colors.transparent,
-                  child: Padding(
-                    padding: const EdgeInsets.all(12),
-                    child: Row(
-                      children: [
-                        Container(
-                          width: 18,
-                          height: 18,
-                          decoration: BoxDecoration(
-                            borderRadius: BorderRadius.circular(18),
-                          ),
-                          child: Builder(
-                            builder: (context) {
-                              final image = _fetchIconUrlFromTicker(ref.watch(
-                                  exchangeFormStateProvider
-                                      .select((value) => value.toTicker)));
-
-                              if (image != null && image.isNotEmpty) {
-                                return Center(
-                                  child: SvgPicture.network(
-                                    image,
-                                    height: 18,
-                                    placeholderBuilder: (_) => Container(
-                                      width: 18,
-                                      height: 18,
-                                      decoration: BoxDecoration(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textFieldDefaultBG,
-                                        borderRadius: BorderRadius.circular(18),
-                                      ),
-                                      child: ClipRRect(
-                                        borderRadius: BorderRadius.circular(
-                                          18,
-                                        ),
-                                        child: const LoadingIndicator(),
-                                      ),
-                                    ),
-                                  ),
-                                );
-                              } else {
-                                return Container(
-                                  width: 18,
-                                  height: 18,
-                                  decoration: BoxDecoration(
-                                    // color: Theme.of(context).extension<StackColors>()!.accentColorDark
-                                    borderRadius: BorderRadius.circular(18),
-                                  ),
-                                  child: SvgPicture.asset(
-                                    Assets.svg.circleQuestion,
-                                    width: 18,
-                                    height: 18,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textFieldDefaultBG,
-                                  ),
-                                );
-                              }
-                            },
-                          ),
-                        ),
-                        const SizedBox(
-                          width: 6,
-                        ),
-                        Text(
-                          ref.watch(exchangeFormStateProvider.select(
-                                  (value) => value.toTicker?.toUpperCase())) ??
-                              "-",
-                          style: STextStyles.smallMed14(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark,
-                          ),
-                        ),
-                        if (!isWalletCoin(coin, false))
-                          const SizedBox(
-                            width: 6,
-                          ),
-                        if (!isWalletCoin(coin, false))
-                          SvgPicture.asset(
-                            Assets.svg.chevronDown,
-                            width: 5,
-                            height: 2.5,
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark,
-                          ),
-                      ],
-                    ),
-                  ),
-                ),
-              ),
-            ),
-          ),
+          onButtonTap: selectReceiveCurrency,
+          isWalletCoin: isWalletCoin(coin, true),
+          image: _fetchIconUrlFromTicker(ref.watch(
+              exchangeFormStateProvider.select((value) => value.toTicker))),
+          ticker: ref.watch(
+              exchangeFormStateProvider.select((value) => value.toTicker)),
+          readOnly: ref.watch(prefsChangeNotifierProvider
+                      .select((value) => value.exchangeRateType)) ==
+                  ExchangeRateType.estimated ||
+              ref.watch(exchangeProvider).name ==
+                  SimpleSwapExchange.exchangeName,
         ),
         if (ref
                 .watch(
diff --git a/lib/widgets/textfields/exchange_textfield.dart b/lib/widgets/textfields/exchange_textfield.dart
new file mode 100644
index 000000000..8d3c5d699
--- /dev/null
+++ b/lib/widgets/textfields/exchange_textfield.dart
@@ -0,0 +1,384 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/loading_indicator.dart';
+
+class ExchangeTextField extends StatefulWidget {
+  const ExchangeTextField({
+    Key? key,
+    this.borderRadius = 0,
+    this.background,
+    required this.controller,
+    this.buttonColor,
+    required this.focusNode,
+    this.buttonContent,
+    required this.textStyle,
+    this.onButtonTap,
+    this.onChanged,
+    this.onSubmitted,
+    this.onTap,
+    required this.isWalletCoin,
+    this.image,
+    this.ticker,
+    this.readOnly = false,
+  }) : super(key: key);
+
+  final double borderRadius;
+  final Color? background;
+  final Color? buttonColor;
+  final Widget? buttonContent;
+  final TextEditingController controller;
+  final FocusNode focusNode;
+  final TextStyle textStyle;
+  final VoidCallback? onTap;
+  final VoidCallback? onButtonTap;
+  final void Function(String)? onChanged;
+  final void Function(String)? onSubmitted;
+
+  final bool isWalletCoin;
+  final bool readOnly;
+  final String? image;
+  final String? ticker;
+
+  @override
+  State<ExchangeTextField> createState() => _ExchangeTextFieldState();
+}
+
+class _ExchangeTextFieldState extends State<ExchangeTextField> {
+  late final TextEditingController controller;
+  late final FocusNode focusNode;
+  late final TextStyle textStyle;
+
+  late final double borderRadius;
+
+  late final Color? background;
+  late final Color? buttonColor;
+  late final Widget? buttonContent;
+  late final VoidCallback? onButtonTap;
+  late final VoidCallback? onTap;
+  late final void Function(String)? onChanged;
+  late final void Function(String)? onSubmitted;
+
+  @override
+  void initState() {
+    borderRadius = widget.borderRadius;
+    background = widget.background;
+    buttonColor = widget.buttonColor;
+    controller = widget.controller;
+    focusNode = widget.focusNode;
+    buttonContent = widget.buttonContent;
+    textStyle = widget.textStyle;
+    onButtonTap = widget.onButtonTap;
+    onChanged = widget.onChanged;
+    onSubmitted = widget.onSubmitted;
+    onTap = widget.onTap;
+
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      decoration: BoxDecoration(
+        color: background,
+        borderRadius: BorderRadius.circular(borderRadius),
+      ),
+      child: IntrinsicHeight(
+        child: Row(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: [
+            Expanded(
+              child: TextField(
+                style: textStyle,
+                controller: controller,
+                focusNode: focusNode,
+                onChanged: onChanged,
+                onTap: onTap,
+                enableSuggestions: false,
+                autocorrect: false,
+                readOnly: widget.readOnly,
+                keyboardType: const TextInputType.numberWithOptions(
+                  signed: false,
+                  decimal: true,
+                ),
+                decoration: InputDecoration(
+                  contentPadding: const EdgeInsets.only(
+                    top: 12,
+                    left: 12,
+                  ),
+                  hintText: "0",
+                  hintStyle: STextStyles.fieldLabel(context).copyWith(
+                    fontSize: 14,
+                  ),
+                ),
+                inputFormatters: [
+                  // regex to validate a crypto amount with 8 decimal places
+                  TextInputFormatter.withFunction((oldValue, newValue) =>
+                      RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
+                              .hasMatch(newValue.text)
+                          ? newValue
+                          : oldValue),
+                ],
+              ),
+            ),
+            MouseRegion(
+              cursor: SystemMouseCursors.click,
+              child: GestureDetector(
+                onTap: () => onButtonTap?.call(),
+                child: Container(
+                  decoration: BoxDecoration(
+                    color: buttonColor,
+                    borderRadius: BorderRadius.horizontal(
+                      right: Radius.circular(
+                        borderRadius,
+                      ),
+                    ),
+                  ),
+                  child: Padding(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 16,
+                    ),
+                    child: Row(
+                      children: [
+                        Container(
+                          width: 18,
+                          height: 18,
+                          decoration: BoxDecoration(
+                            borderRadius: BorderRadius.circular(18),
+                          ),
+                          child: Builder(
+                            builder: (context) {
+                              final image = widget.image;
+
+                              if (image != null && image.isNotEmpty) {
+                                return Center(
+                                  child: SvgPicture.network(
+                                    image,
+                                    height: 18,
+                                    placeholderBuilder: (_) => Container(
+                                      width: 18,
+                                      height: 18,
+                                      decoration: BoxDecoration(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textFieldDefaultBG,
+                                        borderRadius: BorderRadius.circular(
+                                          18,
+                                        ),
+                                      ),
+                                      child: ClipRRect(
+                                        borderRadius: BorderRadius.circular(
+                                          18,
+                                        ),
+                                        child: const LoadingIndicator(),
+                                      ),
+                                    ),
+                                  ),
+                                );
+                              } else {
+                                return Container(
+                                  width: 18,
+                                  height: 18,
+                                  decoration: BoxDecoration(
+                                    // color: Theme.of(context).extension<StackColors>()!.accentColorDark
+                                    borderRadius: BorderRadius.circular(18),
+                                  ),
+                                  child: SvgPicture.asset(
+                                    Assets.svg.circleQuestion,
+                                    width: 18,
+                                    height: 18,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textFieldDefaultBG,
+                                  ),
+                                );
+                              }
+                            },
+                          ),
+                        ),
+                        const SizedBox(
+                          width: 6,
+                        ),
+                        Text(
+                          widget.ticker ?? "-",
+                          style: STextStyles.smallMed14(context).copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark,
+                          ),
+                        ),
+                        if (!widget.isWalletCoin)
+                          const SizedBox(
+                            width: 6,
+                          ),
+                        if (!widget.isWalletCoin)
+                          SvgPicture.asset(
+                            Assets.svg.chevronDown,
+                            width: 5,
+                            height: 2.5,
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark,
+                          ),
+                      ],
+                    ),
+                  ),
+                ),
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+// experimental  UNUSED
+// class ExchangeTextField extends StatefulWidget {
+//   const ExchangeTextField({
+//     Key? key,
+//     this.borderRadius = 0,
+//     this.background,
+//     required this.controller,
+//     this.buttonColor,
+//     required this.focusNode,
+//     this.buttonContent,
+//     required this.textStyle,
+//     this.onButtonTap,
+//     this.onChanged,
+//     this.onSubmitted,
+//   }) : super(key: key);
+//
+//   final double borderRadius;
+//   final Color? background;
+//   final Color? buttonColor;
+//   final Widget? buttonContent;
+//   final TextEditingController controller;
+//   final FocusNode focusNode;
+//   final TextStyle textStyle;
+//   final VoidCallback? onButtonTap;
+//   final void Function(String)? onChanged;
+//   final void Function(String)? onSubmitted;
+//
+//   @override
+//   State<ExchangeTextField> createState() => _ExchangeTextFieldState();
+// }
+//
+// class _ExchangeTextFieldState extends State<ExchangeTextField> {
+//   late final TextEditingController controller;
+//   late final FocusNode focusNode;
+//   late final TextStyle textStyle;
+//
+//   late final double borderRadius;
+//
+//   late final Color? background;
+//   late final Color? buttonColor;
+//   late final Widget? buttonContent;
+//   late final VoidCallback? onButtonTap;
+//   late final void Function(String)? onChanged;
+//   late final void Function(String)? onSubmitted;
+//
+//   @override
+//   void initState() {
+//     borderRadius = widget.borderRadius;
+//     background = widget.background;
+//     buttonColor = widget.buttonColor;
+//     controller = widget.controller;
+//     focusNode = widget.focusNode;
+//     buttonContent = widget.buttonContent;
+//     textStyle = widget.textStyle;
+//     onButtonTap = widget.onButtonTap;
+//     onChanged = widget.onChanged;
+//     onSubmitted = widget.onSubmitted;
+//
+//     super.initState();
+//   }
+//
+//   @override
+//   Widget build(BuildContext context) {
+//     return Container(
+//       decoration: BoxDecoration(
+//         color: background,
+//         borderRadius: BorderRadius.circular(borderRadius),
+//       ),
+//       child: IntrinsicHeight(
+//         child: Row(
+//           crossAxisAlignment: CrossAxisAlignment.stretch,
+//           children: [
+//             Expanded(
+//               child: MouseRegion(
+//                 cursor: SystemMouseCursors.text,
+//                 child: GestureDetector(
+//                   onTap: () {
+//                     //
+//                   },
+//                   child: Padding(
+//                     padding: const EdgeInsets.only(
+//                       left: 16,
+//                       top: 18,
+//                       bottom: 17,
+//                     ),
+//                     child: IgnorePointer(
+//                       ignoring: true,
+//                       child: EditableText(
+//                         controller: controller,
+//                         focusNode: focusNode,
+//                         style: textStyle,
+//                         onChanged: onChanged,
+//                         onSubmitted: onSubmitted,
+//                         onEditingComplete: () => print("lol"),
+//                         autocorrect: false,
+//                         enableSuggestions: false,
+//                         keyboardType: const TextInputType.numberWithOptions(
+//                           signed: false,
+//                           decimal: true,
+//                         ),
+//                         inputFormatters: [
+//                           // regex to validate a crypto amount with 8 decimal places
+//                           TextInputFormatter.withFunction((oldValue,
+//                                   newValue) =>
+//                               RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
+//                                       .hasMatch(newValue.text)
+//                                   ? newValue
+//                                   : oldValue),
+//                         ],
+//                         cursorColor: textStyle.color ??
+//                             Theme.of(context).backgroundColor,
+//                         backgroundCursorColor: background ?? Colors.transparent,
+//                       ),
+//                     ),
+//                   ),
+//                 ),
+//               ),
+//             ),
+//             MouseRegion(
+//               cursor: SystemMouseCursors.click,
+//               child: GestureDetector(
+//                 onTap: () => onButtonTap?.call(),
+//                 child: Container(
+//                   decoration: BoxDecoration(
+//                     color: buttonColor,
+//                     borderRadius: BorderRadius.horizontal(
+//                       right: Radius.circular(
+//                         borderRadius,
+//                       ),
+//                     ),
+//                   ),
+//                   child: Padding(
+//                     padding: const EdgeInsets.symmetric(
+//                       horizontal: 16,
+//                     ),
+//                     child: buttonContent,
+//                   ),
+//                 ),
+//               ),
+//             ),
+//           ],
+//         ),
+//       ),
+//     );
+//   }
+// }

From 0b6545645bdd7bdf1939c2de2b42397e47614210 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 14:55:26 -0600
Subject: [PATCH 379/426] macos + windows app icon

---
 .../AppIcon.appiconset/Contents.json          | 132 +++++++++---------
 .../AppIcon.appiconset/app_icon_1024.png      | Bin 46993 -> 69450 bytes
 .../AppIcon.appiconset/app_icon_128.png       | Bin 3276 -> 4664 bytes
 .../AppIcon.appiconset/app_icon_16.png        | Bin 1429 -> 926 bytes
 .../AppIcon.appiconset/app_icon_256.png       | Bin 5933 -> 10085 bytes
 .../AppIcon.appiconset/app_icon_32.png        | Bin 1243 -> 1441 bytes
 .../AppIcon.appiconset/app_icon_512.png       | Bin 14800 -> 26089 bytes
 .../AppIcon.appiconset/app_icon_64.png        | Bin 1874 -> 2443 bytes
 pubspec.lock                                  |   9 +-
 pubspec.yaml                                  |   9 +-
 windows/runner/resources/app_icon.ico         | Bin 33772 -> 1968 bytes
 11 files changed, 82 insertions(+), 68 deletions(-)

diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
index a2ec33f19..96d3fee1a 100644
--- a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -1,68 +1,68 @@
 {
-  "images" : [
-    {
-      "size" : "16x16",
-      "idiom" : "mac",
-      "filename" : "app_icon_16.png",
-      "scale" : "1x"
+    "info": {
+        "version": 1,
+        "author": "xcode"
     },
-    {
-      "size" : "16x16",
-      "idiom" : "mac",
-      "filename" : "app_icon_32.png",
-      "scale" : "2x"
-    },
-    {
-      "size" : "32x32",
-      "idiom" : "mac",
-      "filename" : "app_icon_32.png",
-      "scale" : "1x"
-    },
-    {
-      "size" : "32x32",
-      "idiom" : "mac",
-      "filename" : "app_icon_64.png",
-      "scale" : "2x"
-    },
-    {
-      "size" : "128x128",
-      "idiom" : "mac",
-      "filename" : "app_icon_128.png",
-      "scale" : "1x"
-    },
-    {
-      "size" : "128x128",
-      "idiom" : "mac",
-      "filename" : "app_icon_256.png",
-      "scale" : "2x"
-    },
-    {
-      "size" : "256x256",
-      "idiom" : "mac",
-      "filename" : "app_icon_256.png",
-      "scale" : "1x"
-    },
-    {
-      "size" : "256x256",
-      "idiom" : "mac",
-      "filename" : "app_icon_512.png",
-      "scale" : "2x"
-    },
-    {
-      "size" : "512x512",
-      "idiom" : "mac",
-      "filename" : "app_icon_512.png",
-      "scale" : "1x"
-    },
-    {
-      "size" : "512x512",
-      "idiom" : "mac",
-      "filename" : "app_icon_1024.png",
-      "scale" : "2x"
-    }
-  ],
-  "info" : {
-    "version" : 1,
-    "author" : "xcode"
-  }
-}
+    "images": [
+        {
+            "size": "16x16",
+            "idiom": "mac",
+            "filename": "app_icon_16.png",
+            "scale": "1x"
+        },
+        {
+            "size": "16x16",
+            "idiom": "mac",
+            "filename": "app_icon_32.png",
+            "scale": "2x"
+        },
+        {
+            "size": "32x32",
+            "idiom": "mac",
+            "filename": "app_icon_32.png",
+            "scale": "1x"
+        },
+        {
+            "size": "32x32",
+            "idiom": "mac",
+            "filename": "app_icon_64.png",
+            "scale": "2x"
+        },
+        {
+            "size": "128x128",
+            "idiom": "mac",
+            "filename": "app_icon_128.png",
+            "scale": "1x"
+        },
+        {
+            "size": "128x128",
+            "idiom": "mac",
+            "filename": "app_icon_256.png",
+            "scale": "2x"
+        },
+        {
+            "size": "256x256",
+            "idiom": "mac",
+            "filename": "app_icon_256.png",
+            "scale": "1x"
+        },
+        {
+            "size": "256x256",
+            "idiom": "mac",
+            "filename": "app_icon_512.png",
+            "scale": "2x"
+        },
+        {
+            "size": "512x512",
+            "idiom": "mac",
+            "filename": "app_icon_512.png",
+            "scale": "1x"
+        },
+        {
+            "size": "512x512",
+            "idiom": "mac",
+            "filename": "app_icon_1024.png",
+            "scale": "2x"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
index 3c4935a7ca84f0976aca34b7f2895d65fb94d1ea..55efad011aa22c651bd4eeb225bebd9c6fea31bd 100644
GIT binary patch
literal 69450
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
PKlPC5u>%Drr*HfpG~rAC

literal 46993
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
QOu#(cH>|q6Qt;3J0APUL!~g&Q

diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
index ed4cc16421680a50164ba74381b4b35ceaa0ccfc..c8ba3b1a21bf014a0ed55ac2169dc48b4abb240f 100644
GIT binary patch
literal 4664
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
Lx+=BLUw-%>(J$+(

literal 3276
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

diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
index 483be61389733f2e5331c08db8ca245268610ccb..e85f014180ccfa3df01d669e08620973393bc259 100644
GIT binary patch
delta 915
zcmV;E18n@23!Vp%8Gi-<001BJ|6u?C0fcEoLr_UWLm+T+Z)Rz1WdHzpoPCi!NW(xJ
z#a~lPRazA6AmWgrI$01Eanvdlp+cw?T6HkF^b49aBq=VAf@{ISkHxBki?gl{u7V)=
z0pjT7r060g{x2!Ci1pyOAMfrx?%n}Hz05SLYaGyY+e{_mVt*#PDh6K>L>T=Dphsqw
zF(*k$bR1vz@bUF7#<Mz~`*VcVoW%g2NIc67(<a^^p5C+#&ilj>R+LrZbK)_RE=c^y
zb;aX1&IOkRo*6OIsd?fEu~=whrHxt9)QG2uqpGG;zL4=)<-EmND_2?bp8SQOoW8Qm
zb(+ISU=d4@Ab&zZ6(y8mBSx!EiiH&I$2<6kT)#vvg<K^tax9<%4YKP8|AXJ%TKUNd
zFDVoU0xyp9F#-g4fkw@7zK<QJaRT_Cfh)b`uhfB=Ptt2GEqVm>Z37qAElt@2E_Z;z
zCqp)6SMt*o@_FF>jJ_!g4BP^}YhG{7eVjf3Y3eF@1AiPG0;2`WUhnYk?)KjPJ=5&(
z2kcmKaYeY=jQ{`v)k#D_RCocUQ@gHdQ4}56B;py7NIc`&_yCQ{2PhPXLL*VAG!z=O
zs5KgeLR1>1L?aS9BGD+sBOwxm#9Q1uSF-nc+<Wf1$r;UFd#y3YoO7(Xxbyk^!Vkdx
zB=}o_&3|Tt)oKN$QVFZo3W-GWe*(MR4$Wp0r_%{erxWY-8q4JpE|&`ig8?Fu=<fp8
z>lLk53+;9r_xl}oyInZDTrL=mMp!Hs@OV5>tJQA;uh$E`UXNux9*;uMY&L_<W`jzl
z6884{J^KAVj7B4?j+@Wt$mjE{Y_r)6u~;mSpMTFMI-L&OZZ{kb$A>d&?{>R^t5hmX
zkwE1US+Ca%eLfx!jK^bEjo0gCW)g?@f};hG-!p;Xa0s1F$4KNpkHg`BTCE0?$%Je+
zD<t3|kq8=%2FuQ4yWO&?h)hP(|70>@CQqkRghC-iqfw+%DR5e?7WH}^rBaD~sc+s`
z5`U%ZqxE|bXD}GBb9M_FjRv_~4&iVZg+c+{ZdWMrb1?anPNxwJ2AQcJ=70vJTrRUY
zC>D#L8{#3AN)eC8kxV9`P$-1`KPHhf2Lb{3{eD!dRVL{3`H;zEV6j*})4zTTGMNmC
pL;|r`405^rE86$3@n6A&Ut0#p@f^_w=nMb=002ovPDHLkV1iY&s4f5i

literal 1429
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F
z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a><YADU|^aU;1l8sRFH7;2N1=B
zQQV0iv0xN^;z#sxC`vr}6NoU?!~oTRQPlAta5Zq#;6?$JK~=((;W7=P3}^zxG`N{)
zZUedys1hg$u?tff&}tw`Joy9Yut*q!D29`8Ga>GbI`Jdw*pG<g2rUo=$RxyAi0zQ@
zK{g*#CB!bc_u+~|kN*O?3St_>cA%L+*Q#&*YQOJ$_%U#(BDn<O1)%wG2LRc++rJs_
z{ARTCo88{;VIVC(fy&@kKq3(+!cg`Os0N4(foRuvi_Pzx*E}+qe75q_|L~(AaRZ1H
zSXO7vE8*g;>``;rKxi&&)LfRxIZ*98z8UWRslDo@Xu)QVh}rB>bKwe@Bjzwg%m$hd
zG)gFMgHZlPxGcm3paLLb44<vP<D2@r*P^96AbR1lK<$hXvw`IQ|Nj*t=9vH!<*kw+
zKTrZ^aK8WT>yHI|Ag0wdp!_yD5R<|B29Ui~27`?vfy#ktk_KyHWMDA42{J=Uq-o}i
z*%kZ@45mQ-Rw?0?K+z{&5KFc}xc5Q%1PFAbL_xCmpj?JNAm>L6SjrCMpiK}5LG0ZE
z<A9vK72<4{``^ETd}9%0zzx*KnB?v5a_b$lS`(1NS>O>_%)r1c48n{Iv*t(u1=&kH
zeO=ifbFy+6aSK)V_5t;<dAc};NL)@%U|@7pOA`w-E93Li%QKkYKD|HQA;2TTCB#SO
z$n*(QCQX|-b#iz>NKhE#$Iz=+Oii|KDJ}W>g}0%`Svgra*tnS6TRU4iTH*e=dj~I`
zym|EM*}I1?pT2#3`oZ(|3I-Y$DkeHMN=8~%YSR?;>=X?(Emci*ZIz9+t<|S1>hE8$
zVa1LmTh{DZv}x6@Wz!a}+qZDz%AHHMuHCzM^XlEpr!QPzf9Qzk<mEnd&1#RGiQN30
zVeL%o{C`cY-D3KYyK;VZO-*PwUK6!9?d`6w(q?(L_M~b@B;5WcYhC{K-sbZA|CrhN
z8(sP2Evw%A=$yRVZ@y(U-=dd)TDzy~#qX?o`>S_0!&1MPx*ICxe}RFdTH+c}l9E`G
zYL#4+3Zxi}3=A!G4S>ir#L(2r)WFKnP}jiR%D`ZOPH`@ZhTQy=%(P0}8ZH)|z6jL7
N;OXk;vd$@?2>?>Ex^Vyi

diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
index bcbf36df2f2aaaa0a63c7dabc94e600184229d0d..bfb090fc604d253944fcabee1e019ee460c70201 100644
GIT binary patch
literal 10085
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

literal 5933
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

diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
index 9c0a652864769b250ed58097f2f6270b393f751f..877b87dc389f3f83852a0eaf258bbeea9122221c 100644
GIT binary patch
delta 1424
zcmV;B1#kM>384#+BYy#eX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmKpe$iQ%hA^6zm}4
zkfAzR5EXIMDionYs1;guFuC*#nlvOSE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JW
zDYS_7;J6>}?mh0_0YbgZG^=YI&~)2OCE{WxyDA1>5kwgM2!EhQW|lE0NlA1ZU-$6w
z^)AM<I-mP<gw>qI0G~)a%M8;d-XNadv<=St#1U4MRpN8vF_SJx{K$31<2TL)mj#{~
zG1IAe;s~)=Xk(>~S<%#pr--Afrc=I<@mS@&#aSy?S@WL!g`u3jvdndw!$@EeOOPN!
zK@}yGVIxMXPJfDp6z#`5_=jA-L@tF~B`|U<paKoD>j(dX-`!gI$q6qh6bAw?j`J}B
z1b2Z(&2heu9j9>u_@99*z2&deftgRzYb`B$1oUkK7uPLK*#j<jfWaq2Hf2}x(-iV~
z;QfrgDGLnT0=;WqZ_Rz2J^*RzDtQAO90H>S%3kmA?tkv~-u^w)?C%HcSaNYixY~^X
z00Y=bL_t(|0qs{=C}v?8esJuRec#taaxcwDjZ%u#Fg2q@8C(#GJC`UUxp5<z6uFQT
zV&=vL5xF2)BeJjA_hruWO~3j19sjY+xS8k1a=!Du&-cF1`@G+gPEJm4@P?4yGWdT2
zuR>sNZ+{Q_`}?rAwuX(3&A%hCxw(n)@o`*ST!_DKZf@Y{=!l@8AXr#f{5=B4$H(aI
z?#95t0AgZdU}$J4{%>GlfUT`9Y;SMF%gYPCzP^wo{oAW1aCv!&zP>(mb#)06mX?;c
z!L`9mEG#Twb!7$q0ReDxa}(sAO@JGYjg6tLt$$6VU4zrpQ(RwPKS+W&mrFA-F@eR!
zMFa;2!`9aJ=>(RRmeAVTikX=iol{(0T?s<Y&d!e>;PCJe!^6XHa&kgoU?9xR&Gi%5
z+ucQbM+b(6hC~LGQaCj=C4{Gx1#N6>YzU1|A3i=lxB9q4fOYQa=@BA3KR?&IDO+%K
zbbl1#;o+)Cuw?V|^H^P7MS!di7Z;a51p52?(a_L<v$Hc;Sy}1bOas>V;NSpZVPT4O
zz7NJ=Htg-~e-o&vs6c&v{p|u*S6BG^`@_`KRMm#Na>;sod*R{Xfsl|8n3<U=uBBno
zD>P&!3QapW!4$D(-rnA#W=2Lvs)%qezJJRA^a1VnjE#*&+V8iew6?bP;AT|$+}s>i
z<bLLhRPkf|to<I_k6sWO8Y;5s>FEhSKfec!Ng|`il+J#q576g%GNw=sj*gDd+1V)!
ztEi|*(G?{!WZfnwCm-FAbsiiXguA=DIE{&kiQ-!J{`B-Tc6N5e!IF}ako@r@vVU`O
zbOx5h1-ZGo$jZu6b+YB<Wvs8SiyBjO+U>`|#IkXXc2-%I#-=88$QjAb&PH-_@?9T@
zii$#BULLBds#KAnU(g*Hi0)=*XD5DVa6VH4eWSFr6wS@eqAZb-k$-$3BO^nUqP)CZ
zY@`MpN+Tm9LgAXRtOm2Qv-mD|9)IKAQ3e^cw6vf}PFGD$jW8HBcuH`#bzxy4qNAfl
ziFBmN)1;=RB0fGI)z#I45H0kj;3eg2W+py=`Ep0ViqnuzRZ>!dPbn!VEh`fppvDL8
zgYP6HBnY89I5_A$*Lxobl4p5cT^)Y@_<?Vgl|pQ45fKrA;^Ja4CzPP-Mt{Upe29(3
zyZ7&fZP(V;LjIspT+cf~ettgU;^OpX?MZh+4yR1Hj){qhsFbtO-rlbBJS{B^>FMb@
z7mrsVpaJJXnXHQxSs(mKtB#d3R8UYLhRsv(qVEFMxUsQOTrz0S&%uj7OlZZ=4gM+w
eUWzv-@C)B~n#-8vW6l5o00{s|MNUMnLSTXy*2F#l

delta 1224
zcmV;(1ULJk3)=~hBYyw{XF*Lt006O%3;baP0000WV@Og>004R>004l5008;`004mK
z004C`008P>0026e000+ooVrmw00006VoOIv0RI600RN!9r;`8x010qNS#tmY3ljhU
z3ljkVnw%H_000McNliru;|T=_G7A!Wjg9~S1IkH6K~z}7t$&wYXdG1($A4#b8}k9i
z6oeKZ#P&&qlI)X$Amqiq`Dz7CgPVW|f)IT2t%#_hFMZ4g#MY*dRbMoOAcdADh?Jrw
zCEB!!RQn+{A3NPmcIWtT=T7d-?(EKPdtsTGd*`0t|D1F0xjRCaZEUFusC^s)&Zu%+
zA+Vk5UX>hhLw{icSULY%F97*&;3t===sx^e;B(*v;H6Fy?x36!SaG}4C$xZrBKz>K
zfXOzt)_@|yd~%>80pszoTlfT6J*n_XV8KrPHVl790t_6)usVmE$uT%&Tmu%~spsOt
zfpf3+HoVj}0$Jgzv1yU#w!0a;t$=Pl$MIZRz*`DPgMTY3;4DQq3dx)UXIsEi1#}7z
z!{0I7M(C-+?RXYAK+b(Q>FjesGKKv~;IRmdEme^gMW$)awK449bO4V8jKw^U!&AJD
z!3A>y#SWkFrlBuvbMeC{8Xi>mk~Ui{>3Q9}{1R}K)J#S8t^@aNr&|g8fiFVCX<$gK
zb~ToV6@O-cW6^QkD8mCT0w1}Z$x__ZYp2S^;K4q87AQ2#i(kJ7J_hb3RoUhPp8zFQ
z1GT>-yvKtLU&%=vu1Rtn{sC||DKZuTRW^aC@UiF^SOX>n7HSGN{|itU-r8e!ATLef
zj)n&KoO2>N+prROt1t*mhazrc7Ue=+;pSEVFn<ip_IMNy^$GoXX$sdi@P?efceUag
zcrHxI&%k^V4ipqP;KAWOVIU_R!y5zuyc>#e#<i}nvK1g9T%84{K#vE9dxe3#DP>vV
zO$8)HlxuLi9DsqAfRRLwA&P{@Kwd7Y>W5k2sRG<q_{q1op8}^+D<eYn@4J=q>gxEx
zLx0a-xOVz$dS5S4IXm9cekK87u^9@hWU(21XZ<h!S^kAR-~UrYCV|BuFmiX#zn^M9
z)1Oi?A%BF~qNNC|2423i!Tl@C)ON}Ua#U4kRCQEB_YS->+r5Ba-|Tnuy$MXInqq|r
z{@OYZFI}a+y%P#mfFr8Rs4{9N=1-KG+JA4G0^3HywO~H8WDs<^ytZC^aCw>C-3me8
zLqnIHdU6X>Ll!mctj)zUm{|b8@Q+5s-u4a}1cMv%i_^Q0{UQl)Bot89Tfl@Wi*~Gj
zVP8Z?Uq;uC_uCIm9<Bbd>2GaLAyRVB42{D9j$ls8QTsjVy*(4z%w>h!cJJJ0Y=1xV
zGLIiTM7&%TxC9&oM%0O@4S9GO0^R^_VA6vA_Ct390BYC2BY*5I`&d=D0=x*kpsHoe
z$?B_`E8r{I2fU)nW#C_aHv;|#93kSZ<%JtK0000bbVXQnWMOn=I%9HWVRU5xGB7bY
zEigGPFf~*$H99pgIx#UVFgH3dFhQU!b8P?s03~!qSaf7zbY(hiZ)9m^c>ppnF*z+T
mIV~_XR53L=H846cF)c7RIxsNNam&#F0000<MNUMnLSTZ9Sr(fB

diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
index e71a726136a47ed24125c7efc79d68a4a01961b4..f24fbe65de8627a88836014c48b7f8156a627594 100644
GIT binary patch
literal 26089
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
BO?v<U

literal 14800
zcmZ{Lc|26@`~R6Crm_qwyCLMMh!)vm)F@HWt|+6V6lE=CaHfcnn4;2x(VilEl9-V}
zsce-cGK|WaF}4{T=lt&J`Fy_L-|vs#>v^7+XU=`!*L|PszSj43o%o$Dj`9mM7C;ar
z@3hrnHw59q|KcHn4EQr~{_70*BYk4yj*SqM&s>NcnFoIBdT-sm1A@YrK@dF#f+SPu
z{Sb8441xx|AjtYQ1gQq5z1g(^49Fba=I8)nl7BMGpQeB(^8>dY41u79Dw6+j(A_jO
z@K83?X~$;S-ud$gYZfZg5|bdvlI`TMaqs!>e}3%9HXev<6;dZZT8Yx`&;pKnN*iCJ
z&x_ycWo9{*O}Gc$JHU`%s*$C%@v73hd+Mf%%9ph_Y1juXamcTAHd9tkwoua7yBu?V
zgROzw>LbxAw3^;bZU~ZGnnHW?=7r9ZAK#wxT;0O<*<yVcDp>z~_>^uV+VCU9B@)|r
z*z^v>$!oH7%WZYrwf)zjGU|(8<chVY*-0*4Pj6Lh%^|P9hq0+MZPBYdgZgADR3T{g
zYE5ZD_S1G_w_84><cT)X-D@%1o3}R$Oi=g+c-7l`tJ%gU>I%9PoktcsH8`z^%$48u
z(O_}1U25s@Q*9{-3O!+t?w*QHo;~P99;6-KTGO{Cb#ADDYWF!eATsx{xh-!YMBiuE
z%bJc7j^^B$Sa|27XRxg(XTaxWoFI}VFfV>0py8mMM;b^vH}49j;kwCA+Lw=q8lptk
z?Pe`{wHI39A&xYkltf5*y%;-DF>5v`-lm0vydYtmqo0s<c>Clh5ueHCLJ+6$0y67Z
zO-_LCT|JXi3tN7fB-!0_Kn#I+=<KtYUj8xb(Xgz6NIk!gc_zD>tyUj87uR5*0>|SZ
zy3x2;aql87`{aPZ@UbBwY0;Z-a*lYL90YApOAMKur7YgOiqA~Cne6%b&{V-t>Am2c
z{eyEuKl!GsA*jF2H_gvX?bP~v46%3ax$r~B$HnZQ;UiCmRl`ROK8v><k|AVL9tOQk
zNVxxGPnpnl?L4PvQwVi;!;c$tYX<&qW4%VB@6B7SQ)}`yVFy2Txa2CfuUVKXCP4PG
z&uwA8qT(w)?1UJC?R?w8c9vQz8sf>;Zs~upH9}qu1ZA3kn-AY2k2@CaH=Qh7K6`nU
z3ib(Bk%H*^_omL6N4_G5NpY20UXGi}a$!}#lf<&J4~nhRwRM5cCB3Zvv#6+N1$g@W
zj9?qmQ`zz-G9HTpoNl~bCOaEQqlTVYi7G0WmB5E34;f{SGcLvFpOb`+Zm)C(wjqLA
z2<r9^6SA@E74}svz3`o(LE6BEW|0=)Vf`kgrzspE{d_YsLgB*(V0R;Zbkx@b{UWP!
zI5JM$S_xJga7j8jwb-c#LxK%UQFHL7&l1HQszD1%da=`dcmY^dOoY!DDPbObSO)xZ
zl+dWnz`XzSQx6?wRG}u_E_7&QGuW}E9Zef;l>;+nmB6~QDXbxZGWKLt38I%X$Q!;h
zup9S~byxKv=$x|^YEV;l0l67jH~E8BU45ft_7xomac-48oq4PZpSNJbw<7DTM4mmz
z!$)z#04cy%b8w@cOvjmb36o;gwYIOLwy+{I#3dJj#W4QdOWwJQ2#20AL49`hSFUa7
zFNAN3OD==G3_kbr1d96>l`_cI`<=thKNh5>hgg7FV>5TfC6d#u)9BNXi@p1K*;2Is
zz+x;l4GbSt#*%>1iq}jGIebXYJY5;PGG0y(^{>SSuZY89aL`sDghOM&&pyP6ABJ#w
zYwK~4^1eUQD)4!GL>`zrWeHV<xVjKNvwq)+S@w2hj;{~tt_D&A_@3=KXhH5^iD^|z
zkgndh$5Cm2fW*BV@AHS*Y7pI_^T*G)A*9KQA3!AGp!v@vLh|KE|L&T}j@kO-Tpj_K
z!RuwTJjD{x=Dt__hCh*ix(N_5|Njz`7C!l&OFVnE9Ay7!OYfn&@D0tXcG<P$hO?8y
zg<PJR45YhhAF{9hh7ug=XM-w|l;LQw_517^mMt9W4`c<rnr00IImC#o9_EOt<ZuT>
z-W!6JZbW*Ngo;Edh<Nb^Um$n5JEPzxCO0Hxmm8uN!K>p_cOysYr!uhKS}vIg_UC}x
z=jXxQfV@4B3<pG?16&6Kklo$f7rwG}S_Lx`8bi8fT=wBK@AHi_d*+_(vF*0Tyn>`5
z!u#byBVXV5GtrSx_8bnT@iKv=Uc6n)Zpa`<9N>+!J~Loxptl5$Z`!u<3a)-+P)say
z#=jc7^mJzPMI2;yMhCmN7YN78E7-^S(t8E}FklC;z|4PL{bO|JieM#p1mBjwyZMEm
zkX^A1RXPGeS2YqtPMX~~t^$~oeFfWAU#jVLi%Z@l2hle^3|e(q?(uS=BVauF?VF{j
z(owKLJuze;_@5p1OtRyrT`EFXf)NfMYb-)E8RVVdr<@}M>4R&~P=;B`c1L%o|8YfB
z-a(LB-i8jc5!&B5cowyI2~M^YID&@Xt<xc|$Zrp@Ke+Dlecz6L=+=Tb56gh|!0E7m
zTw$p!C+O7M9Uj8I-Rz=3X=wD=1se6tSoFwgURSEvC=LgWdQE$g&Il4la>(D9v{|DB
z959<d^dq0TZ}`R(KU~?toG?T`fP-6ys=_)0emn3_)g;1k;ZXn|TvJl0IwpOz<@Niu
zua{s4Gls@`D14Ts43sG~Jk5HVuo7CTbGN0Je5W5Lj04kK5^G8i-CC}X_II5_NVZGS
zYrsJiJ--6y8k;lO46=J+(4uH@uPz{9I3#RcijFvTpl_5&bu~g@x@g;w{L47Vw{k>W
z*vEA77fh3*w*UJ`4Y(bxsoEy6hm7_Wc5gT0^cvso%Ow>9<&@9Q>mxb6-^pv)5yc>n
zQ~^!qY(lPQ1EDGkr%_*y*D8T^YbCa52^MVqYpTLhgJ;N5PfCQ{SXk|plD#Sm+g4c-
zFeL2Dih35W4{_qb75U`4Rb#S0FEo%F85dOhXSX0huPOxdAid{&p6P;<I)GgXFZT-J
zcB`;GOXdk{oh<RtSD@`HX67FDHvEEpcP=0JRxGAcRp2yWD4rczS8uK<x9;|5gDIpb
zX9a3%)pzF5L1j1%yt8GqZ`w+>+9}I)XU7^=3RZu9M<?X_Z9fv{=EfzR0FszwrqOrz
zkiuE34~Ag537@$?P+2#Sd8z@!2^~d%wZMXO)0-??L(hNDAje@rPX_&A$t-E8?V)uC
zyZ!{~yT#1{TH`-yjcK|q(g=P>(g0dLyz_7$8K{`AddBLOfU&B_QNHtmsnNXq`hy~%
zvJ{vtz~Yt9X|o}5<nwuvG%BCD1ZdtuO~olIE3|W3upvGQZ782>vXX)9ZCHaRq8iAb
zUDj8%(MpzJN39LferYKvIc!)z^5T-eW@j3h9a6d%WZ!%@2^@4+6%Z9W1GHZbOj|sb
z0cU$}*~G$fYvDC|XulSC_;m}?KC2jg5pxES$Bt!hA|@EX*2+O!UEb5s<al~dsD}`?
zM|$Rixy}2*Trw3Ohqe9{sGh~(q0&qSxxO!`rmbrnMsAC%R?0vI_dkonN<}2hCHRKr
zuwsfDM6{hk{v?P;G2p(qr2S@)?y1wYta4Z@FEX7hjMI~Y7)xmAfp0>n_^d>z;>;r~
zmO3BivdXboPY*}amsO&`xk|e)S*u=`o67MC(1WTB;OwG+ua4UV7T5Wvy%?U{Pa5cO
zMoLG>#@chO{Oc72XPyX8f3jC7P`$j4$)0wc(b50COaDP3_Cm}aPAglUa7kRXAqmo5
z0KDD<p1=Sdp7W;sk6_)dh3MTt>7G>Gmnpons40WJNYn+pxko92<v-KPf_$71CE$sr
zPp_-LNtHW$y>GXy@PvSErKE-Ou3)3UiRr7!L4+0%+5}sD{bf)uj^ounQ-Y<LIB4VZ
zDTLH{P6b}Ka?}rdp@K5VmumJw1eeJ>n2%%JoZ%FjUv%yjS?Ks4u<yp8Kh_hvLK5ZW
zc=o})S2j^x#1xLWezRG`;l740xGLB5Qx!I3G2OG9>_88Jh%tNliYW~817IV@fqd1T
zi(?;Fv-s3rQEn=9G*E-QzSl%YS|^fe*yn}Aqh!&P<5%#oB?*{wZMa5$PYa*A{VA8!
zbOfS1W!W}cTo%g~iP$>WhE_x7#O4?<H%TB4=_jA;5W?bXVtr>h$jq=>{M77>bTAK_
z6uU0tl6HARboGi}=4krr6WP`9`aAt&P5ON1v(+H{T?jZuJ}B{L-=z3VX)}mZwzrqH
zpf?T!k&$?{&{0_p>b`kdJbSb(p~tFcuG4zh6}hfl@ues6CfJu<-P+!>FlYMlD_3!E
z9$6VE==tlxNYe(s;@8@+4c4jQ$R2g8t0QwE>Et|)5)@kJj6^yaqFYY?0LEM2C!+7+
z+FN|UxR1GCy1KA`{T_%24U+Vserchr5h`;U7<I9f9OTRUuW)Tc^pE=sSdKGz+C-!&
z6!hX>TZPr@43x#MMN{@vV?KSII}R@5k`7cVK}E;c)$f~_{ZLDOoL|-01p~oafxi4F
zG$?Wha&a*rTnz-nTI-bAJ*SLb!5(L!#iRdvLEyo>7D_=H78-qZrm=6{hkUR{tR{H!
z`ZTOV$Oi6^qX5=_{f}V9h}WJAO%h9)kEUF#*-JyY<Z^M?9G9(4J@Y4q%vbDWz5vnf
z;96{(!mN=h_EHJXR7YaE{lB%N`(4E2b9dlVQuMxZtau1Hyese>DbOGZ>Nfs%7L}4p
zopIul&&Bbn!C9o83ypC6W4F$X=_|pex$V4!Whm#48Wfm3*oAW0Gc&#&b+oq<8>aZR
z2BLpouQQwyf$aHpQUK3pMRj(mS^^t#s$IC3{j*m9&l7sQt@RU{o_}N-xI_lh`rND^
zX~-8$o(;p^wf3_5-WZ^qgW`e8T@37{`J)e2KJdSSCUpX6KZu0Ga&U*+u3*PDAs1uK
zpl)40+fROA@Vo#vK?^@Pq%w8DO9HdfmH+~vNinZ$5GRz?sD|k246NepqZd`>81P^P
z#<MrlXt}S;zeU$F<H?O?Q4jJiiv=EzZ{8%amk3RbROH*nW!=GDX6vD|Ef*Dta3%#g
zcI3luBqs*0xK(tvNaTuKOcH*X=fs6E_r^*nPog69ZFBS%p^6Nj9cI$M0sWFC)7hig
zFHQD|*9T-Sz3de{*)s|DQ;%v^K5mHKdPk-zK5CJrPl_9k50398XYM&P@7gnv_qGq^
z*fpn$6U1%|GLam`R|eTDby4#M)Kik5oF4oKHT?*prbUAiN63i=9yHVAuPtlkcq2KN
z;fiIUnKvd@2xa}d_31GnHU8I@IUsH=G0q7zY#%~R4zYM?98d06m$F|99P@PbPSp#m
zl(3uT_nS{5xi1-DgoHEj0{*pBYp{~*ikQU06{|w&VyP{{J!+-EM<$B{vKPK^|2|74
z_W+G~GMb{6Ke!eq#m(h_sq3?sqV{*iC$D}T^M@6U5G5?INDG@ji-KtUHrEPLdj4`;
zFteNdv4@qbsI80I>x#3kUS-}x4k%&~iEUrsb&-X#_;;?y9oCP4crMkC`=q58#NxQ|
z*NXNA;GR4X=GiGXwab5=&M3j04fQw%2UxM<B^dDmT(W<-d9;hnoS28NR-$vxPH*My
z<O>`S(aE)_PlgJttBX96$$lY@Q%0xV^IbcHqzw^Uk&E=vFB;EQ@kzVIeM8lDIW_Q_
zrfy)l6s2QBApF;J2xTD_@wuNMlwDfsdfMyzRq)<>qG{M)Yt}9F1{1HaI_X7=F=7>&
zYB54VaKlxu0lIgS;Ac&25Aw(tcf@K~(cvPi8(OChzhlYp6}#<_MVhU95sD&)n0FtL
zmxm4w$~s(S9jmHOgyovpG!x4uLfJsMsJn^QMraKAa1Ix?{zkV!a7{f%-!u2{NqZ&)
zo+^XB`e<hdiJ?mVR`WF;zS_iMuloAU8M*MtlxRL8?fd?(E&ECy-O4-g5EjksR0Tvq
z7Agsw2j#!5e3D$?gLo@O878`&+z-;UU!9377w{Dg=&V2~$rQ!M?GEGOvK(9Nwi5Qm
zJWoV*4&Qfhs(B6C+R7zug~-1$fX7^?<$NJrXoU2g+<^LIq2Cq@WtE#iYIg&Sg>FQ4
zk-(;_>T#pTKyvW${yL|XXbcv?CE2Tp<3(PjeXhu^Jrp6^Mj}lg_)jamK{g;C+q^Da
ztb!gV!q5)B7G1%lVanA2b>Xs?%hzCgJ{Hc!ldr9dnz7k^xG#4pDpr|0ZmxxiUVl}j
zbD_rg3yAFQ>nnc)0>71D==715jRj4XsRb2#_lJoSOwky&c4957V-|m)@>b^Nak1!8
z@DsIOS8>Oe^T>tgB)WX3Y^I^65Uae+2M;$RxX_C)Aoo0dltvoRRIVQkpnegWj;D#G
z+TwFIRUN%bZW3(K{8yN8!(1i0O!X3YN?Zo08L5D~)_tWQA8&|CvuQb8Od?p_x=GMF
z-B@v9iNLY<Z;l5gz1z><u2;+Io(0!OA}>S1lUsbb`!%f5+1ev8RFPk7xyx5*G;<Dc
zWJzAN<;H)&k5}u6QSsa6pmi}hTXwYcx=x&4ibB~(KJJRH7OO<eerJ$NMDqeyWy}kF
z1W<r!Cb>ybRw(PW*yEZ$unu2`wpH)7<GYSlef=vk^w>b@ZXEz4Jr{?KZKYl!+3^)Q
z)~^g?KlPGtT!{yQU&(Z&^rVjPu>ueeZN86AnhRwc)m|;5NvM&W3xD%n`+Hjg5$e8M
z<qin0=rR*J2f!!!ILhKL@dYYi^b1gikI7;w-+5A;SP)`YSMR)F#~W{$;<Da9Y(DkZ
z1kpjnm<^U4_Ea#xQ#5;r%y0A(8}b!1z5Nd_kswJ-?;;{rCJCbG3VD~CHlWd!JHIR!
z*3N+kY6h4RNLyd<NT*u5+fl}zs-D!ATnP#Qr8|djTdUDGI4QH@${{W(4j3j813O|G
zF}=Usc+aj|6{(kQEh?Y|PpW3H$I4^&%SD)SQUM~zC5cYiqMbd0OjS>Kh1Ju82L~&^
z-IQ5bYhsjqJfr38iwi~8<{oeREh|3l)*Enj4&Q$+mM$15YqwXeufK9P^(O=pj=F-1
zD+&REgwY~!W#ZPccSEi(*jiKJ<?MT|%g8qxcoe57i_fW^ygO58=en$&NaCobuo=qX
z$RAGF#%9vA=XQ@|P3X5!kOj>5)Q|zX;hP}S2T9j_);epH9JQs{n>RG}{Nak)vIbfa
zFQm?H;D+tzrBN2)6{?Mo%fzN6;6d_h0Qyn61)+XT63=!T*WQyRUoB_x0_)Ir`$FtS
zak07C(mOaWN5m%bk?F9X&@mEVKN%{R6obt(9qw&p>w&p;R*l2th9$D^*`pC}NmB+v
z>bk;OJ(C8p$G;jNvRsBbt=a!!tKnjJ`9*yQFgjEN1HcC<&>u<ZoMlc-s)v(P64;BT
zl^{Md(pr2hzy<{#9J6JxF;oA4Y7TE(gYM=!LJacMzy`FWgo{D^0O3NT@#f@2_M!pF
zs>9aStT3>Oq=MOQV!#WOZ6{cv$YVmlJdovPRV}<=IZUPeBV<Mjc(p_0bG*G=>h5DC
z91-?kimq3JUr;UMQ@0?h52gupvG=~(5<y$VSEg97xbAV3%%*BTe;pxJsT#6Jb_oM{
zt6q-h-giM%uI_nix}lPSabe1+$8tXN3W$hlysAxC;01B0iYCOs6gHA@&oTxbkuSdo
z&ivrAW%vO@3sqpg>AVdP(2(%*sL8!#K1-L$9B7MrWGdt(h&whR@vz~0oEHF8u3U1Q
zdGdaIytJj4x@eF*E+^zgi{nPCA8tkjN}UoR8WhDzM3-zLqx0z?2tTdDKyENM<i}?_
zZWW5IP_WawsH2+L)Bf=0)i*;fKhhDp##|iT2C!UbgsI|=Om~tqa+mYrqHY<wXRfIe
z>={fp8VC@3Dt`AiK$;K#H$K2{08mrHG%jgEOLX3MCsG>afZm_0mLPS4jmYUJp~Dm!
z5AUe_vEaOAT3zWdwl#cLvqwd1^lwW?gt7(92wEsOE6c#<0}{szFV4(uO70?3>=((!
zQr}1{J?Wx2ZmjxYL_8OB*m&mimfojzYn~PiJ2g8R&ZRx-i^yF#sdhEWXAUIZ@J?T$
zs3PgT2<&Ki>Bob_n(@S>kUIvE+nY~ti9~6j;O9VAG#{oZ!DZCW)}i6iA!Tgsyz+hC
z1VVyvbQ_nwgdZSEP=U4d#U`2*`e~d4y8uM4Bcmm%!jidaee#4WqN!ZnlBmbYpuaO!
z!rU3`Kl2<aK(wd1=<|{!Jr0}mfZCH4Wln@U7V4tU^q=QwQRt+LvDEJj*ed;$JtA6)
zPN@=w_hCNoQva(^IouC|<;=}VabKwnfB_|<JvYzcEg<Nj{HrBNFVj{jhPo6jj!}aJ
zetPH*J=EmNxrAC`W7^gS)Pqdy*n`T4j$Bxg9{_`^czPxLMJ+M#&HD#bJ=C0tnJpm>
z0O7PD&fQ|_b)Ub!g<YV7b$H0@0KY+#4BI0?Nd~W?<Zxx1b&!1$K_u1S8RYt#pO#$H
zvrlLh(B`H0=E3q@^3{3bh;oyt(|lh3qgR)fE8ynKz>9^s;C2e>1i*2&?1$6yEn?~Y
zI)-WIN8N(5s9;grW+J@K@I%g#?G&hzmlgV=L}ZA{f>3YCMx^P{u@c5Z;U1qmdk#)L
zvX6z1!sL>+@vxO8qVn#k3YxYi?8ggV){?Rn@j$+Fd4-QkuH1@)j#3-=f82GZ!nl~{
zzZ(?kO`ANttVeHSo%xmH!NmNZECh*{s!-8S>ALoe5xOPs>|P5BbUmP@rlV8`d(c=7
zypcp<iW%>LaI*FM^;GM%@q`GAb8kO`$oE|R4<c5@fDa_-qP{8~9~OTjn%$fHIyCUG
zzTL`5_bhGwmdB6WZu<Pil6LuSm0al&lS|@<r$GrQ?`I)7*syPn&%rF?FPilOo1Frt
zJ>8yn)?p(c1t>5;Wwn5r6ck&uw4}TnT80jI`IS~J%q8CpaVgIze<8IykSpVBg8~E!
zW_tGqB;GO47r_er05y+Kwrcn{VLxL*1;HMv@*sd}MB6DH4zaP~u4Y;>@Nw7?F8S?c
zfVIY(^ntnGgWlD|idzGz$Y+Oh(Ra=&VIf4!K2W*a)(%5%78s}8qxOknAGtDAq+HMO
z<Bz{+oo;BDGD2xe*yxg@zl&K+v22V<|MlmIr*1tS|EK3kT4_-4GO|RfRFyw~=vz_F
zqe(*zpVZp8<#NYt3pmsvf-uh1-^uSN!7{s2et|HzXD9Mm`doC@e>M+Nu;0OgQRn36
zA@~a8`uVQ~v9?d!BxnsVaB-z-djypO44BjQAmg7&eVoaew|~)wH$SgefJ2$7_RiY+
z_7ACGoFM6Lhvho+eUG@pU&0X(Uy(*j;9pr?ET?FHTXadlfXC|MReZoU5>AG`mTM<%
zc~*I@E*u0|hwVTdFA~4^b2VT7_~}~tCueNY{de3og=ASFQ`)0dhC2~Ne<}}Rc?ptA
zi}+bQE%N9o*hpSUMH)9xt%Zlz&^p&5=cW}{m#f85iVX64^{!(vhClT<<FP0I=9r2M
z%yS>I)+c)RuiyrZqIw4v`z%YK&;_Fh4_+0B?qAGxMfAM`LzG_bjD>ib4;KGT4<v~u
zrUU;eep+WRS?Is>_1I>sxvL&&qp40ajgQOqIE^9=Az4w#ymo)bW-Vg{T!n=l&|nR_
zw+wcH|FxUH63)~{M;goHepmD{Fe?W9sO|eJP9L$G<{e_7FxxuXQ+)(Z^@;X8I1=%k
zTK$gbHA1^4W<`q~ubQ0M_C^CA5#Z&*nGc(T?4Y_2jLu&FJDQYpCSiRny->$+nC9Jl
z?avTW`ZXYT51%SrEq!}dXNM&!pM6nmL^lce=%S7{_TS)ckN8;{p*LT~LMgmlE~dpL
zEBQy-jDj%cSK6N3)|CCR0LQ$N6iDM~+-1Oz|LAdkip(VZcO`gqCuJ+(Mm{m6@P%_;
zBtF|MMVMP;E`5NJ{&@4j^JE5j&}(Jq{lCGL(P^#uqvbD`2)FVyfNgy|pvT!XY;02Z
zZWbgGsvi6#!*$Zxwd{Xk6_M{+^yV_K@%_SAW(x)Lg|*AuG-%g2#GQYk8F?W&8|2dU
z;00ppzrQnnYXnT`(S%_qF2#QNz&@Y$zcq+O8p>Gto2&4z8(^#cY?DuQwBQ<R2F!0;
zL0i;Al&JSt3AiWd(MNAuQ|LDv54zvDDT)#IYWd%>P4Fe?qUK_-yh4xT{8O@gb`uh`
z>Q%jrgPAnANn<X%Ab^mkTx!C_I?obe<H-n9sJV~DPA=HKVw+Pqr8yzFYpndG{ys^v
ztbgDNd!6Ek5+fJEjx^^mk>4_)->n;w{Mei#J)F+`12&+-MLKSRzF6bL3;4O~oy~v7
zL0K-=m?>>(^qDCgvFRLBI@`04EGdTxe5}xBg#7#Wb!aUED;?5BLDEvZ@tai4*Rh8&
z4V)cOr}DJ0&(FjWH%50Y+&=WtB42^eEVsmaHG)Il#j265oK&Bot(+-IIn`6InmuE#
z;)qXs+X{fSb8^rYb#46X5?KCzH9X0>ppBQi(aKS--;4yA%0N|D<#8RZlOS(8n26=u
zv~<NnQoqdeVnSL0ix$1=!kGoSaNLoEfxW34n!`*Jgk<wm=@}|snQvuo1&+8g$VoLy
zbm+XDvIJ%^LS?y&utDCRpIhk{$21PSD+P}8*=3wAF(Vd0DXsv_2FRp9$pdl2uC{=k
zjAr+J%mem&rT+)1FFmz5fG7d9TX4h#JuRIhWJ+D#+xmV@{lSHx+|YJc_F1%^*Z(N`
zEk5tuCk;*f|4#WJCg|Fm00dj&X!)?cvoN=!rky0Kmi6+wPg>y;KC>`ypW=aqj`&x9
z0Zm>NKp<m=AL-*_ulV^c=aRbed=w8wQ=qsxzpYm2O?L|YK3~IqfiTX^|A&4fhbU3f
z0}S>}hPJu1+QDo<v`mN3tjW8~<kk>(_U(Gt0SZ`IJWnp%QK`pye>Bm!w{sG>;VU^2
z4lZhV1}tCE8(?zu#j99|l3-qRBcz3bG+DlyxPGB$^6B^ssc_qYQ6lG0q~EAI?1$?(
zahfn%etVvuKwB7R=>JDQluP97nLDM6*5;b0Ox#b{4nIgZA*+?IvyDN{K9WGnlA=Ju
z+)6hjr}{;GxQQIDr3*lf32lRp{<XwWfx+CXf?>nHP8uiz^Fa|<qAV@%&JNy<l*cXM
zftfGb#vEU2;5)rCvyHJ!9}5I^rJ8*BK&!As?PW;ok4d7J(AEIWyP5;zJ<rc&$!xwq
z;FW3o@n_xcXjx!-b-3(O^DtmCA{67v*$*Mkl~ug~tKCm$mjOe=pWTWmU6Rz3_J=Np
z6Dm*9ew0)rJod<mgpR#p>K+dUc@wD4Kf5RPxVkUZFCdtZH{+=c$AC)G2T-Qn@BPbr
zZigIhKhKrVYy`!Mlc#HVr=CURVrhUjExhI~gZ%a=WM9BwvnN?=z!_ZQ$(sP?X;2Jy
zyI$}H^^SvH2tf6+Uk$pJww@ngzPp856-l9g6WtW+%Yf>N^A}->#<OdlRlrDy-c0GC
zjCr7z(zF-JiCzA)HQ!45fP2RZKJzx%eEtqD@6-*KBf{dn6wbaXi-o5a2p#=FQJ_2o
zyz#B41*khPrd-l$aH6mE@$AV1EsN`h^4CeHO=l><x52S|(>1W2n=WJ%sZ0<){Z&#%
z^Kzl$>Km)sIxKLFjtc;}bZeoaZSpL4>`jCmAeRM-NP9sQ&-mi@p0j7Iq>1n&z@8?M
z%dM7K^SgE5z)@i5w#rLE4+8%|^J`a6wYr`3BlvdD>7xW?Dd>`0HC0o{w7r_ot~h*G
z2gI7Y!AUZ6YN+z$=GNzns@Tu7BxgAb3MBha30-ZG7a%rckU5}y{df`lj@^+34kr5>
z988PPbWYdHye~=?>uZ4N&MN@4RBLk_?9W*b$}jqt0j%>yO9QOV(*!#cX~=wRdVL&S
zhPQ{${0CGU-rfdS&b@u|IK{hV2Z=(*B2d0?&jwWfT=?Gk`4T9TfMQ)CfNgpLQa#>Q
z%6A$w#QNc&qOtrHAbqY>J782@!X{9Y@N(HMSr;PP^;0Dl<ekSr<>JNxfC`oMB%Ocg
zC*hnEsF|p*=CVe^dT)>BTL0yff)uo!U<+_2o3p)CE8quU1JI(=6)9$KxVdJYD*S*~
zzNeSkzFIQyqK}578+<tVtN?ksKvx2B`PHYB;FBotPlw7=(K46E1to>qq6X8rrRdgX
z4k&R=AGex~a)MoB0pK&|yA<(*J#P&tR?ImBVD)ZTA4VH5L5D<h?c|3EvZ^!R*@#C4
zbwy*=@iVvPr}b3j+TJ|AHj4*)Ha9qj*Ng71aNx0?RGB)}t@&&xwr69%0|r0X2)dkS
zO70Y}ZcR8Oqy4JbeL<>xXe<-*s`Aox%H1{-^Qa`kG_DGXD%QX-;l1#&#IVQP6>kir
ztO@~ZvJDPnTvKt>fc*(j$W^)JhWk{4kWwbpFIXzuPt2V%M4H19-i5Gn*6(D`4_c1+
zYoI1@yT^~9JF~t>2eVM6p=GP3b*;daJpQOhAMNO|LKnwE2B5n8y9mf;q=)-L_FfD0
z<}YIRBO{k)6AHAn8iG>pYT+3bJ7jvP9}LSMR1<Xp4HrOTs8d4Y>nZW$5HR%PD1rFz
z{4XE^Vmi-QX#?|Farz=CYS_8!%$E#G%4j2+;Avz|9QBj|YIExYk?y-1(j}0h{$$<o
z*?rKt+3|<1Bi_rABg{3E)&=!2!WMJs*9A9H?CydPs>MnC_*F0U2*ExSi1ZCb_S9aV
zTgyGP0Cl=m`emxM4Qih1E{`J{4oJo8K}WnH`@js^pR7Z-vTBK5F5JIFCDN}<p_`<~
zQpXl!3n<V7pe|mkrNylm#E%R4yzXFiJaGe136Qt4V*c*d2zJ{LOFwgAK6@P#OS$Pd
z)6y1R{Q6idBn{dXc6kweStX;}RthnB+Y5d75~wyuKmW*1(t|b*PJ2R)F(pyM&UZpq
z&}{!VE;(?3fsx)$YtD41hZTRCvGp4a{Ggg_m-T6Gp;N=w=4h69o@v11owAM)adDFL
zx{rS1$Hn4Yohg>7pU^_nV>NTz@2$|Kcc5o+L&^Db_AQ);F?)X5BF*QJRCdLI-a%gW
z++DZM)x=6*fNrSaUA&hf&CUqC$F*y^CJC-MAm9gd*5#^mh;-dR1?a&<3-hp3@}XN!
z&8dcwo6=MQua%0KFvYbi>O{j)RrbDQo3S*y!oEJ~2=}^-v%zn~@hnmKGOvX6JL<kT
zNBqc%We7m8c^X)37j<O%1g&K62qOf)p)UQ)N|!Si40N$-_$O@#Cpn$8IMWd1&vzEE
zL8rrD9`-}IHI82VSW_F{iOAO*mh%l_q1)cwwbH&M3P(ExfQ-G^)X@fbh+8pD%nO;W
ziG@ngWoxB5pjFI3e^QTgO#JwVF!j}xI5mh@@@>r;>DNC3)={8OM<Dy%yS4D205Fn(
zX=2_%ZLoJrk@93DNp^U4?yw?m1hu%U2R#A4!757*2UHbw2L1sDI(~9|%<ct+qa+a)
zj@&9Khv40>9n5Zs*(DlS*|%JTniJX2Uav7sOFT0vdIiUOC5pEtY?EF)@Fh9pCfD%N
zXskZ8b^ldI{HHj{-l?iWo@IW6Nr`hAS>f8S*8FGc*gmcK^f2JS+>I&r#Gcewy=-JM
zv0*w<5qBa6UQB@`esOG*4*t@7c9AkrTp<t5hFd4+T4L$3d?5aG3((&4P7{A=0XtL`
zYvmoX>M`v=eY?cO#z17H9B%Xy4m!}LhW}*iZ27w1?HrevgB1SZ1q2X$mm@FK@Qt7o
z!s~Lio^IRdwzyvQ80{5iYeTV@mAo=2o5>KepRH0d{*Szlg~n%w2)S5v2|K8}pj;c{
zoDRLvYJO1@?x-=mq+LVhD{l-1-Dw<!hVrSst3G~Rxh<<#AGgtwo$Pbh_QD$8I5tzG
zjZSqn@anJAld9P9`Z!6)MV@0TK&}AF#HD^;?4LrR8?^pD9G&F$KkEA#v~Vf(A0;sU
z6|R})do$fbL#~sBcGAX}O<Vhlmx?%-Iv6PW=lt;;1+{NAMB=`Qm1TT3a>4`7M?3@+
z`fu7?1#9W++6Y46N=H0+bD|CJH~q*CdEBm8D##VS7`cXy4~+x=<QO?*dJ7)%BOHio
zk)!}+mKG#Dkj8Z%-<Mc=@vJEJMG|Rb2e<KNh<RrpuqySueB$MBzMuhQCna4^cd-A(
zo5+AC?X!U5V~fekR^CA*rR@B7Exf{^=@Z8YZR6!tMEVxcnPUFKLfSwn>ZC17rJeBh
zI~qW^&FU`+e!{AKO3(>z5Ghh14bUT$=4B<l=<$uuaZulI=la+3L-{`#>>@DVm(cj*
zSLA*j!?z!=SLuVvAPh_EFKx}JE8T8;Gx)LH^H136=#Jn3Bo*@?=S`5M{WJPY&~ODs
z+^V57DhJ2kD^Z|&;H}eoN~sxS8~cN5u1eW{t&y{!ouH`%p4(yDZaqw$%dlm4A0f0|
z8H}XZFDs?3QuqI^PEy}T;r!5+QpfKEt&V|D)Z*xoJ?XXZ+k!sU2X!rcTF4tg8vWPM
zr-JE>iu9DZK`#R5gQO{nyGDALY!l@M&eZsc*j*H~l4lD)8S?R*nrdxn?ELUR4kxK?
zH(t9IM~^mfPs9WxR>J{agadQg@N6%=tUQ8Bn++TC|Hbqn*q;WydeNIS@gt|3j!P`w
zxCKoeKQ*WBlF%l4-apIhERKl(hXS1vVk$U?Wifi)&lL6vF@bmFXmQEe{=$iG)Zt*l
z0df@_)B-P_^K2P7h=>OIQ6f0Q-E@|M?$Z5n^oN>2_sBCpN>q(LnqUoef{tm^5^L$#
z{<G^VUZy%FbkEvx*&nJB@2lYh7g5N|><<Azp;!ZSq5fh8aSu+uV7Ju~yF2-fQN>SL
zKmH78cHX`4cBKIY8u1x*lwrgP^fJ%E&&AmHrRY7^hH*=2OA9K?!+|~Aeia=nAA`5~
z#zI=h#I>@FXaGk(n)0uqelNY;A5I9obE~OjsuW!%^NxK*52CfBPWYuw--v<1v|B>h
z8<d@QfEBtab*BQ@0pyvFqU!y~%8z;+lUVw43Iv>R=#$TS-Pt3?d@P+xqmYpL4oB8-
z>w99}%xqy9W!A^ODfLq<yl-TEk~DC_X)H5c{0?B6!k%8iax3yT3{#DUPblK<{0uL@
zFgja4-Ghcu_tb)1X)@zXq!x#G4aAd~-hB$V#L451NGkQ=XFabV?~DT8Jx6wln%t&;
z27dclRQ%Nb=uO}#OF`Y0HN??f1E}MCi|=>8iA@z}10u?o#nG#MXumSaybi(S{`wIM
z&nE3n2gWWMu93EvtofWzvG2{v;$ysuw^8q?3n}y=pB1vUr5gi++PjiyBH3jzKBRny
zSO~O++1ZLdy7v7VzS&$yY;^Z7*j_#BI`PK`dAzJa9G1{9ahPqPi1C}ti+L)WHii*=
z+RZ^+at-tlatc4|akPa&9H;%gn9aS`X_kfb>n>#NTyUVM6m4NCIfLm(28>qaYv7}t
zn`M<L_RgRwQtG)L2jDHf!wV%Gz9}}14&oEd*jw07gWK-08e2QqR`bo#`^K}MeAY-C
zTmgNb{8DPv^G`l2?&;vc=}0f5e#1{kh&!hWru(L&(J>;XcONtXoa3#u3{L-ytd_&g
z2mO$8CnE?460w#eSm|smlnNwFHM;A&Ix<T{6<XR65_kvDI?K6T6HE6&s8rBe(KXjX
z%zNzu>SKLzVkV<v(K%3>7nNVqZ*A`)eI{Nbg6WxsarAFuc=FFf1z|%#eTvBgUhY}N
zsCT>`_YO>14i^vFX0KXbARLItzT{TeD%N~=ovGtZ6j{>PxkuYlHNTe0!u>rgw#?td
z{)n=QrGvgCDE6BUem$Rh(1y!$@(Bn!k3E0|>PQ(8O==zN`?yBhAqlWyq+c%+h?p^-
zE&OtLind}^_=>pbhxOgOIC0q9{cLK6p6*eg_|S+p9$W~_u4wzx@N?$QmFg2S)m~^R
znni$X{U*!lHgdS@fI;|Owl<v8cAEoFH(*1-<(nr=Wmd$F+l;42kJ1k03g-EHbggf*
z5^=4v#P3{ZJXPv}YDgc8B)qp<R@(5X3m)qXi<*>=9Gwi?dr0m#>yL<8<}bLW_Kpl|
zSGesADX&n?qmHC`2GyIev^hi~ka}ISZ^Y4w-yUzyPxaJB0mm%<loIfE_E0+&{@#^E
zU_YIl@#I7f-DBS`edLy=La~>ww^>if3<;P^U+L5=s+cifT-ct<o*l7a{UcjmQlH2U
z0VPFuaMsR}iZY9dP0dDy+y7<)lNibtm2XI6=tK6II&VkE$Jw{ZkNZZ_=o&}oqd$g(
z<(KXb0akdoyq?|hYpcEV4EV02dtD)K=79|St2be_9nGy7OP**ooXeU;55E&o3ES*O
zBb!qvt{Z=m0=Y;XjXcpCjLjxgq+Znk_M84q8-H{mXsej^teo#RC82yC)BH#z0zJ_U
ztd+yX@M4L#4vo_;>*;!dOOk#SOZNv@a^J|DrS3YtSn8EEAlabX1NV3RfHwZn_41Xa
z4;$taa6JJR()-FQ<#0G~WlML<<Jyt?<YE`OqO0PP*EPSp4#m<rK!C2_nQKus7vE?4
zMHO=L;-GiDG3$G9v^pOD4m5uIPTe#;HCjcYrYRG<h(wT+Jdy<N1Q2Ervxt(}mDXh!
zQowA`&+Q<=R&L2D;Pm1^v500Stp+|(a5&>l5I+IPnqDpW(PP>hRcQ+S2zU?tbG^(y
z1K_?1R){jF;OKGw0WYjnm>aPxnmr5?bP?^B-|Fv`TT4ecH3O`Z3`X_r;vgFn>t1tE
zGE6W2PODPKUj+@a%3lB;lS?srE5lp(tZ;uvz<Hikq{C4{9{8SM>rPb){f~n7v_^z!
z=16!Vdm!Q0q#?jy0qY%#0d^J8D9o)A;Rj!~j%u>KPs-tB08{4s1ry9VS>gW~5o^L;
z7vyjmfXDGRVFa@-mis2!a$GI@9kE*pe3y_C3-$iVGUTQzZ<Iud8GypIP=x69)}}Z{
zygNG%uBiDA5+b@R_%h?xb3L!t)6r7>E+%>vT0=r|2%xMDBC@>WlkGU4CjoWs@D(rZ
zS1NB#e69fvI^O#5r$Hj;bhHPEE4)4q5*t5Gyj<A5>zyc{)o459VkEhJ$%hJUC&67k
z7gdo`Q*Jm3R&?ueqBezPTa}OI9wqcc;FRTcfVXob^z|dNIB0hMkHV26$zA%YgR$sM
zTKM6<kcKx>1S}#wJ#u+0UDE3N+U*~Tz1nnV;W<8Akz&6M7-6mIF(Pq`wJ1A%loYL(
zIS;&2((xbyL7zoyaY2Sa%BBYBxo6Aa*53`~e@|RA`MP+<v+{1S9>?iI4KZ+y4EU&I
zS_|(#*&j2hxpELa3r0O7ok&5!ijRiRu9i-_3cdnydZU9Mp6Y);skv%!$~`i-J7e-g
zj@EoHf+gtcrKf;tY5`4iLnWSHa)9brUM$XmEzG3T0BXTG_+0}p7uGLs^(uYh0j$;~
zT1&~S%_Y5VImvf1EkD7vP-@F%hRlBe{a@T!SW(4WEQd1!O47*Crf@u-TS==48iR5x
z!*`Ul4AJI^vIVaN3u5UifXBX{fJ@z>4Q2#1?jpcdLocwymBgKrZ+^Cb@QuIxl58B*
zD{t-W3;M;{MGHm_@&<V7ayWCz+D-tm2~jPRB5_<^=UQO1web}OC+mn3SctxVSOcGS
z{e*1V%A(PR)?wN_$L##lrfYiL1aNBiJ$=3OokVO&OKbgVy;wR;LhjpO{KW<5fu5M;
z<o{5NQNt?$57PJsM0t|Ft`fmwt^ArZ^)evNjK)FsMj)soz#oT(r}plQrP~H9fI^qv
z01#Kn>n(6A-AsD;JO#>J3o4ru{hy;k;8?=rkp0tadEEcHNECoTI(W31`El-CI0eWQ
zWD4&2ehvACkLCjG`82T`L^cNNC4Oo2IH(T4e;C75IwkJ&`|ArqSKD}TX_-E*eeiU&
ziUuAC)A?d>-;@9Jcmsdca>@q1`6vzo^3etEH%1Gco&gvC{;Y-qyJ$Re`#A!5Kd((5
z6sSiKnA20uPX0**Mu&6tNgTunUR1sodoNmDst1&wz8v7AG3=^huypTi`S7+GrO$D6
z)0Ja-y5r?QQ+&jVQBjit<YfcAtuqP9b&;6Me_ZRc{Fc{z>IZ`z2Ia}iXWf#=#>nU+
zL29$)Q>f#o<#4deo!Kuo@WX{G(`eLaf%(_Nc}E`q=BXHMS(Os{!g%(|&tTDIczE_#
z5y%wjCp9S?&*8bS3imJi_9_COC)-_;6D9~8Om@?U2PGQpM^7LKG7Q~(AoSRgP#<gW
zU?1=YT4T1_%ES!(Yrc22xwW~O_3G6oW){|FW|_tzr~jV?rvr|iJbvN-zo04TV-r{a
OIc;`vc)7{z(*FShbtRtw

diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
index 8a31fe2dd3f91d79cab6e0390356bb3c1a355f94..b81789038bb1b5e0704d296cdcab37af92284870 100644
GIT binary patch
delta 2433
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

delta 1860
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

diff --git a/pubspec.lock b/pubspec.lock
index 0b8f49c2c..f12b25487 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -205,6 +205,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.1"
+  cli_util:
+    dependency: transitive
+    description:
+      name: cli_util
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.5"
   clock:
     dependency: transitive
     description:
@@ -494,7 +501,7 @@ packages:
       name: flutter_launcher_icons
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.9.3"
+    version: "0.11.0"
   flutter_libepiccash:
     dependency: "direct main"
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index af4370d99..b1312427d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -141,7 +141,7 @@ dev_dependencies:
   integration_test:
       sdk: flutter
   build_runner: ^2.1.7
-  flutter_launcher_icons: ^0.9.3
+  flutter_launcher_icons: ^0.11.0
   hive_generator: ^1.1.2
   dependency_validator: ^3.1.2
   hive_test: ^1.0.1
@@ -160,6 +160,13 @@ flutter_icons:
   image_path_android: assets/icon/app_icon_alpha.png
   image_path_ios: assets/icon/icon.png
   remove_alpha_ios: true
+  windows:
+    generate: true
+    image_path: assets/icon/icon.png
+    icon_size: 48 # min:48, max:256, default: 48
+  macos:
+    generate: true
+    image_path: assets/icon/icon.png
 
 flutter_native_splash:
   image: assets/images/splash.png
diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico
index c04e20caf6370ebb9253ad831cc31de4a9c965f6..eee73d91b8f7daeadfb6dcb917cdb15466910278 100644
GIT binary patch
literal 1968
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
CG^h~(

literal 33772
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


From a8b0901ec664e9f1bee21222cd5d4e319e92aeff Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 15:32:06 -0600
Subject: [PATCH 380/426] desktop exchange navigation flow fix

---
 lib/pages/exchange_view/confirm_change_now_send.dart | 12 ++++++++++++
 lib/pages/exchange_view/send_from_view.dart          |  6 ++++++
 .../exchange_steps/subwidgets/desktop_step_4.dart    |  1 +
 3 files changed, 19 insertions(+)

diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index 9f62bd8ec..540067915 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -37,6 +37,7 @@ class ConfirmChangeNowSendView extends ConsumerStatefulWidget {
     this.routeOnSuccessName = WalletView.routeName,
     required this.trade,
     this.shouldSendPublicFiroFunds,
+    this.fromDesktopStep4 = false,
   }) : super(key: key);
 
   static const String routeName = "/confirmChangeNowSend";
@@ -46,6 +47,7 @@ class ConfirmChangeNowSendView extends ConsumerStatefulWidget {
   final String routeOnSuccessName;
   final Trade trade;
   final bool? shouldSendPublicFiroFunds;
+  final bool fromDesktopStep4;
 
   @override
   ConsumerState<ConfirmChangeNowSendView> createState() =>
@@ -105,7 +107,17 @@ class _ConfirmChangeNowSendViewState
       if (mounted) {
         if (Util.isDesktop) {
           Navigator.of(context, rootNavigator: true).pop();
+
+          // stupid hack
+          if (widget.fromDesktopStep4) {
+            Navigator.of(context, rootNavigator: true).pop();
+            Navigator.of(context, rootNavigator: true).pop();
+            Navigator.of(context, rootNavigator: true).pop();
+            Navigator.of(context, rootNavigator: true).pop();
+            Navigator.of(context, rootNavigator: true).pop();
+          }
         }
+
         Navigator.of(context).popUntil(ModalRoute.withName(routeOnSuccessName));
       }
     } catch (e) {
diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart
index 7cbf38384..7c5f5541c 100644
--- a/lib/pages/exchange_view/send_from_view.dart
+++ b/lib/pages/exchange_view/send_from_view.dart
@@ -38,6 +38,7 @@ class SendFromView extends ConsumerStatefulWidget {
     required this.amount,
     required this.address,
     this.shouldPopRoot = false,
+    this.fromDesktopStep4 = false,
   }) : super(key: key);
 
   static const String routeName = "/sendFrom";
@@ -47,6 +48,7 @@ class SendFromView extends ConsumerStatefulWidget {
   final String address;
   final Trade trade;
   final bool shouldPopRoot;
+  final bool fromDesktopStep4;
 
   @override
   ConsumerState<SendFromView> createState() => _SendFromViewState();
@@ -191,6 +193,7 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
                       amount: amount,
                       address: address,
                       trade: trade,
+                      fromDesktopStep4: widget.fromDesktopStep4,
                     ),
                   );
                 },
@@ -210,12 +213,14 @@ class SendFromCard extends ConsumerStatefulWidget {
     required this.amount,
     required this.address,
     required this.trade,
+    this.fromDesktopStep4 = false,
   }) : super(key: key);
 
   final String walletId;
   final Decimal amount;
   final String address;
   final Trade trade;
+  final bool fromDesktopStep4;
 
   @override
   ConsumerState<SendFromCard> createState() => _SendFromCardState();
@@ -323,6 +328,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
                     : HomeView.routeName,
                 trade: trade,
                 shouldSendPublicFiroFunds: shouldSendPublicFiroFunds,
+                fromDesktopStep4: widget.fromDesktopStep4,
               ),
               settings: const RouteSettings(
                 name: ConfirmChangeNowSendView.routeName,
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
index c86713a76..5b69f064d 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
@@ -224,6 +224,7 @@ class _DesktopStep4State extends ConsumerState<DesktopStep4> {
                                 amount: amount,
                                 address: address,
                                 shouldPopRoot: true,
+                                fromDesktopStep4: true,
                               ),
                               const RouteSettings(
                                 name: SendFromView.routeName,

From c3a3dd3180358f0f1e2faae0cf16c6d7a8b4ecb4 Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Tue, 22 Nov 2022 11:48:52 -0600
Subject: [PATCH 381/426] remove Wownero if isDesktop

or isLinux or isWindows or isMacOS, respectively
---
 .../add_wallet_view/sub_widgets/searchable_coin_list.dart    | 5 +++++
 lib/utilities/enums/coin_enum.dart                           | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart
index d89d42bbf..38181b9e1 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart
@@ -32,6 +32,11 @@ class SearchableCoinList extends ConsumerWidget {
     // remove firo testnet regardless
     _coins.remove(Coin.firoTestNet);
 
+    // Kidgloves for Wownero on desktop
+    if(isDesktop) {
+      _coins.remove(Coin.wownero);
+    }
+
     return _coins;
   }
 
diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart
index 48212bde8..f80c40f52 100644
--- a/lib/utilities/enums/coin_enum.dart
+++ b/lib/utilities/enums/coin_enum.dart
@@ -12,6 +12,7 @@ import 'package:stackwallet/services/coins/monero/monero_wallet.dart' as xmr;
 import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'
     as nmc;
 import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart' as wow;
+import 'dart:io' show Platform;
 
 enum Coin {
   bitcoin,
@@ -36,8 +37,7 @@ enum Coin {
   firoTestNet,
 }
 
-// remove firotestnet for now
-const int kTestNetCoinCount = 4;
+int kTestNetCoinCount = (Platform.isLinux || Platform.isWindows || Platform.isMacOS) ? 5 : 4;
 
 extension CoinExt on Coin {
   String get prettyName {

From 3306cf8b99f4afd54030bdef8746eb5de89adf6c Mon Sep 17 00:00:00 2001
From: sneurlax <sneurlax@gmail.com>
Date: Tue, 22 Nov 2022 11:56:13 -0600
Subject: [PATCH 382/426] expand the ternary for readability

---
 lib/utilities/enums/coin_enum.dart | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart
index f80c40f52..648407809 100644
--- a/lib/utilities/enums/coin_enum.dart
+++ b/lib/utilities/enums/coin_enum.dart
@@ -37,7 +37,12 @@ enum Coin {
   firoTestNet,
 }
 
-int kTestNetCoinCount = (Platform.isLinux || Platform.isWindows || Platform.isMacOS) ? 5 : 4;
+if(Platform.isLinux || Platform.isWindows || Platform.isMacOS) {
+  int kTestNetCoinCount = 5; // Because we are removing Wownero from Desktop
+} else {
+  // remove firotestnet for now
+  int kTestNetCoinCount = 4;
+}
 
 extension CoinExt on Coin {
   String get prettyName {

From 172b3d157bacc84dff2dece8b4fd0c11ca9e1487 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 15:37:47 -0600
Subject: [PATCH 383/426] wownero disable on desktop fix

---
 lib/utilities/enums/coin_enum.dart | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart
index 648407809..543a193ee 100644
--- a/lib/utilities/enums/coin_enum.dart
+++ b/lib/utilities/enums/coin_enum.dart
@@ -12,7 +12,7 @@ import 'package:stackwallet/services/coins/monero/monero_wallet.dart' as xmr;
 import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'
     as nmc;
 import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart' as wow;
-import 'dart:io' show Platform;
+import 'package:stackwallet/utilities/util.dart';
 
 enum Coin {
   bitcoin,
@@ -37,12 +37,7 @@ enum Coin {
   firoTestNet,
 }
 
-if(Platform.isLinux || Platform.isWindows || Platform.isMacOS) {
-  int kTestNetCoinCount = 5; // Because we are removing Wownero from Desktop
-} else {
-  // remove firotestnet for now
-  int kTestNetCoinCount = 4;
-}
+final int kTestNetCoinCount = Util.isDesktop ? 5 : 4;
 
 extension CoinExt on Coin {
   String get prettyName {

From 157829a933da78229e6279aeb3ae1fcc8409307b Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 15:53:16 -0600
Subject: [PATCH 384/426] fixed failing test

---
 test/widget_tests/address_book_card_test.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/widget_tests/address_book_card_test.dart b/test/widget_tests/address_book_card_test.dart
index 7c53d8d50..07b1387df 100644
--- a/test/widget_tests/address_book_card_test.dart
+++ b/test/widget_tests/address_book_card_test.dart
@@ -70,7 +70,7 @@ void main() {
       await widgetTester.tap(find.byType(RawMaterialButton));
       expect(find.byType(ContactPopUp), findsOneWidget);
     } else if (Util.isDesktop) {
-      expect(find.byType(RawMaterialButton), findsOneWidget);
+      expect(find.byType(RawMaterialButton), findsNothing);
     }
   });
 }

From 467d43d9f3c3c80b4dfc03c8232b56bcefeebc1d Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 16:18:38 -0600
Subject: [PATCH 385/426] desktop trade history scroll fix

---
 .../desktop_exchange_view.dart                |  16 +-
 .../subwidgets/desktop_trade_history.dart     | 368 ++++++++++--------
 2 files changed, 217 insertions(+), 167 deletions(-)

diff --git a/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart b/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart
index 0f44eb59b..105c485f0 100644
--- a/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart
@@ -63,19 +63,9 @@ class _DesktopExchangeViewState extends State<DesktopExchangeView> {
               width: 16,
             ),
             Expanded(
-              child: Column(
-                mainAxisSize: MainAxisSize.min,
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  Text(
-                    "Exchange details",
-                    style: STextStyles.desktopTextExtraExtraSmall(context),
-                  ),
-                  const SizedBox(
-                    height: 16,
-                  ),
-                  const RoundedWhiteContainer(
-                    padding: EdgeInsets.all(0),
+              child: Row(
+                children: const [
+                  Expanded(
                     child: DesktopTradeHistory(),
                   ),
                 ],
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 a8f825911..e31a87dd4 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
@@ -6,6 +6,7 @@ import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
 import 'package:stackwallet/providers/exchange/trade_sent_from_stack_lookup_provider.dart';
 import 'package:stackwallet/providers/global/trades_service_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.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/widgets/rounded_white_container.dart';
@@ -24,6 +25,28 @@ class DesktopTradeHistory extends ConsumerStatefulWidget {
 }
 
 class _DesktopTradeHistoryState extends ConsumerState<DesktopTradeHistory> {
+  BorderRadius get _borderRadiusFirst {
+    return BorderRadius.only(
+      topLeft: Radius.circular(
+        Constants.size.circularBorderRadius,
+      ),
+      topRight: Radius.circular(
+        Constants.size.circularBorderRadius,
+      ),
+    );
+  }
+
+  BorderRadius get _borderRadiusLast {
+    return BorderRadius.only(
+      bottomLeft: Radius.circular(
+        Constants.size.circularBorderRadius,
+      ),
+      bottomRight: Radius.circular(
+        Constants.size.circularBorderRadius,
+      ),
+    );
+  }
+
   @override
   Widget build(BuildContext context) {
     final trades =
@@ -33,169 +56,206 @@ class _DesktopTradeHistoryState extends ConsumerState<DesktopTradeHistory> {
     final hasHistory = tradeCount > 0;
 
     if (hasHistory) {
-      return ListView.separated(
-        shrinkWrap: true,
-        primary: false,
-        itemBuilder: (context, index) {
-          return TradeCard(
-            key: Key("tradeCard_${trades[index].uuid}"),
-            trade: trades[index],
-            onTap: () async {
-              final String tradeId = trades[index].tradeId;
-
-              final lookup = ref.read(tradeSentFromStackLookupProvider).all;
-
-              debugPrint("ALL: $lookup");
-
-              final String? txid = ref
-                  .read(tradeSentFromStackLookupProvider)
-                  .getTxidForTradeId(tradeId);
-              final List<String>? walletIds = ref
-                  .read(tradeSentFromStackLookupProvider)
-                  .getWalletIdsForTradeId(tradeId);
-
-              if (txid != null && walletIds != null && walletIds.isNotEmpty) {
-                final manager = ref
-                    .read(walletsChangeNotifierProvider)
-                    .getManager(walletIds.first);
-
-                debugPrint("name: ${manager.walletName}");
-
-                // TODO store tx data completely locally in isar so we don't lock up ui here when querying txData
-                final txData = await manager.transactionData;
-
-                final tx = txData.getAllTransactions()[txid];
-
-                if (mounted) {
-                  await showDialog<void>(
-                    context: context,
-                    builder: (context) => Navigator(
-                      initialRoute: TradeDetailsView.routeName,
-                      onGenerateRoute: RouteGenerator.generateRoute,
-                      onGenerateInitialRoutes: (_, __) {
-                        return [
-                          FadePageRoute(
-                            DesktopDialog(
-                              // maxHeight:
-                              //     MediaQuery.of(context).size.height - 64,
-                              maxHeight: double.infinity,
-                              maxWidth: 580,
-                              child: Column(
-                                mainAxisSize: MainAxisSize.min,
-                                children: [
-                                  Padding(
-                                    padding: const EdgeInsets.only(
-                                      left: 32,
-                                      bottom: 16,
-                                    ),
-                                    child: Row(
-                                      mainAxisAlignment:
-                                          MainAxisAlignment.spaceBetween,
-                                      children: [
-                                        Text(
-                                          "Trade details",
-                                          style: STextStyles.desktopH3(context),
-                                        ),
-                                        DesktopDialogCloseButton(
-                                          onPressedOverride: Navigator.of(
-                                            context,
-                                            rootNavigator: true,
-                                          ).pop,
-                                        ),
-                                      ],
-                                    ),
-                                  ),
-                                  Flexible(
-                                    child: TradeDetailsView(
-                                      tradeId: tradeId,
-                                      transactionIfSentFromStack: tx,
-                                      walletName: manager.walletName,
-                                      walletId: walletIds.first,
-                                    ),
-                                  ),
-                                ],
-                              ),
-                            ),
-                            const RouteSettings(
-                              name: TradeDetailsView.routeName,
-                            ),
-                          ),
-                        ];
-                      },
-                    ),
-                  );
+      return Column(
+        mainAxisSize: MainAxisSize.min,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Text(
+            "Exchange details",
+            style: STextStyles.desktopTextExtraExtraSmall(context),
+          ),
+          const SizedBox(
+            height: 16,
+          ),
+          Expanded(
+            child: ListView.separated(
+              shrinkWrap: true,
+              primary: false,
+              itemBuilder: (context, index) {
+                BorderRadius? radius;
+                if (index == tradeCount - 1) {
+                  radius = _borderRadiusLast;
+                } else if (index == 0) {
+                  radius = _borderRadiusFirst;
                 }
-              } else {
-                unawaited(
-                  showDialog<void>(
-                    context: context,
-                    builder: (context) => Navigator(
-                      initialRoute: TradeDetailsView.routeName,
-                      onGenerateRoute: RouteGenerator.generateRoute,
-                      onGenerateInitialRoutes: (_, __) {
-                        return [
-                          FadePageRoute(
-                            DesktopDialog(
-                              // maxHeight:
-                              //     MediaQuery.of(context).size.height - 64,
-                              maxHeight: double.infinity,
-                              maxWidth: 580,
-                              child: Column(
-                                mainAxisSize: MainAxisSize.min,
-                                children: [
-                                  Padding(
-                                    padding: const EdgeInsets.only(
-                                      left: 32,
-                                      bottom: 16,
+
+                return Container(
+                  decoration: BoxDecoration(
+                    color: Theme.of(context).extension<StackColors>()!.popupBG,
+                    borderRadius: radius,
+                  ),
+                  child: TradeCard(
+                    key: Key("tradeCard_${trades[index].uuid}"),
+                    trade: trades[index],
+                    onTap: () async {
+                      final String tradeId = trades[index].tradeId;
+
+                      final lookup =
+                          ref.read(tradeSentFromStackLookupProvider).all;
+
+                      debugPrint("ALL: $lookup");
+
+                      final String? txid = ref
+                          .read(tradeSentFromStackLookupProvider)
+                          .getTxidForTradeId(tradeId);
+                      final List<String>? walletIds = ref
+                          .read(tradeSentFromStackLookupProvider)
+                          .getWalletIdsForTradeId(tradeId);
+
+                      if (txid != null &&
+                          walletIds != null &&
+                          walletIds.isNotEmpty) {
+                        final manager = ref
+                            .read(walletsChangeNotifierProvider)
+                            .getManager(walletIds.first);
+
+                        debugPrint("name: ${manager.walletName}");
+
+                        // TODO store tx data completely locally in isar so we don't lock up ui here when querying txData
+                        final txData = await manager.transactionData;
+
+                        final tx = txData.getAllTransactions()[txid];
+
+                        if (mounted) {
+                          await showDialog<void>(
+                            context: context,
+                            builder: (context) => Navigator(
+                              initialRoute: TradeDetailsView.routeName,
+                              onGenerateRoute: RouteGenerator.generateRoute,
+                              onGenerateInitialRoutes: (_, __) {
+                                return [
+                                  FadePageRoute(
+                                    DesktopDialog(
+                                      // maxHeight:
+                                      //     MediaQuery.of(context).size.height - 64,
+                                      maxHeight: double.infinity,
+                                      maxWidth: 580,
+                                      child: Column(
+                                        mainAxisSize: MainAxisSize.min,
+                                        children: [
+                                          Padding(
+                                            padding: const EdgeInsets.only(
+                                              left: 32,
+                                              bottom: 16,
+                                            ),
+                                            child: Row(
+                                              mainAxisAlignment:
+                                                  MainAxisAlignment
+                                                      .spaceBetween,
+                                              children: [
+                                                Text(
+                                                  "Trade details",
+                                                  style: STextStyles.desktopH3(
+                                                      context),
+                                                ),
+                                                DesktopDialogCloseButton(
+                                                  onPressedOverride:
+                                                      Navigator.of(
+                                                    context,
+                                                    rootNavigator: true,
+                                                  ).pop,
+                                                ),
+                                              ],
+                                            ),
+                                          ),
+                                          Flexible(
+                                            child: TradeDetailsView(
+                                              tradeId: tradeId,
+                                              transactionIfSentFromStack: tx,
+                                              walletName: manager.walletName,
+                                              walletId: walletIds.first,
+                                            ),
+                                          ),
+                                        ],
+                                      ),
                                     ),
-                                    child: Row(
-                                      mainAxisAlignment:
-                                          MainAxisAlignment.spaceBetween,
-                                      children: [
-                                        Text(
-                                          "Trade details",
-                                          style: STextStyles.desktopH3(context),
-                                        ),
-                                        DesktopDialogCloseButton(
-                                          onPressedOverride: Navigator.of(
-                                            context,
-                                            rootNavigator: true,
-                                          ).pop,
-                                        ),
-                                      ],
+                                    const RouteSettings(
+                                      name: TradeDetailsView.routeName,
                                     ),
                                   ),
-                                  Flexible(
-                                    child: TradeDetailsView(
-                                      tradeId: tradeId,
-                                      transactionIfSentFromStack: null,
-                                      walletName: null,
-                                      walletId: walletIds?.first,
-                                    ),
-                                  ),
-                                ],
-                              ),
+                                ];
+                              },
                             ),
-                            const RouteSettings(
-                              name: TradeDetailsView.routeName,
+                          );
+                        }
+                      } else {
+                        unawaited(
+                          showDialog<void>(
+                            context: context,
+                            builder: (context) => Navigator(
+                              initialRoute: TradeDetailsView.routeName,
+                              onGenerateRoute: RouteGenerator.generateRoute,
+                              onGenerateInitialRoutes: (_, __) {
+                                return [
+                                  FadePageRoute(
+                                    DesktopDialog(
+                                      // maxHeight:
+                                      //     MediaQuery.of(context).size.height - 64,
+                                      maxHeight: double.infinity,
+                                      maxWidth: 580,
+                                      child: Column(
+                                        mainAxisSize: MainAxisSize.min,
+                                        children: [
+                                          Padding(
+                                            padding: const EdgeInsets.only(
+                                              left: 32,
+                                              bottom: 16,
+                                            ),
+                                            child: Row(
+                                              mainAxisAlignment:
+                                                  MainAxisAlignment
+                                                      .spaceBetween,
+                                              children: [
+                                                Text(
+                                                  "Trade details",
+                                                  style: STextStyles.desktopH3(
+                                                      context),
+                                                ),
+                                                DesktopDialogCloseButton(
+                                                  onPressedOverride:
+                                                      Navigator.of(
+                                                    context,
+                                                    rootNavigator: true,
+                                                  ).pop,
+                                                ),
+                                              ],
+                                            ),
+                                          ),
+                                          Flexible(
+                                            child: TradeDetailsView(
+                                              tradeId: tradeId,
+                                              transactionIfSentFromStack: null,
+                                              walletName: null,
+                                              walletId: walletIds?.first,
+                                            ),
+                                          ),
+                                        ],
+                                      ),
+                                    ),
+                                    const RouteSettings(
+                                      name: TradeDetailsView.routeName,
+                                    ),
+                                  ),
+                                ];
+                              },
                             ),
                           ),
-                        ];
-                      },
-                    ),
+                        );
+                      }
+                    },
                   ),
                 );
-              }
-            },
-          );
-        },
-        separatorBuilder: (context, index) {
-          return Container(
-            height: 1,
-            color: Theme.of(context).extension<StackColors>()!.background,
-          );
-        },
-        itemCount: tradeCount,
+              },
+              separatorBuilder: (context, index) {
+                return Container(
+                  height: 1,
+                  color: Theme.of(context).extension<StackColors>()!.background,
+                );
+              },
+              itemCount: tradeCount,
+            ),
+          ),
+        ],
       );
     } else {
       return RoundedWhiteContainer(

From 4debb0fff9d67087f20743c4c3899996085c6b41 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 16:34:31 -0600
Subject: [PATCH 386/426] desktop block explorer warning dialog navigation fix

---
 .../transaction_views/transaction_details_view.dart    | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
index dc4e41152..4d45428ff 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -266,7 +266,10 @@ class _TransactionDetailsViewState
                           buttonHeight: ButtonHeight.l,
                           label: "Cancel",
                           onPressed: () {
-                            Navigator.of(context).pop(false);
+                            Navigator.of(
+                              context,
+                              rootNavigator: true,
+                            ).pop(false);
                           },
                         ),
                         const SizedBox(width: 20),
@@ -275,7 +278,10 @@ class _TransactionDetailsViewState
                           buttonHeight: ButtonHeight.l,
                           label: "Continue",
                           onPressed: () {
-                            Navigator.of(context).pop(true);
+                            Navigator.of(
+                              context,
+                              rootNavigator: true,
+                            ).pop(true);
                           },
                         ),
                       ],

From 67d375dbd5ba0b994fa9d370dd6787e197a6dbf5 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 22 Nov 2022 16:37:47 -0600
Subject: [PATCH 387/426] desktop new notifications bell icon indicator

---
 .../home/desktop_menu.dart                    | 32 ++++++++++++-------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_menu.dart b/lib/pages_desktop_specific/home/desktop_menu.dart
index 60a424a06..d82d62883 100644
--- a/lib/pages_desktop_specific/home/desktop_menu.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu.dart
@@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_menu_item.dart';
 import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart';
+import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -149,20 +150,27 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                     ),
                     DesktopMenuItem(
                       icon: SvgPicture.asset(
-                        Assets.svg.bell,
+                        ref.watch(notificationsProvider.select(
+                                (value) => value.hasUnreadNotifications))
+                            ? Assets.svg.bellNew(context)
+                            : Assets.svg.bell,
                         width: 20,
                         height: 20,
-                        color: DesktopMenuItemId.notifications ==
-                                ref
-                                    .watch(currentDesktopMenuItemProvider.state)
-                                    .state
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .accentColorDark
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .accentColorDark
-                                .withOpacity(0.8),
+                        color: ref.watch(notificationsProvider.select(
+                                (value) => value.hasUnreadNotifications))
+                            ? null
+                            : DesktopMenuItemId.notifications ==
+                                    ref
+                                        .watch(currentDesktopMenuItemProvider
+                                            .state)
+                                        .state
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorDark
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorDark
+                                    .withOpacity(0.8),
                       ),
                       label: "Notifications",
                       value: DesktopMenuItemId.notifications,

From 7719ad32a5973958e4e9ba6793fb5a110effb891 Mon Sep 17 00:00:00 2001
From: Diego Salazar <diego@cypherstack.com>
Date: Tue, 22 Nov 2022 17:56:14 -0700
Subject: [PATCH 388/426] Bump version (1.5.18, build 90)

---
 pubspec.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index b1312427d..f79879f61 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.17+89
+version: 1.5.18+90
 
 environment:
   sdk: ">=2.17.0 <3.0.0"
@@ -410,4 +410,4 @@ import_sorter:
   ignored_files: # Optional, defaults to []
     - \/test\/*
     - \/crypto_plugins\/*
-    - \/integration_test\/*
\ No newline at end of file
+    - \/integration_test\/*

From 140e68948f084a5435500e195712f3920f523409 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 23 Nov 2022 08:26:03 -0600
Subject: [PATCH 389/426] uppercase tickers on exchange form coin select field
 buttons

---
 lib/widgets/textfields/exchange_textfield.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/widgets/textfields/exchange_textfield.dart b/lib/widgets/textfields/exchange_textfield.dart
index 8d3c5d699..399d077c4 100644
--- a/lib/widgets/textfields/exchange_textfield.dart
+++ b/lib/widgets/textfields/exchange_textfield.dart
@@ -203,7 +203,7 @@ class _ExchangeTextFieldState extends State<ExchangeTextField> {
                           width: 6,
                         ),
                         Text(
-                          widget.ticker ?? "-",
+                          widget.ticker?.toUpperCase() ?? "-",
                           style: STextStyles.smallMed14(context).copyWith(
                             color: Theme.of(context)
                                 .extension<StackColors>()!

From d50e1e4a1418a4fd1f6b6d697e73ebaf370bb8a6 Mon Sep 17 00:00:00 2001
From: Diego Salazar <diego@cypherstack.com>
Date: Tue, 22 Nov 2022 17:56:14 -0700
Subject: [PATCH 390/426] Bump version (1.5.18, build 90)

---
 pubspec.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index b1312427d..f79879f61 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.17+89
+version: 1.5.18+90
 
 environment:
   sdk: ">=2.17.0 <3.0.0"
@@ -410,4 +410,4 @@ import_sorter:
   ignored_files: # Optional, defaults to []
     - \/test\/*
     - \/crypto_plugins\/*
-    - \/integration_test\/*
\ No newline at end of file
+    - \/integration_test\/*

From b3a7b19b8e9430dd7ad6dfb851ac09b2e64129e4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 23 Nov 2022 08:36:27 -0600
Subject: [PATCH 391/426] mobile exchange form layout fixes

---
 lib/pages/exchange_view/exchange_form.dart    | 46 ++++++++++---------
 .../sub_widgets/rate_type_toggle.dart         |  4 +-
 2 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index 921b35bf0..d818a73ff 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -1281,28 +1281,30 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
               condition: isDesktop,
               builder: (child) => MouseRegion(
                 cursor: SystemMouseCursors.click,
-                child: RoundedContainer(
-                  padding: const EdgeInsets.all(6),
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .buttonBackSecondary,
-                  radiusMultiplier: 0.75,
-                  child: child,
-                ),
+                child: child,
               ),
-              child: GestureDetector(
-                onTap: () async {
-                  await _swap();
-                },
-                child: Padding(
-                  padding: const EdgeInsets.all(4),
-                  child: SvgPicture.asset(
-                    Assets.svg.swap,
-                    width: 20,
-                    height: 20,
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .accentColorDark,
+              child: RoundedContainer(
+                padding: isDesktop
+                    ? const EdgeInsets.all(6)
+                    : const EdgeInsets.all(2),
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .buttonBackSecondary,
+                radiusMultiplier: 0.75,
+                child: GestureDetector(
+                  onTap: () async {
+                    await _swap();
+                  },
+                  child: Padding(
+                    padding: const EdgeInsets.all(4),
+                    child: SvgPicture.asset(
+                      Assets.svg.swap,
+                      width: 20,
+                      height: 20,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                    ),
                   ),
                 ),
               ),
@@ -1310,7 +1312,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
           ],
         ),
         SizedBox(
-          height: isDesktop ? 10 : 4,
+          height: isDesktop ? 10 : 7,
         ),
         ExchangeTextField(
           focusNode: _receiveFocusNode,
diff --git a/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart b/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart
index 31ee01ce2..361d49e65 100644
--- a/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart
+++ b/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart
@@ -55,7 +55,7 @@ class RateTypeToggle extends ConsumerWidget {
                 child: RoundedContainer(
                   padding: isDesktop
                       ? const EdgeInsets.all(17)
-                      : const EdgeInsets.all(0),
+                      : const EdgeInsets.all(12),
                   color: estimated
                       ? Theme.of(context)
                           .extension<StackColors>()!
@@ -136,7 +136,7 @@ class RateTypeToggle extends ConsumerWidget {
                 child: RoundedContainer(
                   padding: isDesktop
                       ? const EdgeInsets.all(17)
-                      : const EdgeInsets.all(0),
+                      : const EdgeInsets.all(12),
                   color: !estimated
                       ? Theme.of(context)
                           .extension<StackColors>()!

From 4377c351d304d135303626f74ca7f175705ed2db Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 23 Nov 2022 08:45:29 -0600
Subject: [PATCH 392/426] mobile exchange step 2 only enable next button when
 all fields are filled out

---
 .../exchange_step_views/step_2_view.dart      | 95 +++++++++++++++----
 1 file changed, 77 insertions(+), 18 deletions(-)

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 800d1e146..030f91cb7 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
@@ -7,8 +7,6 @@ import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart
 import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart';
 import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_3_view.dart';
 import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
-import 'package:stackwallet/providers/exchange/exchange_flow_is_active_state_provider.dart';
-import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/address_utils.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
@@ -20,6 +18,7 @@ import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 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/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
@@ -57,6 +56,8 @@ class _Step2ViewState extends ConsumerState<Step2View> {
   late final FocusNode _toFocusNode;
   late final FocusNode _refundFocusNode;
 
+  bool enableNext = false;
+
   bool isStackCoin(String ticker) {
     try {
       coinFromTickerCaseInsensitive(ticker);
@@ -207,6 +208,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                         _toController.text = manager.walletName;
                                         model.recipientAddress = await manager
                                             .currentReceivingAddress;
+
+                                        setState(() {
+                                          enableNext = _toController
+                                                  .text.isNotEmpty &&
+                                              _refundController.text.isNotEmpty;
+                                        });
                                       }
                                     });
                                   } catch (e, s) {
@@ -275,7 +282,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                 model.recipientAddress =
                                                     _toController.text;
 
-                                                setState(() {});
+                                                setState(() {
+                                                  enableNext = _toController
+                                                          .text.isNotEmpty &&
+                                                      _refundController
+                                                          .text.isNotEmpty;
+                                                });
                                               },
                                               child: const XIcon(),
                                             )
@@ -295,7 +307,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                   model.recipientAddress =
                                                       _toController.text;
 
-                                                  setState(() {});
+                                                  setState(() {
+                                                    enableNext = _toController
+                                                            .text.isNotEmpty &&
+                                                        _refundController
+                                                            .text.isNotEmpty;
+                                                  });
                                                 }
                                               },
                                               child: _toController.text.isEmpty
@@ -338,6 +355,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                             .state)
                                                     .state = "";
                                               }
+                                              setState(() {
+                                                enableNext = _toController
+                                                        .text.isNotEmpty &&
+                                                    _refundController
+                                                        .text.isNotEmpty;
+                                              });
                                             });
                                           },
                                           child: const AddressBookIcon(),
@@ -361,14 +384,24 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                 model.recipientAddress =
                                                     _toController.text;
 
-                                                setState(() {});
+                                                setState(() {
+                                                  enableNext = _toController
+                                                          .text.isNotEmpty &&
+                                                      _refundController
+                                                          .text.isNotEmpty;
+                                                });
                                               } else {
                                                 _toController.text =
                                                     qrResult.rawContent;
                                                 model.recipientAddress =
                                                     _toController.text;
 
-                                                setState(() {});
+                                                setState(() {
+                                                  enableNext = _toController
+                                                          .text.isNotEmpty &&
+                                                      _refundController
+                                                          .text.isNotEmpty;
+                                                });
                                               }
                                             } on PlatformException catch (e, s) {
                                               Logging.instance.log(
@@ -429,6 +462,11 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                         model.refundAddress = await manager
                                             .currentReceivingAddress;
                                       }
+                                      setState(() {
+                                        enableNext = _toController
+                                                .text.isNotEmpty &&
+                                            _refundController.text.isNotEmpty;
+                                      });
                                     });
                                   } catch (e, s) {
                                     Logging.instance
@@ -495,7 +533,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                 model.refundAddress =
                                                     _refundController.text;
 
-                                                setState(() {});
+                                                setState(() {
+                                                  enableNext = _toController
+                                                          .text.isNotEmpty &&
+                                                      _refundController
+                                                          .text.isNotEmpty;
+                                                });
                                               },
                                               child: const XIcon(),
                                             )
@@ -516,7 +559,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                   model.refundAddress =
                                                       _refundController.text;
 
-                                                  setState(() {});
+                                                  setState(() {
+                                                    enableNext = _toController
+                                                            .text.isNotEmpty &&
+                                                        _refundController
+                                                            .text.isNotEmpty;
+                                                  });
                                                 }
                                               },
                                               child:
@@ -555,6 +603,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                 model.refundAddress =
                                                     _refundController.text;
                                               }
+                                              setState(() {
+                                                enableNext = _toController
+                                                        .text.isNotEmpty &&
+                                                    _refundController
+                                                        .text.isNotEmpty;
+                                              });
                                             });
                                           },
                                           child: const AddressBookIcon(),
@@ -578,14 +632,24 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                 model.refundAddress =
                                                     _refundController.text;
 
-                                                setState(() {});
+                                                setState(() {
+                                                  enableNext = _toController
+                                                          .text.isNotEmpty &&
+                                                      _refundController
+                                                          .text.isNotEmpty;
+                                                });
                                               } else {
                                                 _refundController.text =
                                                     qrResult.rawContent;
                                                 model.refundAddress =
                                                     _refundController.text;
 
-                                                setState(() {});
+                                                setState(() {
+                                                  enableNext = _toController
+                                                          .text.isNotEmpty &&
+                                                      _refundController
+                                                          .text.isNotEmpty;
+                                                });
                                               }
                                             } on PlatformException catch (e, s) {
                                               Logging.instance.log(
@@ -637,20 +701,15 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                               width: 16,
                             ),
                             Expanded(
-                              child: TextButton(
+                              child: PrimaryButton(
+                                label: "Next",
+                                enabled: enableNext,
                                 onPressed: () {
                                   Navigator.of(context).pushNamed(
                                     Step3View.routeName,
                                     arguments: model,
                                   );
                                 },
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getPrimaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Next",
-                                  style: STextStyles.button(context),
-                                ),
                               ),
                             ),
                           ],

From 7011c6e1f68417d5e5fbee1ac53596bc50b618b0 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Tue, 22 Nov 2022 12:31:45 -0700
Subject: [PATCH 393/426] submit on enter for wallet keys

---
 .../unlock_wallet_keys_desktop.dart           | 58 +++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
index 739a3ebc4..e6d0ff390 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
@@ -43,6 +43,58 @@ class _UnlockWalletKeysDesktopState
   bool continueEnabled = false;
   bool hidePassword = true;
 
+  Future<void> enterPassphrase() async {
+    unawaited(
+      showDialog(
+        context: context,
+        builder: (context) => Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: const [
+            LoadingIndicator(
+              width: 200,
+              height: 200,
+            ),
+          ],
+        ),
+      ),
+    );
+
+    await Future<void>.delayed(const Duration(seconds: 1));
+
+    final verified = await ref
+        .read(storageCryptoHandlerProvider)
+        .verifyPassphrase(passwordController.text);
+
+    if (verified) {
+      Navigator.of(context, rootNavigator: true).pop();
+
+      final words = await ref
+          .read(walletsChangeNotifierProvider)
+          .getManager(widget.walletId)
+          .mnemonic;
+
+      if (mounted) {
+        await Navigator.of(context).pushReplacementNamed(
+          WalletKeysDesktopPopup.routeName,
+          arguments: words,
+        );
+      }
+    } else {
+      Navigator.of(context, rootNavigator: true).pop();
+
+      await Future<void>.delayed(const Duration(milliseconds: 300));
+
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "Invalid passphrase!",
+          context: context,
+        ),
+      );
+    }
+  }
+
   @override
   void initState() {
     passwordController = TextEditingController();
@@ -120,6 +172,12 @@ class _UnlockWalletKeysDesktopState
                 obscureText: hidePassword,
                 enableSuggestions: false,
                 autocorrect: false,
+                autofocus: true,
+                onSubmitted: (_) {
+                  if (continueEnabled) {
+                    enterPassphrase();
+                  }
+                },
                 decoration: standardInputDecoration(
                   "Enter password",
                   passwordFocusNode,

From d7a7c706d2a066d6815088ba6228cdcd8fed2603 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 23 Nov 2022 11:24:07 -0700
Subject: [PATCH 394/426] adjusted restore calendar height

---
 .../restore_options_view/restore_options_view.dart              | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
index 1ce5d713a..ac84964ca 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
@@ -155,7 +155,7 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
     final date = await showRoundedDatePicker(
       context: context,
       initialDate: DateTime.now(),
-      height: height * 0.5,
+      height: height / 3.2,
       theme: ThemeData(
         primarySwatch: Util.createMaterialColor(fetchedColor),
       ),

From adee71224b25bf9f8e72521dad0d289d55a16df1 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 23 Nov 2022 12:31:31 -0600
Subject: [PATCH 395/426] Format coin amounts improvements, fixed fee rates
 display issue, use hard coded xmr estimates for now

---
 lib/models/paymint/transactions_model.dart    |  10 +-
 .../confirm_change_now_send.dart              |  46 ++++----
 .../exchange_step_views/step_4_view.dart      |   2 +-
 lib/pages/exchange_view/send_from_view.dart   |  35 ++----
 .../exchange_provider_options.dart            |  31 ++++--
 .../send_view/confirm_transaction_view.dart   |  36 +++----
 lib/pages/send_view/send_view.dart            |  83 +++++++++-----
 .../transaction_fee_selection_sheet.dart      |  77 +++++++++----
 .../all_transactions_view.dart                |  17 +--
 .../transaction_details_view.dart             |  58 +++++-----
 .../transaction_search_filter_view.dart       |  19 +---
 .../sub_widgets/desktop_fee_dropdown.dart     |  86 ++++++++-------
 .../wallet_view/sub_widgets/desktop_send.dart |  24 +++--
 .../coins/bitcoin/bitcoin_wallet.dart         |  52 +++++----
 .../coins/bitcoincash/bitcoincash_wallet.dart |  53 ++++-----
 .../coins/dogecoin/dogecoin_wallet.dart       |  53 ++++-----
 lib/services/coins/firo/firo_wallet.dart      |  81 +++++++-------
 .../coins/litecoin/litecoin_wallet.dart       |  52 +++++----
 lib/services/coins/monero/monero_wallet.dart  | 101 +++++++++---------
 .../coins/namecoin/namecoin_wallet.dart       |  52 +++++----
 .../coins/wownero/wownero_wallet.dart         |  50 ++++-----
 lib/utilities/constants.dart                  |  42 ++++++--
 lib/utilities/format.dart                     |  50 +++------
 lib/widgets/transaction_card.dart             |  18 +---
 24 files changed, 602 insertions(+), 526 deletions(-)

diff --git a/lib/models/paymint/transactions_model.dart b/lib/models/paymint/transactions_model.dart
index 08b6eb7e2..382459922 100644
--- a/lib/models/paymint/transactions_model.dart
+++ b/lib/models/paymint/transactions_model.dart
@@ -2,6 +2,7 @@ import 'package:dart_numerics/dart_numerics.dart';
 import 'package:decimal/decimal.dart';
 import 'package:hive/hive.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 part '../type_adaptors/transactions_model.g.dart';
 
@@ -220,14 +221,16 @@ class Transaction {
           (DateTime.now().millisecondsSinceEpoch ~/ 1000),
       txType: json['txType'] as String,
       amount: (Decimal.parse(json["amount"].toString()) *
-              Decimal.fromInt(Constants.satsPerCoin))
+              Decimal.fromInt(Constants.satsPerCoin(Coin
+                  .firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
           .toBigInt()
           .toInt(),
       aliens: [],
       worthNow: json['worthNow'] as String,
       worthAtBlockTimestamp: json['worthAtBlockTimestamp'] as String? ?? "0",
       fees: (Decimal.parse(json["fees"].toString()) *
-              Decimal.fromInt(Constants.satsPerCoin))
+              Decimal.fromInt(Constants.satsPerCoin(Coin
+                  .firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
           .toBigInt()
           .toInt(),
       inputSize: json['inputSize'] as int? ?? 0,
@@ -386,7 +389,8 @@ class Output {
       scriptpubkeyType: json['scriptPubKey']['type'] as String?,
       scriptpubkeyAddress: address,
       value: (Decimal.parse(json["value"].toString()) *
-              Decimal.fromInt(Constants.satsPerCoin))
+              Decimal.fromInt(Constants.satsPerCoin(Coin
+                  .firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure
           .toBigInt()
           .toInt(),
     );
diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index 540067915..0e1eef755 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -342,6 +342,9 @@ class _ConfirmChangeNowSendViewState
                                 localeServiceChangeNotifierProvider
                                     .select((value) => value.locale),
                               ),
+                              ref.watch(
+                                managerProvider.select((value) => value.coin),
+                              ),
                             )} ${ref.watch(
                                   managerProvider.select((value) => value.coin),
                                 ).ticker}",
@@ -382,6 +385,9 @@ class _ConfirmChangeNowSendViewState
                                 localeServiceChangeNotifierProvider
                                     .select((value) => value.locale),
                               ),
+                              ref.watch(
+                                managerProvider.select((value) => value.coin),
+                              ),
                             )} ${ref.watch(
                                   managerProvider.select((value) => value.coin),
                                 ).ticker}",
@@ -563,13 +569,12 @@ class _ConfirmChangeNowSendViewState
                       ],
                     ),
                     child: Text(
-                      "${Format.satoshiAmountToPrettyString(
-                        transactionInfo["recipientAmt"] as int,
-                        ref.watch(
-                          localeServiceChangeNotifierProvider
-                              .select((value) => value.locale),
-                        ),
-                      )} ${ref.watch(
+                      "${Format.satoshiAmountToPrettyString(transactionInfo["recipientAmt"] as int, ref.watch(
+                            localeServiceChangeNotifierProvider
+                                .select((value) => value.locale),
+                          ), ref.watch(
+                            managerProvider.select((value) => value.coin),
+                          ))} ${ref.watch(
                             managerProvider.select((value) => value.coin),
                           ).ticker}",
                       style: STextStyles.itemSubtitle12(context),
@@ -597,13 +602,12 @@ class _ConfirmChangeNowSendViewState
                     style: STextStyles.smallMed12(context),
                   ),
                   Text(
-                    "${Format.satoshiAmountToPrettyString(
-                      transactionInfo["fee"] as int,
-                      ref.watch(
-                        localeServiceChangeNotifierProvider
-                            .select((value) => value.locale),
-                      ),
-                    )} ${ref.watch(
+                    "${Format.satoshiAmountToPrettyString(transactionInfo["fee"] as int, ref.watch(
+                          localeServiceChangeNotifierProvider
+                              .select((value) => value.locale),
+                        ), ref.watch(
+                          managerProvider.select((value) => value.coin),
+                        ))} ${ref.watch(
                           managerProvider.select((value) => value.coin),
                         ).ticker}",
                     style: STextStyles.itemSubtitle12(context),
@@ -685,14 +689,12 @@ class _ConfirmChangeNowSendViewState
                       ),
                     ),
                     Text(
-                      "${Format.satoshiAmountToPrettyString(
-                        (transactionInfo["fee"] as int) +
-                            (transactionInfo["recipientAmt"] as int),
-                        ref.watch(
-                          localeServiceChangeNotifierProvider
-                              .select((value) => value.locale),
-                        ),
-                      )} ${ref.watch(
+                      "${Format.satoshiAmountToPrettyString((transactionInfo["fee"] as int) + (transactionInfo["recipientAmt"] as int), ref.watch(
+                            localeServiceChangeNotifierProvider
+                                .select((value) => value.locale),
+                          ), ref.watch(
+                            managerProvider.select((value) => value.coin),
+                          ))} ${ref.watch(
                             managerProvider.select((value) => value.coin),
                           ).ticker}",
                       style: STextStyles.itemSubtitle12(context).copyWith(
diff --git a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
index a8b403dcf..f5975a277 100644
--- a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
+++ b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
@@ -487,7 +487,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
 
                                         final amount =
                                             Format.decimalAmountToSatoshis(
-                                                model.sendAmount);
+                                                model.sendAmount, manager.coin);
                                         final address =
                                             model.trade!.payInAddress;
 
diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart
index 7c5f5541c..f13971a67 100644
--- a/lib/pages/exchange_view/send_from_view.dart
+++ b/lib/pages/exchange_view/send_from_view.dart
@@ -61,25 +61,7 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
   late final Trade trade;
 
   String formatAmount(Decimal amount, Coin coin) {
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.bitcoincash:
-      case Coin.litecoin:
-      case Coin.dogecoin:
-      case Coin.epicCash:
-      case Coin.firo:
-      case Coin.namecoin:
-      case Coin.bitcoinTestNet:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincashTestnet:
-      case Coin.dogecoinTestNet:
-      case Coin.firoTestNet:
-        return amount.toStringAsFixed(Constants.decimalPlaces);
-      case Coin.monero:
-        return amount.toStringAsFixed(Constants.decimalPlacesMonero);
-      case Coin.wownero:
-        return amount.toStringAsFixed(Constants.decimalPlacesWownero);
-    }
+    return amount.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
   }
 
   @override
@@ -233,7 +215,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
   late final Trade trade;
 
   Future<void> _send(Manager manager, {bool? shouldSendPublicFiroFunds}) async {
-    final _amount = Format.decimalAmountToSatoshis(amount);
+    final _amount = Format.decimalAmountToSatoshis(amount, manager.coin);
 
     try {
       bool wasCancelled = false;
@@ -464,7 +446,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
                                     "${Format.localizedStringAsFixed(
                                       value: snapshot.data!,
                                       locale: locale,
-                                      decimalPlaces: Constants.decimalPlaces,
+                                      decimalPlaces:
+                                          Constants.decimalPlacesForCoin(coin),
                                     )} ${coin.ticker}",
                                     style: STextStyles.itemSubtitle(context),
                                   );
@@ -549,7 +532,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
                                     "${Format.localizedStringAsFixed(
                                       value: snapshot.data!,
                                       locale: locale,
-                                      decimalPlaces: Constants.decimalPlaces,
+                                      decimalPlaces:
+                                          Constants.decimalPlacesForCoin(coin),
                                     )} ${coin.ticker}",
                                     style: STextStyles.itemSubtitle(context),
                                   );
@@ -657,11 +641,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
                               "${Format.localizedStringAsFixed(
                                 value: snapshot.data!,
                                 locale: locale,
-                                decimalPlaces: coin == Coin.monero
-                                    ? Constants.decimalPlacesMonero
-                                    : coin == Coin.wownero
-                                        ? Constants.decimalPlacesWownero
-                                        : Constants.decimalPlaces,
+                                decimalPlaces:
+                                    Constants.decimalPlacesForCoin(coin),
                               )} ${coin.ticker}",
                               style: STextStyles.itemSubtitle(context),
                             );
diff --git a/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart b/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart
index 4dd768403..ebaf68066 100644
--- a/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart
+++ b/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart
@@ -159,6 +159,14 @@ class ExchangeProviderOptions extends ConsumerWidget {
                                             .toDecimal(
                                                 scaleOnInfinitePrecision: 12);
                                       }
+                                      Coin coin;
+                                      try {
+                                        coin =
+                                            coinFromTickerCaseInsensitive(to!);
+                                      } catch (_) {
+                                        coin = Coin.bitcoin;
+                                      }
+
                                       return Text(
                                         "1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
                                           value: rate,
@@ -167,11 +175,9 @@ class ExchangeProviderOptions extends ConsumerWidget {
                                                 .select(
                                                     (value) => value.locale),
                                           ),
-                                          decimalPlaces: to!.toUpperCase() ==
-                                                  Coin.monero.ticker
-                                                      .toUpperCase()
-                                              ? Constants.decimalPlacesMonero
-                                              : Constants.decimalPlaces,
+                                          decimalPlaces:
+                                              Constants.decimalPlacesForCoin(
+                                                  coin),
                                         )} ${to!.toUpperCase()}",
                                         style:
                                             STextStyles.itemSubtitle12(context)
@@ -354,6 +360,13 @@ class ExchangeProviderOptions extends ConsumerWidget {
                                           .toDecimal(
                                               scaleOnInfinitePrecision: 12);
 
+                                      Coin coin;
+                                      try {
+                                        coin =
+                                            coinFromTickerCaseInsensitive(to!);
+                                      } catch (_) {
+                                        coin = Coin.bitcoin;
+                                      }
                                       return Text(
                                         "1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
                                           value: rate,
@@ -362,11 +375,9 @@ class ExchangeProviderOptions extends ConsumerWidget {
                                                 .select(
                                                     (value) => value.locale),
                                           ),
-                                          decimalPlaces: to!.toUpperCase() ==
-                                                  Coin.monero.ticker
-                                                      .toUpperCase()
-                                              ? Constants.decimalPlacesMonero
-                                              : Constants.decimalPlaces,
+                                          decimalPlaces:
+                                              Constants.decimalPlacesForCoin(
+                                                  coin),
                                         )} ${to!.toUpperCase()}",
                                         style:
                                             STextStyles.itemSubtitle12(context)
diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index 276203804..1ddeb3c9f 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -317,13 +317,12 @@ class _ConfirmTransactionViewState
                           style: STextStyles.smallMed12(context),
                         ),
                         Text(
-                          "${Format.satoshiAmountToPrettyString(
-                            transactionInfo["recipientAmt"] as int,
-                            ref.watch(
-                              localeServiceChangeNotifierProvider
-                                  .select((value) => value.locale),
-                            ),
-                          )} ${ref.watch(
+                          "${Format.satoshiAmountToPrettyString(transactionInfo["recipientAmt"] as int, ref.watch(
+                                localeServiceChangeNotifierProvider
+                                    .select((value) => value.locale),
+                              ), ref.watch(
+                                managerProvider.select((value) => value.coin),
+                              ))} ${ref.watch(
                                 managerProvider.select((value) => value.coin),
                               ).ticker}",
                           style: STextStyles.itemSubtitle12(context),
@@ -344,13 +343,12 @@ class _ConfirmTransactionViewState
                           style: STextStyles.smallMed12(context),
                         ),
                         Text(
-                          "${Format.satoshiAmountToPrettyString(
-                            transactionInfo["fee"] as int,
-                            ref.watch(
-                              localeServiceChangeNotifierProvider
-                                  .select((value) => value.locale),
-                            ),
-                          )} ${ref.watch(
+                          "${Format.satoshiAmountToPrettyString(transactionInfo["fee"] as int, ref.watch(
+                                localeServiceChangeNotifierProvider
+                                    .select((value) => value.locale),
+                              ), ref.watch(
+                                managerProvider.select((value) => value.coin),
+                              ))} ${ref.watch(
                                 managerProvider.select((value) => value.coin),
                               ).ticker}",
                           style: STextStyles.itemSubtitle12(context),
@@ -494,6 +492,7 @@ class _ConfirmTransactionViewState
                                           localeServiceChangeNotifierProvider
                                               .select((value) => value.locale),
                                         ),
+                                        coin,
                                       )} ${coin.ticker}",
                                       style: STextStyles
                                               .desktopTextExtraExtraSmall(
@@ -638,11 +637,7 @@ class _ConfirmTransactionViewState
                           value: fee,
                           locale: ref.watch(localeServiceChangeNotifierProvider
                               .select((value) => value.locale)),
-                          decimalPlaces: coin == Coin.monero
-                              ? Constants.decimalPlacesMonero
-                              : coin == Coin.wownero
-                                  ? Constants.decimalPlacesWownero
-                                  : Constants.decimalPlaces,
+                          decimalPlaces: Constants.decimalPlacesForCoin(coin),
                         )} ${coin.ticker}",
                         style: STextStyles.itemSubtitle(context),
                       );
@@ -750,6 +745,9 @@ class _ConfirmTransactionViewState
                           localeServiceChangeNotifierProvider
                               .select((value) => value.locale),
                         ),
+                        ref.watch(
+                          managerProvider.select((value) => value.coin),
+                        ),
                       )} ${ref.watch(
                             managerProvider.select((value) => value.coin),
                           ).ticker}",
diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart
index d91b7a3ea..2539b89ab 100644
--- a/lib/pages/send_view/send_view.dart
+++ b/lib/pages/send_view/send_view.dart
@@ -1,5 +1,6 @@
 import 'dart:async';
 
+import 'package:cw_core/monero_transaction_priority.dart';
 import 'package:decimal/decimal.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
@@ -30,6 +31,7 @@ import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.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/animated_text.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
@@ -41,8 +43,6 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class SendView extends ConsumerStatefulWidget {
   const SendView({
     Key? key,
@@ -211,29 +211,47 @@ class _SendViewState extends ConsumerState<SendView> {
     }
 
     int fee;
+    if (coin == Coin.monero) {
+      MoneroTransactionPriority specialMoneroId;
+      switch (ref.read(feeRateTypeStateProvider.state).state) {
+        case FeeRateType.fast:
+          specialMoneroId = MoneroTransactionPriority.fast;
+          break;
+        case FeeRateType.average:
+          specialMoneroId = MoneroTransactionPriority.regular;
+          break;
+        case FeeRateType.slow:
+          specialMoneroId = MoneroTransactionPriority.slow;
+          break;
+      }
 
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+      fee = await manager.estimateFeeFor(amount, specialMoneroId.raw!);
+      cachedFees[amount] = Format.satoshisToAmount(fee, coin: coin)
+          .toStringAsFixed(Constants.decimalPlacesForCoin(coin));
+
+      return cachedFees[amount]!;
+    } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
       if (ref.read(publicPrivateBalanceStateProvider.state).state ==
           "Private") {
         fee = await manager.estimateFeeFor(amount, feeRate);
 
-        cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee)
-            .toStringAsFixed(Constants.decimalPlaces);
+        cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee, coin: coin)
+            .toStringAsFixed(Constants.decimalPlacesForCoin(coin));
 
         return cachedFiroPrivateFees[amount]!;
       } else {
         fee = await (manager.wallet as FiroWallet)
             .estimateFeeForPublic(amount, feeRate);
 
-        cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee)
-            .toStringAsFixed(Constants.decimalPlaces);
+        cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee, coin: coin)
+            .toStringAsFixed(Constants.decimalPlacesForCoin(coin));
 
         return cachedFiroPublicFees[amount]!;
       }
     } else {
       fee = await manager.estimateFeeFor(amount, feeRate);
-      cachedFees[amount] =
-          Format.satoshisToAmount(fee).toStringAsFixed(Constants.decimalPlaces);
+      cachedFees[amount] = Format.satoshisToAmount(fee, coin: coin)
+          .toStringAsFixed(Constants.decimalPlacesForCoin(coin));
 
       return cachedFees[amount]!;
     }
@@ -296,8 +314,8 @@ class _SendViewState extends ConsumerState<SendView> {
           });
         } else {
           setState(() {
-            _calculateFeesFuture =
-                calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
+            _calculateFeesFuture = calculateFees(
+                Format.decimalAmountToSatoshis(_amountToSend!, coin));
           });
         }
       }
@@ -311,8 +329,8 @@ class _SendViewState extends ConsumerState<SendView> {
           });
         } else {
           setState(() {
-            _calculateFeesFuture =
-                calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
+            _calculateFeesFuture = calculateFees(
+                Format.decimalAmountToSatoshis(_amountToSend!, coin));
           });
         }
       }
@@ -354,8 +372,8 @@ class _SendViewState extends ConsumerState<SendView> {
           });
         } else {
           setState(() {
-            _calculateFeesFuture =
-                calculateFees(Format.decimalAmountToSatoshis(_amountToSend!));
+            _calculateFeesFuture = calculateFees(
+                Format.decimalAmountToSatoshis(_amountToSend!, coin));
           });
         }
       });
@@ -492,7 +510,9 @@ class _SendViewState extends ConsumerState<SendView> {
                                         onTap: () {
                                           cryptoAmountController.text =
                                               _cachedBalance!.toStringAsFixed(
-                                                  Constants.decimalPlaces);
+                                                  Constants
+                                                      .decimalPlacesForCoin(
+                                                          coin));
                                         },
                                         child: Container(
                                           color: Colors.transparent,
@@ -781,8 +801,9 @@ class _SendViewState extends ConsumerState<SendView> {
                                                         .read(
                                                             localeServiceChangeNotifierProvider)
                                                         .locale,
-                                                    decimalPlaces:
-                                                        Constants.decimalPlaces,
+                                                    decimalPlaces: Constants
+                                                        .decimalPlacesForCoin(
+                                                            coin),
                                                   );
                                                   amount.toString();
                                                   _amountToSend = amount;
@@ -1044,19 +1065,22 @@ class _SendViewState extends ConsumerState<SendView> {
                                         (await firoWallet
                                                 .availablePrivateBalance())
                                             .toStringAsFixed(
-                                                Constants.decimalPlaces);
+                                                Constants.decimalPlacesForCoin(
+                                                    coin));
                                   } else {
                                     cryptoAmountController.text =
                                         (await firoWallet
                                                 .availablePublicBalance())
                                             .toStringAsFixed(
-                                                Constants.decimalPlaces);
+                                                Constants.decimalPlacesForCoin(
+                                                    coin));
                                   }
                                 } else {
                                   cryptoAmountController.text = (await ref
                                           .read(provider)
                                           .availableBalance)
-                                      .toStringAsFixed(Constants.decimalPlaces);
+                                      .toStringAsFixed(
+                                          Constants.decimalPlacesForCoin(coin));
                                 }
                               },
                             ),
@@ -1167,7 +1191,8 @@ class _SendViewState extends ConsumerState<SendView> {
                                       ? Decimal.zero
                                       : (baseAmount / _price).toDecimal(
                                           scaleOnInfinitePrecision:
-                                              Constants.decimalPlaces);
+                                              Constants.decimalPlacesForCoin(
+                                                  coin));
                                 }
                                 if (_cachedAmountToSend != null &&
                                     _cachedAmountToSend == _amountToSend) {
@@ -1184,7 +1209,8 @@ class _SendViewState extends ConsumerState<SendView> {
                                   locale: ref
                                       .read(localeServiceChangeNotifierProvider)
                                       .locale,
-                                  decimalPlaces: Constants.decimalPlaces,
+                                  decimalPlaces:
+                                      Constants.decimalPlacesForCoin(coin),
                                 );
 
                                 _cryptoAmountChangeLock = true;
@@ -1506,7 +1532,7 @@ class _SendViewState extends ConsumerState<SendView> {
                                   }
 
                                   final amount = Format.decimalAmountToSatoshis(
-                                      _amountToSend!);
+                                      _amountToSend!, coin);
                                   int availableBalance;
                                   if ((coin == Coin.firo ||
                                       coin == Coin.firoTestNet)) {
@@ -1520,18 +1546,21 @@ class _SendViewState extends ConsumerState<SendView> {
                                           Format.decimalAmountToSatoshis(
                                               await (manager.wallet
                                                       as FiroWallet)
-                                                  .availablePrivateBalance());
+                                                  .availablePrivateBalance(),
+                                              coin);
                                     } else {
                                       availableBalance =
                                           Format.decimalAmountToSatoshis(
                                               await (manager.wallet
                                                       as FiroWallet)
-                                                  .availablePublicBalance());
+                                                  .availablePublicBalance(),
+                                              coin);
                                     }
                                   } else {
                                     availableBalance =
                                         Format.decimalAmountToSatoshis(
-                                            await manager.availableBalance);
+                                            await manager.availableBalance,
+                                            coin);
                                   }
 
                                   // confirm send all
diff --git a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart
index 982086d3c..2f5ce2f3e 100644
--- a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart
+++ b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart
@@ -1,3 +1,4 @@
+import 'package:cw_core/monero_transaction_priority.dart';
 import 'package:decimal/decimal.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -70,16 +71,27 @@ class _TransactionFeeSelectionSheetState
           final manager =
               ref.read(walletsChangeNotifierProvider).getManager(walletId);
 
-          if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+          if (coin == Coin.monero || coin == Coin.wownero) {
+            final fee = await manager.estimateFeeFor(
+                amount, MoneroTransactionPriority.fast.raw!);
+            ref.read(feeSheetSessionCacheProvider).fast[amount] =
+                Format.satoshisToAmount(
+              fee,
+              coin: coin,
+            );
+          } else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
               ref.read(publicPrivateBalanceStateProvider.state).state !=
                   "Private") {
             ref.read(feeSheetSessionCacheProvider).fast[amount] =
-                Format.satoshisToAmount(await (manager.wallet as FiroWallet)
-                    .estimateFeeForPublic(amount, feeRate));
+                Format.satoshisToAmount(
+                    await (manager.wallet as FiroWallet)
+                        .estimateFeeForPublic(amount, feeRate),
+                    coin: coin);
           } else {
             ref.read(feeSheetSessionCacheProvider).fast[amount] =
                 Format.satoshisToAmount(
-                    await manager.estimateFeeFor(amount, feeRate));
+                    await manager.estimateFeeFor(amount, feeRate),
+                    coin: coin);
           }
         }
         return ref.read(feeSheetSessionCacheProvider).fast[amount]!;
@@ -88,17 +100,27 @@ class _TransactionFeeSelectionSheetState
         if (ref.read(feeSheetSessionCacheProvider).average[amount] == null) {
           final manager =
               ref.read(walletsChangeNotifierProvider).getManager(walletId);
-
-          if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+          if (coin == Coin.monero || coin == Coin.wownero) {
+            final fee = await manager.estimateFeeFor(
+                amount, MoneroTransactionPriority.regular.raw!);
+            ref.read(feeSheetSessionCacheProvider).average[amount] =
+                Format.satoshisToAmount(
+              fee,
+              coin: coin,
+            );
+          } else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
               ref.read(publicPrivateBalanceStateProvider.state).state !=
                   "Private") {
             ref.read(feeSheetSessionCacheProvider).average[amount] =
-                Format.satoshisToAmount(await (manager.wallet as FiroWallet)
-                    .estimateFeeForPublic(amount, feeRate));
+                Format.satoshisToAmount(
+                    await (manager.wallet as FiroWallet)
+                        .estimateFeeForPublic(amount, feeRate),
+                    coin: coin);
           } else {
             ref.read(feeSheetSessionCacheProvider).average[amount] =
                 Format.satoshisToAmount(
-                    await manager.estimateFeeFor(amount, feeRate));
+                    await manager.estimateFeeFor(amount, feeRate),
+                    coin: coin);
           }
         }
         return ref.read(feeSheetSessionCacheProvider).average[amount]!;
@@ -107,17 +129,27 @@ class _TransactionFeeSelectionSheetState
         if (ref.read(feeSheetSessionCacheProvider).slow[amount] == null) {
           final manager =
               ref.read(walletsChangeNotifierProvider).getManager(walletId);
-
-          if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+          if (coin == Coin.monero || coin == Coin.wownero) {
+            final fee = await manager.estimateFeeFor(
+                amount, MoneroTransactionPriority.slow.raw!);
+            ref.read(feeSheetSessionCacheProvider).slow[amount] =
+                Format.satoshisToAmount(
+              fee,
+              coin: coin,
+            );
+          } else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
               ref.read(publicPrivateBalanceStateProvider.state).state !=
                   "Private") {
             ref.read(feeSheetSessionCacheProvider).slow[amount] =
-                Format.satoshisToAmount(await (manager.wallet as FiroWallet)
-                    .estimateFeeForPublic(amount, feeRate));
+                Format.satoshisToAmount(
+                    await (manager.wallet as FiroWallet)
+                        .estimateFeeForPublic(amount, feeRate),
+                    coin: coin);
           } else {
             ref.read(feeSheetSessionCacheProvider).slow[amount] =
                 Format.satoshisToAmount(
-                    await manager.estimateFeeFor(amount, feeRate));
+                    await manager.estimateFeeFor(amount, feeRate),
+                    coin: coin);
           }
         }
         return ref.read(feeSheetSessionCacheProvider).slow[amount]!;
@@ -225,7 +257,7 @@ class _TransactionFeeSelectionSheetState
                           ref.read(feeRateTypeStateProvider.state).state =
                               FeeRateType.fast;
                         }
-                        String? fee = getAmount(FeeRateType.fast);
+                        String? fee = getAmount(FeeRateType.fast, manager.coin);
                         if (fee != null) {
                           widget.updateChosen(fee);
                         }
@@ -293,7 +325,7 @@ class _TransactionFeeSelectionSheetState
                                               feeRate: feeObject!.fast,
                                               amount: Format
                                                   .decimalAmountToSatoshis(
-                                                      amount)),
+                                                      amount, manager.coin)),
                                           // future: manager.estimateFeeFor(
                                           //     Format.decimalAmountToSatoshis(
                                           //         amount),
@@ -358,7 +390,8 @@ class _TransactionFeeSelectionSheetState
                           ref.read(feeRateTypeStateProvider.state).state =
                               FeeRateType.average;
                         }
-                        String? fee = getAmount(FeeRateType.average);
+                        String? fee =
+                            getAmount(FeeRateType.average, manager.coin);
                         if (fee != null) {
                           widget.updateChosen(fee);
                         }
@@ -424,7 +457,7 @@ class _TransactionFeeSelectionSheetState
                                               feeRate: feeObject!.medium,
                                               amount: Format
                                                   .decimalAmountToSatoshis(
-                                                      amount)),
+                                                      amount, manager.coin)),
                                           // future: manager.estimateFeeFor(
                                           //     Format.decimalAmountToSatoshis(
                                           //         amount),
@@ -489,7 +522,7 @@ class _TransactionFeeSelectionSheetState
                           ref.read(feeRateTypeStateProvider.state).state =
                               FeeRateType.slow;
                         }
-                        String? fee = getAmount(FeeRateType.slow);
+                        String? fee = getAmount(FeeRateType.slow, manager.coin);
                         print("fee $fee");
                         if (fee != null) {
                           widget.updateChosen(fee);
@@ -557,7 +590,7 @@ class _TransactionFeeSelectionSheetState
                                               feeRate: feeObject!.slow,
                                               amount: Format
                                                   .decimalAmountToSatoshis(
-                                                      amount)),
+                                                      amount, manager.coin)),
                                           // future: manager.estimateFeeFor(
                                           //     Format.decimalAmountToSatoshis(
                                           //         amount),
@@ -624,10 +657,10 @@ class _TransactionFeeSelectionSheetState
     );
   }
 
-  String? getAmount(FeeRateType feeRateType) {
+  String? getAmount(FeeRateType feeRateType, Coin coin) {
     try {
       print(feeRateType);
-      var amount = Format.decimalAmountToSatoshis(this.amount);
+      var amount = Format.decimalAmountToSatoshis(this.amount, coin);
       print(amount);
       print(ref.read(feeSheetSessionCacheProvider).fast);
       print(ref.read(feeSheetSessionCacheProvider).average);
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 95dcc8126..b9ea02e79 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -937,13 +937,9 @@ class _DesktopTransactionCardRowState
                 flex: 6,
                 child: Builder(
                   builder: (_) {
-                    final amount = coin == Coin.monero
-                        ? (_transaction.amount ~/ 10000)
-                        : coin == Coin.wownero
-                            ? (_transaction.amount ~/ 1000)
-                            : _transaction.amount;
+                    final amount = _transaction.amount;
                     return Text(
-                      "$prefix${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}",
+                      "$prefix${Format.satoshiAmountToPrettyString(amount, locale, coin)} ${coin.ticker}",
                       style: STextStyles.desktopTextExtraExtraSmall(context)
                           .copyWith(
                         color: Theme.of(context)
@@ -960,17 +956,12 @@ class _DesktopTransactionCardRowState
                   flex: 4,
                   child: Builder(
                     builder: (_) {
-                      // TODO: modify Format.<functions> to take optional Coin parameter so this type oif check isn't done in ui
                       int value = _transaction.amount;
-                      if (coin == Coin.monero) {
-                        value = (value ~/ 10000);
-                      } else if (coin == Coin.wownero) {
-                        value = (value ~/ 1000);
-                      }
 
                       return Text(
                         "$prefix${Format.localizedStringAsFixed(
-                          value: Format.satoshisToAmount(value) * price,
+                          value: Format.satoshisToAmount(value, coin: coin) *
+                              price,
                           locale: locale,
                           decimalPlaces: 2,
                         )} $baseCurrency",
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 4d45428ff..c2a0590e4 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -78,8 +78,8 @@ class _TransactionDetailsViewState
     walletId = widget.walletId;
 
     coin = widget.coin;
-    amount = Format.satoshisToAmount(_transaction.amount);
-    fee = Format.satoshisToAmount(_transaction.fees);
+    amount = Format.satoshisToAmount(_transaction.amount, coin: coin);
+    fee = Format.satoshisToAmount(_transaction.fees, coin: coin);
 
     if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
         _transaction.subType == "mint") {
@@ -418,21 +418,15 @@ class _TransactionDetailsViewState
                                       children: [
                                         SelectableText(
                                           "$amountPrefix${Format.localizedStringAsFixed(
-                                            value: coin == Coin.monero
-                                                ? (amount / 10000.toDecimal())
-                                                    .toDecimal()
-                                                : coin == Coin.wownero
-                                                    ? (amount /
-                                                            1000.toDecimal())
-                                                        .toDecimal()
-                                                    : amount,
+                                            value: amount,
                                             locale: ref.watch(
                                               localeServiceChangeNotifierProvider
                                                   .select(
                                                       (value) => value.locale),
                                             ),
                                             decimalPlaces:
-                                                Constants.decimalPlaces,
+                                                Constants.decimalPlacesForCoin(
+                                                    coin),
                                           )} ${coin.ticker}",
                                           style: isDesktop
                                               ? STextStyles
@@ -454,11 +448,21 @@ class _TransactionDetailsViewState
                                                 (value) =>
                                                     value.externalCalls)))
                                           SelectableText(
-                                            "$amountPrefix${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch(
-                                                  localeServiceChangeNotifierProvider
-                                                      .select((value) =>
-                                                          value.locale),
-                                                ), decimalPlaces: 2)} ${ref.watch(
+                                            "$amountPrefix${Format.localizedStringAsFixed(
+                                              value: amount *
+                                                  ref.watch(
+                                                    priceAnd24hChangeNotifierProvider
+                                                        .select((value) => value
+                                                            .getPrice(coin)
+                                                            .item1),
+                                                  ),
+                                              locale: ref.watch(
+                                                localeServiceChangeNotifierProvider
+                                                    .select((value) =>
+                                                        value.locale),
+                                              ),
+                                              decimalPlaces: 2,
+                                            )} ${ref.watch(
                                               prefsChangeNotifierProvider
                                                   .select(
                                                 (value) => value.currency,
@@ -834,32 +838,22 @@ class _TransactionDetailsViewState
                               final feeString = showFeePending
                                   ? _transaction.confirmedStatus
                                       ? Format.localizedStringAsFixed(
-                                          value: coin == Coin.monero
-                                              ? (fee / 10000.toDecimal())
-                                                  .toDecimal()
-                                              : coin == Coin.wownero
-                                                  ? (fee / 1000.toDecimal())
-                                                      .toDecimal()
-                                                  : fee,
+                                          value: fee,
                                           locale: ref.watch(
                                               localeServiceChangeNotifierProvider
                                                   .select(
                                                       (value) => value.locale)),
                                           decimalPlaces:
-                                              Constants.decimalPlaces)
+                                              Constants.decimalPlacesForCoin(
+                                                  coin))
                                       : "Pending"
                                   : Format.localizedStringAsFixed(
-                                      value: coin == Coin.monero
-                                          ? (fee / 10000.toDecimal())
-                                              .toDecimal()
-                                          : coin == Coin.wownero
-                                              ? (fee / 1000.toDecimal())
-                                                  .toDecimal()
-                                              : fee,
+                                      value: fee,
                                       locale: ref.watch(
                                           localeServiceChangeNotifierProvider
                                               .select((value) => value.locale)),
-                                      decimalPlaces: Constants.decimalPlaces);
+                                      decimalPlaces:
+                                          Constants.decimalPlacesForCoin(coin));
 
                               return Row(
                                 mainAxisAlignment:
diff --git a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
index d135ea276..0b3fd3acb 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
@@ -79,7 +79,7 @@ class _TransactionSearchViewState
       String amount = "";
       if (filterState.amount != null) {
         amount = Format.satoshiAmountToPrettyString(filterState.amount!,
-            ref.read(localeServiceChangeNotifierProvider).locale);
+            ref.read(localeServiceChangeNotifierProvider).locale, widget.coin);
       }
       _amountTextEditingController.text = amount;
     }
@@ -967,22 +967,7 @@ class _TransactionSearchViewState
     }
     int? amount;
     if (amountDecimal != null) {
-      if (widget.coin == Coin.monero) {
-        amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoinMonero))
-            .floor()
-            .toBigInt()
-            .toInt();
-      } else if (widget.coin == Coin.wownero) {
-        amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoinWownero))
-            .floor()
-            .toBigInt()
-            .toInt();
-      } else {
-        amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoin))
-            .floor()
-            .toBigInt()
-            .toInt();
-      }
+      amount = Format.decimalAmountToSatoshis(amountDecimal, widget.coin);
     }
 
     final TransactionFilter filter = TransactionFilter(
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart
index 9acb3a6f9..25e1f47ab 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart
@@ -1,3 +1,4 @@
+import 'package:cw_core/monero_transaction_priority.dart';
 import 'package:decimal/decimal.dart';
 import 'package:dropdown_button2/dropdown_button2.dart';
 import 'package:flutter/material.dart';
@@ -55,16 +56,27 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
           final manager =
               ref.read(walletsChangeNotifierProvider).getManager(walletId);
 
-          if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+          if (coin == Coin.monero || coin == Coin.wownero) {
+            final fee = await manager.estimateFeeFor(
+                amount, MoneroTransactionPriority.fast.raw!);
+            ref.read(feeSheetSessionCacheProvider).fast[amount] =
+                Format.satoshisToAmount(
+              fee,
+              coin: coin,
+            );
+          } else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
               ref.read(publicPrivateBalanceStateProvider.state).state !=
                   "Private") {
             ref.read(feeSheetSessionCacheProvider).fast[amount] =
-                Format.satoshisToAmount(await (manager.wallet as FiroWallet)
-                    .estimateFeeForPublic(amount, feeRate));
+                Format.satoshisToAmount(
+                    await (manager.wallet as FiroWallet)
+                        .estimateFeeForPublic(amount, feeRate),
+                    coin: coin);
           } else {
             ref.read(feeSheetSessionCacheProvider).fast[amount] =
                 Format.satoshisToAmount(
-                    await manager.estimateFeeFor(amount, feeRate));
+                    await manager.estimateFeeFor(amount, feeRate),
+                    coin: coin);
           }
         }
         return ref.read(feeSheetSessionCacheProvider).fast[amount]!;
@@ -74,16 +86,27 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
           final manager =
               ref.read(walletsChangeNotifierProvider).getManager(walletId);
 
-          if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+          if (coin == Coin.monero || coin == Coin.wownero) {
+            final fee = await manager.estimateFeeFor(
+                amount, MoneroTransactionPriority.regular.raw!);
+            ref.read(feeSheetSessionCacheProvider).average[amount] =
+                Format.satoshisToAmount(
+              fee,
+              coin: coin,
+            );
+          } else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
               ref.read(publicPrivateBalanceStateProvider.state).state !=
                   "Private") {
             ref.read(feeSheetSessionCacheProvider).average[amount] =
-                Format.satoshisToAmount(await (manager.wallet as FiroWallet)
-                    .estimateFeeForPublic(amount, feeRate));
+                Format.satoshisToAmount(
+                    await (manager.wallet as FiroWallet)
+                        .estimateFeeForPublic(amount, feeRate),
+                    coin: coin);
           } else {
             ref.read(feeSheetSessionCacheProvider).average[amount] =
                 Format.satoshisToAmount(
-                    await manager.estimateFeeFor(amount, feeRate));
+                    await manager.estimateFeeFor(amount, feeRate),
+                    coin: coin);
           }
         }
         return ref.read(feeSheetSessionCacheProvider).average[amount]!;
@@ -93,47 +116,33 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
           final manager =
               ref.read(walletsChangeNotifierProvider).getManager(walletId);
 
-          if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+          if (coin == Coin.monero || coin == Coin.wownero) {
+            final fee = await manager.estimateFeeFor(
+                amount, MoneroTransactionPriority.slow.raw!);
+            ref.read(feeSheetSessionCacheProvider).slow[amount] =
+                Format.satoshisToAmount(
+              fee,
+              coin: coin,
+            );
+          } else if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
               ref.read(publicPrivateBalanceStateProvider.state).state !=
                   "Private") {
             ref.read(feeSheetSessionCacheProvider).slow[amount] =
-                Format.satoshisToAmount(await (manager.wallet as FiroWallet)
-                    .estimateFeeForPublic(amount, feeRate));
+                Format.satoshisToAmount(
+                    await (manager.wallet as FiroWallet)
+                        .estimateFeeForPublic(amount, feeRate),
+                    coin: coin);
           } else {
             ref.read(feeSheetSessionCacheProvider).slow[amount] =
                 Format.satoshisToAmount(
-                    await manager.estimateFeeFor(amount, feeRate));
+                    await manager.estimateFeeFor(amount, feeRate),
+                    coin: coin);
           }
         }
         return ref.read(feeSheetSessionCacheProvider).slow[amount]!;
     }
   }
 
-  String estimatedTimeToBeIncludedInNextBlock(
-      int targetBlockTime, int estimatedNumberOfBlocks) {
-    int time = targetBlockTime * estimatedNumberOfBlocks;
-
-    int hours = (time / 3600).floor();
-    if (hours > 1) {
-      return "~$hours hours";
-    } else if (hours == 1) {
-      return "~$hours hour";
-    }
-
-    // less than an hour
-
-    final string = (time / 60).toStringAsFixed(1);
-
-    if (string == "1.0") {
-      return "~1 minute";
-    } else {
-      if (string.endsWith(".0")) {
-        return "~${(time / 60).floor()} minutes";
-      }
-      return "~$string minutes";
-    }
-  }
-
   @override
   void initState() {
     walletId = widget.walletId;
@@ -307,7 +316,7 @@ class FeeDropDownChild extends ConsumerWidget {
       return FutureBuilder(
         future: feeFor(
           coin: manager.coin,
-          feeRateType: FeeRateType.fast,
+          feeRateType: feeRateType,
           feeRate: feeRateType == FeeRateType.fast
               ? feeObject!.fast
               : feeRateType == FeeRateType.slow
@@ -315,6 +324,7 @@ class FeeDropDownChild extends ConsumerWidget {
                   : feeObject!.medium,
           amount: Format.decimalAmountToSatoshis(
             ref.watch(sendAmountProvider.state).state,
+            manager.coin,
           ),
         ),
         builder: (_, AsyncSnapshot<Decimal> snapshot) {
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index 336dd7b4e..72690c7e5 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -161,20 +161,22 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
       return;
     }
 
-    final amount = Format.decimalAmountToSatoshis(_amountToSend!);
+    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(
-            await (manager.wallet as FiroWallet).availablePrivateBalance());
+            await (manager.wallet as FiroWallet).availablePrivateBalance(),
+            coin);
       } else {
         availableBalance = Format.decimalAmountToSatoshis(
-            await (manager.wallet as FiroWallet).availablePublicBalance());
+            await (manager.wallet as FiroWallet).availablePublicBalance(),
+            coin);
       }
     } else {
       availableBalance =
-          Format.decimalAmountToSatoshis(await manager.availableBalance);
+          Format.decimalAmountToSatoshis(await manager.availableBalance, coin);
     }
 
     // confirm send all
@@ -642,7 +644,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           cryptoAmountController.text = Format.localizedStringAsFixed(
             value: amount,
             locale: ref.read(localeServiceChangeNotifierProvider).locale,
-            decimalPlaces: Constants.decimalPlaces,
+            decimalPlaces: Constants.decimalPlacesForCoin(coin),
           );
           amount.toString();
           _amountToSend = amount;
@@ -709,8 +711,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
       } else {
         _amountToSend = baseAmount <= Decimal.zero
             ? Decimal.zero
-            : (baseAmount / _price)
-                .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces);
+            : (baseAmount / _price).toDecimal(
+                scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin));
       }
       if (_cachedAmountToSend != null && _cachedAmountToSend == _amountToSend) {
         return;
@@ -722,7 +724,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
       final amountString = Format.localizedStringAsFixed(
         value: _amountToSend!,
         locale: ref.read(localeServiceChangeNotifierProvider).locale,
-        decimalPlaces: Constants.decimalPlaces,
+        decimalPlaces: Constants.decimalPlacesForCoin(coin),
       );
 
       _cryptoAmountChangeLock = true;
@@ -752,18 +754,18 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           "Private") {
         cryptoAmountController.text =
             (await firoWallet.availablePrivateBalance())
-                .toStringAsFixed(Constants.decimalPlaces);
+                .toStringAsFixed(Constants.decimalPlacesForCoin(coin));
       } else {
         cryptoAmountController.text =
             (await firoWallet.availablePublicBalance())
-                .toStringAsFixed(Constants.decimalPlaces);
+                .toStringAsFixed(Constants.decimalPlacesForCoin(coin));
       }
     } else {
       cryptoAmountController.text = (await ref
               .read(walletsChangeNotifierProvider)
               .getManager(walletId)
               .availableBalance)
-          .toStringAsFixed(Constants.decimalPlaces);
+          .toStringAsFixed(Constants.decimalPlacesForCoin(coin));
     }
   }
 
diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart
index dfd5ea180..25ec6b519 100644
--- a/lib/services/coins/bitcoin/bitcoin_wallet.dart
+++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart
@@ -200,19 +200,21 @@ class BitcoinWallet extends CoinServiceAPI {
   Future<Decimal> get availableBalance async {
     final data = await utxoData;
     return Format.satoshisToAmount(
-        data.satoshiBalance - data.satoshiBalanceUnconfirmed);
+        data.satoshiBalance - data.satoshiBalanceUnconfirmed,
+        coin: coin);
   }
 
   @override
   Future<Decimal> get pendingBalance async {
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
+    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
   }
 
   @override
   Future<Decimal> get balanceMinusMaxFee async =>
       (await availableBalance) -
-      (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
+      (Decimal.fromInt((await maxFee)) /
+              Decimal.fromInt(Constants.satsPerCoin(coin)))
           .toDecimal();
 
   @override
@@ -222,13 +224,13 @@ class BitcoinWallet extends CoinServiceAPI {
           .get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
       if (totalBalance == null) {
         final data = await utxoData;
-        return Format.satoshisToAmount(data.satoshiBalance);
+        return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
       } else {
-        return Format.satoshisToAmount(totalBalance);
+        return Format.satoshisToAmount(totalBalance, coin: coin);
       }
     }
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalance);
+    return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
   }
 
   @override
@@ -266,7 +268,8 @@ class BitcoinWallet extends CoinServiceAPI {
   @override
   Future<int> get maxFee async {
     final fee = (await fees).fast as String;
-    final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin);
+    final satsFee =
+        Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin(coin));
     return satsFee.floor().toBigInt().toInt();
   }
 
@@ -1093,7 +1096,8 @@ class BitcoinWallet extends CoinServiceAPI {
 
         // check for send all
         bool isSendAll = false;
-        final balance = Format.decimalAmountToSatoshis(await availableBalance);
+        final balance =
+            Format.decimalAmountToSatoshis(await availableBalance, coin);
         if (satoshiAmount == balance) {
           isSendAll = true;
         }
@@ -1297,7 +1301,7 @@ class BitcoinWallet extends CoinServiceAPI {
     final String worthNow = Format.localizedStringAsFixed(
         value:
             ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2),
         decimalPlaces: 2,
         locale: locale!);
@@ -1497,9 +1501,9 @@ class BitcoinWallet extends CoinServiceAPI {
         numberOfBlocksFast: f,
         numberOfBlocksAverage: m,
         numberOfBlocksSlow: s,
-        fast: Format.decimalAmountToSatoshis(fast),
-        medium: Format.decimalAmountToSatoshis(medium),
-        slow: Format.decimalAmountToSatoshis(slow),
+        fast: Format.decimalAmountToSatoshis(fast, coin),
+        medium: Format.decimalAmountToSatoshis(medium, coin),
+        slow: Format.decimalAmountToSatoshis(slow, coin),
       );
 
       Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
@@ -1968,7 +1972,7 @@ class BitcoinWallet extends CoinServiceAPI {
           utxo["status"]["block_time"] = txn["blocktime"];
 
           final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
           utxo["rawWorth"] = fiatValue;
           utxo["fiatWorth"] = fiatValue.toString();
@@ -1978,15 +1982,16 @@ class BitcoinWallet extends CoinServiceAPI {
 
       Decimal currencyBalanceRaw =
           ((Decimal.fromInt(satoshiBalance) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
 
       final Map<String, dynamic> result = {
         "total_user_currency": currencyBalanceRaw.toString(),
         "total_sats": satoshiBalance,
         "total_btc": (Decimal.fromInt(satoshiBalance) /
-                Decimal.fromInt(Constants.satsPerCoin))
-            .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
+                Decimal.fromInt(Constants.satsPerCoin(coin)))
+            .toDecimal(
+                scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
             .toString(),
         "outputArray": outputArray,
         "unconfirmed": satoshiBalancePending,
@@ -2532,7 +2537,7 @@ class BitcoinWallet extends CoinServiceAPI {
             if (prevOut == out["n"]) {
               inputAmtSentFromWallet +=
                   (Decimal.parse(out["value"]!.toString()) *
-                          Decimal.fromInt(Constants.satsPerCoin))
+                          Decimal.fromInt(Constants.satsPerCoin(coin)))
                       .toBigInt()
                       .toInt();
             }
@@ -2545,7 +2550,7 @@ class BitcoinWallet extends CoinServiceAPI {
           final String address = output["scriptPubKey"]!["address"] as String;
           final value = output["value"]!;
           final _value = (Decimal.parse(value.toString()) *
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toBigInt()
               .toInt();
           totalOutput += _value;
@@ -2570,7 +2575,7 @@ class BitcoinWallet extends CoinServiceAPI {
           final address = output["scriptPubKey"]["address"];
           if (address != null) {
             final value = (Decimal.parse(output["value"].toString()) *
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toBigInt()
                 .toInt();
             totalOut += value;
@@ -2593,7 +2598,7 @@ class BitcoinWallet extends CoinServiceAPI {
           for (final out in tx["vout"] as List) {
             if (prevOut == out["n"]) {
               totalIn += (Decimal.parse(out["value"].toString()) *
-                      Decimal.fromInt(Constants.satsPerCoin))
+                      Decimal.fromInt(Constants.satsPerCoin(coin)))
                   .toBigInt()
                   .toInt();
             }
@@ -2615,7 +2620,7 @@ class BitcoinWallet extends CoinServiceAPI {
         midSortedTx["amount"] = inputAmtSentFromWallet;
         final String worthNow =
             ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -2625,7 +2630,7 @@ class BitcoinWallet extends CoinServiceAPI {
         midSortedTx["amount"] = outputAmtAddressedToWallet;
         final worthNow =
             ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -3753,7 +3758,8 @@ class BitcoinWallet extends CoinServiceAPI {
 
   @override
   Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
-    final available = Format.decimalAmountToSatoshis(await availableBalance);
+    final available =
+        Format.decimalAmountToSatoshis(await availableBalance, coin);
 
     if (available == satoshiAmount) {
       return satoshiAmount - sweepAllEstimate(feeRate);
diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
index 429af898e..59b2454b4 100644
--- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
+++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart
@@ -170,19 +170,21 @@ class BitcoinCashWallet extends CoinServiceAPI {
   Future<Decimal> get availableBalance async {
     final data = await utxoData;
     return Format.satoshisToAmount(
-        data.satoshiBalance - data.satoshiBalanceUnconfirmed);
+        data.satoshiBalance - data.satoshiBalanceUnconfirmed,
+        coin: coin);
   }
 
   @override
   Future<Decimal> get pendingBalance async {
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
+    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
   }
 
   @override
   Future<Decimal> get balanceMinusMaxFee async =>
       (await availableBalance) -
-      (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
+      (Decimal.fromInt((await maxFee)) /
+              Decimal.fromInt(Constants.satsPerCoin(coin)))
           .toDecimal();
 
   @override
@@ -192,13 +194,13 @@ class BitcoinCashWallet extends CoinServiceAPI {
           .get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
       if (totalBalance == null) {
         final data = await utxoData;
-        return Format.satoshisToAmount(data.satoshiBalance);
+        return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
       } else {
-        return Format.satoshisToAmount(totalBalance);
+        return Format.satoshisToAmount(totalBalance, coin: coin);
       }
     }
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalance);
+    return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
   }
 
   @override
@@ -232,8 +234,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
   @override
   Future<int> get maxFee async {
     final fee = (await fees).fast;
-    final satsFee =
-        Format.satoshisToAmount(fee) * Decimal.fromInt(Constants.satsPerCoin);
+    final satsFee = Format.satoshisToAmount(fee, coin: coin) *
+        Decimal.fromInt(Constants.satsPerCoin(coin));
     return satsFee.floor().toBigInt().toInt();
   }
 
@@ -988,7 +990,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
         }
         // check for send all
         bool isSendAll = false;
-        final balance = Format.decimalAmountToSatoshis(await availableBalance);
+        final balance =
+            Format.decimalAmountToSatoshis(await availableBalance, coin);
         if (satoshiAmount == balance) {
           isSendAll = true;
         }
@@ -1175,7 +1178,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
     final String worthNow = Format.localizedStringAsFixed(
         value:
             ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2),
         decimalPlaces: 2,
         locale: locale!);
@@ -1384,9 +1387,9 @@ class BitcoinCashWallet extends CoinServiceAPI {
         numberOfBlocksFast: f,
         numberOfBlocksAverage: m,
         numberOfBlocksSlow: s,
-        fast: Format.decimalAmountToSatoshis(fast),
-        medium: Format.decimalAmountToSatoshis(medium),
-        slow: Format.decimalAmountToSatoshis(slow),
+        fast: Format.decimalAmountToSatoshis(fast, coin),
+        medium: Format.decimalAmountToSatoshis(medium, coin),
+        slow: Format.decimalAmountToSatoshis(slow, coin),
       );
 
       Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
@@ -1791,7 +1794,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
           utxo["status"]["block_time"] = txn["blocktime"];
 
           final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
           utxo["rawWorth"] = fiatValue;
           utxo["fiatWorth"] = fiatValue.toString();
@@ -1801,15 +1804,16 @@ class BitcoinCashWallet extends CoinServiceAPI {
 
       Decimal currencyBalanceRaw =
           ((Decimal.fromInt(satoshiBalance) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
 
       final Map<String, dynamic> result = {
         "total_user_currency": currencyBalanceRaw.toString(),
         "total_sats": satoshiBalance,
         "total_btc": (Decimal.fromInt(satoshiBalance) /
-                Decimal.fromInt(Constants.satsPerCoin))
-            .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
+                Decimal.fromInt(Constants.satsPerCoin(coin)))
+            .toDecimal(
+                scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
             .toString(),
         "outputArray": outputArray,
         "unconfirmed": satoshiBalancePending,
@@ -2332,7 +2336,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
             if (prevOut == out["n"]) {
               inputAmtSentFromWallet +=
                   (Decimal.parse(out["value"].toString()) *
-                          Decimal.fromInt(Constants.satsPerCoin))
+                          Decimal.fromInt(Constants.satsPerCoin(coin)))
                       .toBigInt()
                       .toInt();
             }
@@ -2345,7 +2349,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
           final address = output["scriptPubKey"]["addresses"][0];
           final value = output["value"];
           final _value = (Decimal.parse(value.toString()) *
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toBigInt()
               .toInt();
           totalOutput += _value;
@@ -2370,7 +2374,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
           final address = output["scriptPubKey"]["addresses"][0];
           if (address != null) {
             final value = (Decimal.parse(output["value"].toString()) *
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toBigInt()
                 .toInt();
             totalOut += value;
@@ -2394,7 +2398,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
           for (final out in tx["vout"] as List) {
             if (prevOut == out["n"]) {
               totalIn += (Decimal.parse(out["value"].toString()) *
-                      Decimal.fromInt(Constants.satsPerCoin))
+                      Decimal.fromInt(Constants.satsPerCoin(coin)))
                   .toBigInt()
                   .toInt();
             }
@@ -2416,7 +2420,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
         midSortedTx["amount"] = inputAmtSentFromWallet;
         final String worthNow =
             ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -2426,7 +2430,7 @@ class BitcoinCashWallet extends CoinServiceAPI {
         midSortedTx["amount"] = outputAmtAddressedToWallet;
         final worthNow =
             ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -3457,7 +3461,8 @@ class BitcoinCashWallet extends CoinServiceAPI {
 
   @override
   Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
-    final available = Format.decimalAmountToSatoshis(await availableBalance);
+    final available =
+        Format.decimalAmountToSatoshis(await availableBalance, coin);
 
     if (available == satoshiAmount) {
       return satoshiAmount - sweepAllEstimate(feeRate);
diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart
index 41778a9e0..f7372752b 100644
--- a/lib/services/coins/dogecoin/dogecoin_wallet.dart
+++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart
@@ -167,19 +167,21 @@ class DogecoinWallet extends CoinServiceAPI {
   Future<Decimal> get availableBalance async {
     final data = await utxoData;
     return Format.satoshisToAmount(
-        data.satoshiBalance - data.satoshiBalanceUnconfirmed);
+        data.satoshiBalance - data.satoshiBalanceUnconfirmed,
+        coin: coin);
   }
 
   @override
   Future<Decimal> get pendingBalance async {
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
+    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
   }
 
   @override
   Future<Decimal> get balanceMinusMaxFee async =>
       (await availableBalance) -
-      (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
+      (Decimal.fromInt((await maxFee)) /
+              Decimal.fromInt(Constants.satsPerCoin(coin)))
           .toDecimal();
 
   @override
@@ -189,13 +191,13 @@ class DogecoinWallet extends CoinServiceAPI {
           .get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
       if (totalBalance == null) {
         final data = await utxoData;
-        return Format.satoshisToAmount(data.satoshiBalance);
+        return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
       } else {
-        return Format.satoshisToAmount(totalBalance);
+        return Format.satoshisToAmount(totalBalance, coin: coin);
       }
     }
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalance);
+    return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
   }
 
   @override
@@ -225,8 +227,8 @@ class DogecoinWallet extends CoinServiceAPI {
   @override
   Future<int> get maxFee async {
     final fee = (await fees).fast;
-    final satsFee =
-        Format.satoshisToAmount(fee) * Decimal.fromInt(Constants.satsPerCoin);
+    final satsFee = Format.satoshisToAmount(fee, coin: coin) *
+        Decimal.fromInt(Constants.satsPerCoin(coin));
     return satsFee.floor().toBigInt().toInt();
   }
 
@@ -878,7 +880,8 @@ class DogecoinWallet extends CoinServiceAPI {
         }
         // check for send all
         bool isSendAll = false;
-        final balance = Format.decimalAmountToSatoshis(await availableBalance);
+        final balance =
+            Format.decimalAmountToSatoshis(await availableBalance, coin);
         if (satoshiAmount == balance) {
           isSendAll = true;
         }
@@ -1065,7 +1068,7 @@ class DogecoinWallet extends CoinServiceAPI {
     final String worthNow = Format.localizedStringAsFixed(
         value:
             ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2),
         decimalPlaces: 2,
         locale: locale!);
@@ -1247,9 +1250,9 @@ class DogecoinWallet extends CoinServiceAPI {
         numberOfBlocksFast: f,
         numberOfBlocksAverage: m,
         numberOfBlocksSlow: s,
-        fast: Format.decimalAmountToSatoshis(fast),
-        medium: Format.decimalAmountToSatoshis(medium),
-        slow: Format.decimalAmountToSatoshis(slow),
+        fast: Format.decimalAmountToSatoshis(fast, coin),
+        medium: Format.decimalAmountToSatoshis(medium, coin),
+        slow: Format.decimalAmountToSatoshis(slow, coin),
       );
 
       Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
@@ -1650,7 +1653,7 @@ class DogecoinWallet extends CoinServiceAPI {
           utxo["status"]["block_time"] = txn["blocktime"];
 
           final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
           utxo["rawWorth"] = fiatValue;
           utxo["fiatWorth"] = fiatValue.toString();
@@ -1660,15 +1663,16 @@ class DogecoinWallet extends CoinServiceAPI {
 
       Decimal currencyBalanceRaw =
           ((Decimal.fromInt(satoshiBalance) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
 
       final Map<String, dynamic> result = {
         "total_user_currency": currencyBalanceRaw.toString(),
         "total_sats": satoshiBalance,
         "total_btc": (Decimal.fromInt(satoshiBalance) /
-                Decimal.fromInt(Constants.satsPerCoin))
-            .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
+                Decimal.fromInt(Constants.satsPerCoin(coin)))
+            .toDecimal(
+                scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
             .toString(),
         "outputArray": outputArray,
         "unconfirmed": satoshiBalancePending,
@@ -2144,7 +2148,7 @@ class DogecoinWallet extends CoinServiceAPI {
             if (prevOut == out["n"]) {
               inputAmtSentFromWallet +=
                   (Decimal.parse(out["value"].toString()) *
-                          Decimal.fromInt(Constants.satsPerCoin))
+                          Decimal.fromInt(Constants.satsPerCoin(coin)))
                       .toBigInt()
                       .toInt();
             }
@@ -2157,7 +2161,7 @@ class DogecoinWallet extends CoinServiceAPI {
           final address = output["scriptPubKey"]["addresses"][0];
           final value = output["value"];
           final _value = (Decimal.parse(value.toString()) *
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toBigInt()
               .toInt();
           totalOutput += _value;
@@ -2182,7 +2186,7 @@ class DogecoinWallet extends CoinServiceAPI {
           final address = output["scriptPubKey"]["addresses"][0];
           if (address != null) {
             final value = (Decimal.parse(output["value"].toString()) *
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toBigInt()
                 .toInt();
             totalOut += value;
@@ -2205,7 +2209,7 @@ class DogecoinWallet extends CoinServiceAPI {
           for (final out in tx["vout"] as List) {
             if (prevOut == out["n"]) {
               totalIn += (Decimal.parse(out["value"].toString()) *
-                      Decimal.fromInt(Constants.satsPerCoin))
+                      Decimal.fromInt(Constants.satsPerCoin(coin)))
                   .toBigInt()
                   .toInt();
             }
@@ -2227,7 +2231,7 @@ class DogecoinWallet extends CoinServiceAPI {
         midSortedTx["amount"] = inputAmtSentFromWallet;
         final String worthNow =
             ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -2237,7 +2241,7 @@ class DogecoinWallet extends CoinServiceAPI {
         midSortedTx["amount"] = outputAmtAddressedToWallet;
         final worthNow =
             ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -3050,7 +3054,8 @@ class DogecoinWallet extends CoinServiceAPI {
 
   @override
   Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
-    final available = Format.decimalAmountToSatoshis(await availableBalance);
+    final available =
+        Format.decimalAmountToSatoshis(await availableBalance, coin);
 
     if (available == satoshiAmount) {
       return satoshiAmount - sweepAllEstimate(feeRate);
diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart
index 4bd863f2c..3e0cba75d 100644
--- a/lib/services/coins/firo/firo_wallet.dart
+++ b/lib/services/coins/firo/firo_wallet.dart
@@ -620,7 +620,7 @@ Future<dynamic> isolateCreateJoinSplitTransaction(
     "txid": txId,
     "txHex": txHex,
     "value": amount,
-    "fees": Format.satoshisToAmount(fee).toDouble(),
+    "fees": Format.satoshisToAmount(fee, coin: coin).toDouble(),
     "fee": fee,
     "vSize": extTx.virtualSize(),
     "jmintValue": changeToMint,
@@ -629,11 +629,11 @@ Future<dynamic> isolateCreateJoinSplitTransaction(
     "height": locktime,
     "txType": "Sent",
     "confirmed_status": false,
-    "amount": Format.satoshisToAmount(amount).toDouble(),
+    "amount": Format.satoshisToAmount(amount, coin: coin).toDouble(),
     "recipientAmt": amount,
     "worthNow": Format.localizedStringAsFixed(
         value: ((Decimal.fromInt(amount) * price) /
-                Decimal.fromInt(Constants.satsPerCoin))
+                Decimal.fromInt(Constants.satsPerCoin(coin)))
             .toDecimal(scaleOnInfinitePrecision: 2),
         decimalPlaces: 2,
         locale: locale),
@@ -883,7 +883,7 @@ class FiroWallet extends CoinServiceAPI {
   Future<Decimal> get balanceMinusMaxFee async {
     final balances = await this.balances;
     final maxFee = await this.maxFee;
-    return balances[0] - Format.satoshisToAmount(maxFee);
+    return balances[0] - Format.satoshisToAmount(maxFee, coin: coin);
   }
 
   @override
@@ -919,7 +919,7 @@ class FiroWallet extends CoinServiceAPI {
     final String worthNow = Format.localizedStringAsFixed(
         value:
             ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2),
         decimalPlaces: 2,
         locale: locale!);
@@ -1089,8 +1089,8 @@ class FiroWallet extends CoinServiceAPI {
 
         // check for send all
         bool isSendAll = false;
-        final balance =
-            Format.decimalAmountToSatoshis(await availablePublicBalance());
+        final balance = Format.decimalAmountToSatoshis(
+            await availablePublicBalance(), coin);
         if (satoshiAmount == balance) {
           isSendAll = true;
         }
@@ -1176,7 +1176,7 @@ class FiroWallet extends CoinServiceAPI {
       // check for send all
       bool isSendAll = false;
       final balance =
-          Format.decimalAmountToSatoshis(await availablePrivateBalance());
+          Format.decimalAmountToSatoshis(await availablePrivateBalance(), coin);
       if (satoshiAmount == balance) {
         // print("is send all");
         isSendAll = true;
@@ -1222,7 +1222,8 @@ class FiroWallet extends CoinServiceAPI {
         // temporarily update apdate available balance until a full refresh is done
 
         // TODO: something here causes an exception to be thrown giving user false info that the tx failed
-        Decimal sendTotal = Format.satoshisToAmount(txData["value"] as int);
+        Decimal sendTotal =
+            Format.satoshisToAmount(txData["value"] as int, coin: coin);
         sendTotal += Decimal.parse(txData["fees"].toString());
         final bals = await balances;
         bals[0] -= sendTotal;
@@ -1270,7 +1271,7 @@ class FiroWallet extends CoinServiceAPI {
 
           // temporarily update apdate available balance until a full refresh is done
           Decimal sendTotal =
-              Format.satoshisToAmount(txHexOrError["value"] as int);
+              Format.satoshisToAmount(txHexOrError["value"] as int, coin: coin);
           sendTotal += Decimal.parse(txHexOrError["fees"].toString());
           final bals = await balances;
           bals[0] -= sendTotal;
@@ -2333,8 +2334,9 @@ class FiroWallet extends CoinServiceAPI {
 
   Future<int> _fetchMaxFee() async {
     final balance = await availableBalance;
-    int spendAmount =
-        (balance * Decimal.fromInt(Constants.satsPerCoin)).toBigInt().toInt();
+    int spendAmount = (balance * Decimal.fromInt(Constants.satsPerCoin(coin)))
+        .toBigInt()
+        .toInt();
     int fee = await estimateJoinSplitFee(spendAmount);
     return fee;
   }
@@ -2480,18 +2482,20 @@ class FiroWallet extends CoinServiceAPI {
       }
 
       final int utxosIntValue = utxos.satoshiBalance;
-      final Decimal utxosValue = Format.satoshisToAmount(utxosIntValue);
+      final Decimal utxosValue =
+          Format.satoshisToAmount(utxosIntValue, coin: coin);
 
       List<Decimal> balances = List.empty(growable: true);
 
-      Decimal lelantusBalance = Format.satoshisToAmount(intLelantusBalance);
+      Decimal lelantusBalance =
+          Format.satoshisToAmount(intLelantusBalance, coin: coin);
 
       balances.add(lelantusBalance);
 
       balances.add(lelantusBalance * price);
 
       Decimal _unconfirmedLelantusBalance =
-          Format.satoshisToAmount(unconfirmedLelantusBalance);
+          Format.satoshisToAmount(unconfirmedLelantusBalance, coin: coin);
 
       balances.add(lelantusBalance + utxosValue + _unconfirmedLelantusBalance);
 
@@ -2503,7 +2507,7 @@ class FiroWallet extends CoinServiceAPI {
       if (availableSats < 0) {
         availableSats = 0;
       }
-      balances.add(Format.satoshisToAmount(availableSats));
+      balances.add(Format.satoshisToAmount(availableSats, coin: coin));
 
       Logging.instance.log("balances $balances", level: LogLevel.Info);
       await DB.instance.put<dynamic>(
@@ -2601,7 +2605,8 @@ class FiroWallet extends CoinServiceAPI {
 
     final feesObject = await fees;
 
-    final Decimal fastFee = Format.satoshisToAmount(feesObject.fast);
+    final Decimal fastFee =
+        Format.satoshisToAmount(feesObject.fast, coin: coin);
     int firoFee =
         (dvsize * fastFee * Decimal.fromInt(100000)).toDouble().ceil();
     // int firoFee = (vsize * feesObject.fast * (1 / 1000.0) * 100000000).ceil();
@@ -2789,15 +2794,15 @@ class FiroWallet extends CoinServiceAPI {
       "txid": txId,
       "txHex": txHex,
       "value": amount - fee,
-      "fees": Format.satoshisToAmount(fee).toDouble(),
+      "fees": Format.satoshisToAmount(fee, coin: coin).toDouble(),
       "publicCoin": "",
       "height": height,
       "txType": "Sent",
       "confirmed_status": false,
-      "amount": Format.satoshisToAmount(amount).toDouble(),
+      "amount": Format.satoshisToAmount(amount, coin: coin).toDouble(),
       "worthNow": Format.localizedStringAsFixed(
           value: ((Decimal.fromInt(amount) * price) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2),
           decimalPlaces: 2,
           locale: locale!),
@@ -3040,9 +3045,9 @@ class FiroWallet extends CoinServiceAPI {
         numberOfBlocksFast: f,
         numberOfBlocksAverage: m,
         numberOfBlocksSlow: s,
-        fast: Format.decimalAmountToSatoshis(fast),
-        medium: Format.decimalAmountToSatoshis(medium),
-        slow: Format.decimalAmountToSatoshis(slow),
+        fast: Format.decimalAmountToSatoshis(fast, coin),
+        medium: Format.decimalAmountToSatoshis(medium, coin),
+        slow: Format.decimalAmountToSatoshis(slow, coin),
       );
 
       Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
@@ -3328,7 +3333,7 @@ class FiroWallet extends CoinServiceAPI {
           if (nFees != null) {
             nFeesUsed = true;
             fees = (Decimal.parse(nFees.toString()) *
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toBigInt()
                 .toInt();
           }
@@ -3353,7 +3358,7 @@ class FiroWallet extends CoinServiceAPI {
             if (value != null) {
               if (changeAddresses.contains(address)) {
                 inputAmtSentFromWallet -= (Decimal.parse(value.toString()) *
-                        Decimal.fromInt(Constants.satsPerCoin))
+                        Decimal.fromInt(Constants.satsPerCoin(coin)))
                     .toBigInt()
                     .toInt();
               } else {
@@ -3363,7 +3368,7 @@ class FiroWallet extends CoinServiceAPI {
           }
           if (value != null) {
             outAmount += (Decimal.parse(value.toString()) *
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toBigInt()
                 .toInt();
           }
@@ -3376,7 +3381,7 @@ class FiroWallet extends CoinServiceAPI {
           final nFees = input["nFees"];
           if (nFees != null) {
             fees += (Decimal.parse(nFees.toString()) *
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toBigInt()
                 .toInt();
           }
@@ -3391,7 +3396,7 @@ class FiroWallet extends CoinServiceAPI {
 
             if (allAddresses.contains(address)) {
               outputAmtAddressedToWallet += (Decimal.parse(value.toString()) *
-                      Decimal.fromInt(Constants.satsPerCoin))
+                      Decimal.fromInt(Constants.satsPerCoin(coin)))
                   .toBigInt()
                   .toInt();
               outAddress = address;
@@ -3413,7 +3418,7 @@ class FiroWallet extends CoinServiceAPI {
         midSortedTx["amount"] = inputAmtSentFromWallet;
         final String worthNow = Format.localizedStringAsFixed(
             value: ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2),
             decimalPlaces: 2,
             locale: locale!);
@@ -3428,7 +3433,7 @@ class FiroWallet extends CoinServiceAPI {
         final worthNow = Format.localizedStringAsFixed(
             value:
                 ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
-                        Decimal.fromInt(Constants.satsPerCoin))
+                        Decimal.fromInt(Constants.satsPerCoin(coin)))
                     .toDecimal(scaleOnInfinitePrecision: 2),
             decimalPlaces: 2,
             locale: locale!);
@@ -3589,7 +3594,7 @@ class FiroWallet extends CoinServiceAPI {
           utxo["status"]["block_time"] = txn["blocktime"];
 
           final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
           utxo["rawWorth"] = fiatValue;
           utxo["fiatWorth"] = fiatValue.toString();
@@ -3600,15 +3605,16 @@ class FiroWallet extends CoinServiceAPI {
 
       Decimal currencyBalanceRaw =
           ((Decimal.fromInt(satoshiBalance) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
 
       final Map<String, dynamic> result = {
         "total_user_currency": currencyBalanceRaw.toString(),
         "total_sats": satoshiBalance,
         "total_btc": (Decimal.fromInt(satoshiBalance) /
-                Decimal.fromInt(Constants.satsPerCoin))
-            .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
+                Decimal.fromInt(Constants.satsPerCoin(coin)))
+            .toDecimal(
+                scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
             .toString(),
         "outputArray": outputArray,
         "unconfirmed": satoshiBalancePending,
@@ -4571,8 +4577,9 @@ class FiroWallet extends CoinServiceAPI {
   ) async {
     var lelantusEntry = await _getLelantusEntry();
     final balance = await availableBalance;
-    int spendAmount =
-        (balance * Decimal.fromInt(Constants.satsPerCoin)).toBigInt().toInt();
+    int spendAmount = (balance * Decimal.fromInt(Constants.satsPerCoin(coin)))
+        .toBigInt()
+        .toInt();
     if (spendAmount == 0 || lelantusEntry.isEmpty) {
       return LelantusFeeData(0, 0, []).fee;
     }
@@ -4633,7 +4640,7 @@ class FiroWallet extends CoinServiceAPI {
 
   Future<int> estimateFeeForPublic(int satoshiAmount, int feeRate) async {
     final available =
-        Format.decimalAmountToSatoshis(await availablePublicBalance());
+        Format.decimalAmountToSatoshis(await availablePublicBalance(), coin);
 
     if (available == satoshiAmount) {
       return satoshiAmount - sweepAllEstimate(feeRate);
diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart
index db7c9d1fa..9c4bb2305 100644
--- a/lib/services/coins/litecoin/litecoin_wallet.dart
+++ b/lib/services/coins/litecoin/litecoin_wallet.dart
@@ -200,19 +200,21 @@ class LitecoinWallet extends CoinServiceAPI {
   Future<Decimal> get availableBalance async {
     final data = await utxoData;
     return Format.satoshisToAmount(
-        data.satoshiBalance - data.satoshiBalanceUnconfirmed);
+        data.satoshiBalance - data.satoshiBalanceUnconfirmed,
+        coin: coin);
   }
 
   @override
   Future<Decimal> get pendingBalance async {
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
+    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
   }
 
   @override
   Future<Decimal> get balanceMinusMaxFee async =>
       (await availableBalance) -
-      (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
+      (Decimal.fromInt((await maxFee)) /
+              Decimal.fromInt(Constants.satsPerCoin(coin)))
           .toDecimal();
 
   @override
@@ -222,13 +224,13 @@ class LitecoinWallet extends CoinServiceAPI {
           .get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
       if (totalBalance == null) {
         final data = await utxoData;
-        return Format.satoshisToAmount(data.satoshiBalance);
+        return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
       } else {
-        return Format.satoshisToAmount(totalBalance);
+        return Format.satoshisToAmount(totalBalance, coin: coin);
       }
     }
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalance);
+    return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
   }
 
   @override
@@ -266,7 +268,8 @@ class LitecoinWallet extends CoinServiceAPI {
   @override
   Future<int> get maxFee async {
     final fee = (await fees).fast as String;
-    final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin);
+    final satsFee =
+        Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin(coin));
     return satsFee.floor().toBigInt().toInt();
   }
 
@@ -1095,7 +1098,8 @@ class LitecoinWallet extends CoinServiceAPI {
 
         // check for send all
         bool isSendAll = false;
-        final balance = Format.decimalAmountToSatoshis(await availableBalance);
+        final balance =
+            Format.decimalAmountToSatoshis(await availableBalance, coin);
         if (satoshiAmount == balance) {
           isSendAll = true;
         }
@@ -1299,7 +1303,7 @@ class LitecoinWallet extends CoinServiceAPI {
     final String worthNow = Format.localizedStringAsFixed(
         value:
             ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2),
         decimalPlaces: 2,
         locale: locale!);
@@ -1499,9 +1503,9 @@ class LitecoinWallet extends CoinServiceAPI {
         numberOfBlocksFast: f,
         numberOfBlocksAverage: m,
         numberOfBlocksSlow: s,
-        fast: Format.decimalAmountToSatoshis(fast),
-        medium: Format.decimalAmountToSatoshis(medium),
-        slow: Format.decimalAmountToSatoshis(slow),
+        fast: Format.decimalAmountToSatoshis(fast, coin),
+        medium: Format.decimalAmountToSatoshis(medium, coin),
+        slow: Format.decimalAmountToSatoshis(slow, coin),
       );
 
       Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
@@ -1978,7 +1982,7 @@ class LitecoinWallet extends CoinServiceAPI {
           utxo["status"]["block_time"] = txn["blocktime"];
 
           final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
           utxo["rawWorth"] = fiatValue;
           utxo["fiatWorth"] = fiatValue.toString();
@@ -1988,15 +1992,16 @@ class LitecoinWallet extends CoinServiceAPI {
 
       Decimal currencyBalanceRaw =
           ((Decimal.fromInt(satoshiBalance) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
 
       final Map<String, dynamic> result = {
         "total_user_currency": currencyBalanceRaw.toString(),
         "total_sats": satoshiBalance,
         "total_btc": (Decimal.fromInt(satoshiBalance) /
-                Decimal.fromInt(Constants.satsPerCoin))
-            .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
+                Decimal.fromInt(Constants.satsPerCoin(coin)))
+            .toDecimal(
+                scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
             .toString(),
         "outputArray": outputArray,
         "unconfirmed": satoshiBalancePending,
@@ -2543,7 +2548,7 @@ class LitecoinWallet extends CoinServiceAPI {
             if (prevOut == out["n"]) {
               inputAmtSentFromWallet +=
                   (Decimal.parse(out["value"]!.toString()) *
-                          Decimal.fromInt(Constants.satsPerCoin))
+                          Decimal.fromInt(Constants.satsPerCoin(coin)))
                       .toBigInt()
                       .toInt();
             }
@@ -2557,7 +2562,7 @@ class LitecoinWallet extends CoinServiceAPI {
               output["scriptPubKey"]!["addresses"][0] as String;
           final value = output["value"]!;
           final _value = (Decimal.parse(value.toString()) *
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toBigInt()
               .toInt();
           totalOutput += _value;
@@ -2582,7 +2587,7 @@ class LitecoinWallet extends CoinServiceAPI {
           final address = output["scriptPubKey"]["addresses"][0];
           if (address != null) {
             final value = (Decimal.parse(output["value"].toString()) *
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toBigInt()
                 .toInt();
             totalOut += value;
@@ -2605,7 +2610,7 @@ class LitecoinWallet extends CoinServiceAPI {
           for (final out in tx["vout"] as List) {
             if (prevOut == out["n"]) {
               totalIn += (Decimal.parse(out["value"].toString()) *
-                      Decimal.fromInt(Constants.satsPerCoin))
+                      Decimal.fromInt(Constants.satsPerCoin(coin)))
                   .toBigInt()
                   .toInt();
             }
@@ -2627,7 +2632,7 @@ class LitecoinWallet extends CoinServiceAPI {
         midSortedTx["amount"] = inputAmtSentFromWallet;
         final String worthNow =
             ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -2637,7 +2642,7 @@ class LitecoinWallet extends CoinServiceAPI {
         midSortedTx["amount"] = outputAmtAddressedToWallet;
         final worthNow =
             ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -3769,7 +3774,8 @@ class LitecoinWallet extends CoinServiceAPI {
 
   @override
   Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
-    final available = Format.decimalAmountToSatoshis(await availableBalance);
+    final available =
+        Format.decimalAmountToSatoshis(await availableBalance, coin);
 
     if (available == satoshiAmount) {
       return satoshiAmount - sweepAllEstimate(feeRate);
diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index f94f0cd2a..58bd36c72 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -44,6 +44,7 @@ import 'package:stackwallet/utilities/default_nodes.dart';
 import 'package:stackwallet/utilities/enums/coin_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/prefs.dart';
 import 'package:stackwallet/utilities/stack_file_system.dart';
@@ -533,7 +534,8 @@ class MoneroWallet extends CoinServiceAPI {
   @override
   Future<Decimal> get balanceMinusMaxFee async =>
       (await availableBalance) -
-      (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
+      (Decimal.fromInt((await maxFee)) /
+              Decimal.fromInt(Constants.satsPerCoin(coin)))
           .toDecimal();
 
   @override
@@ -542,16 +544,16 @@ class MoneroWallet extends CoinServiceAPI {
 
   @override
   Future<void> exit() async {
-    await stopSyncPercentTimer();
     _hasCalledExit = true;
-    isActive = false;
-    await walletBase?.save(prioritySave: true);
-    walletBase?.close();
+    stopNetworkAlivePinging();
     moneroAutosaveTimer?.cancel();
     moneroAutosaveTimer = null;
     timer?.cancel();
     timer = null;
-    stopNetworkAlivePinging();
+    await stopSyncPercentTimer();
+    await walletBase?.save(prioritySave: true);
+    walletBase?.close();
+    isActive = false;
   }
 
   bool _hasCalledExit = false;
@@ -562,13 +564,15 @@ class MoneroWallet extends CoinServiceAPI {
   Future<String>? _currentReceivingAddress;
 
   Future<FeeObject> _getFees() async {
+    // TODO: not use hard coded values here
     return FeeObject(
-        numberOfBlocksFast: 10,
-        numberOfBlocksAverage: 10,
-        numberOfBlocksSlow: 10,
-        fast: 4,
-        medium: 2,
-        slow: 0);
+      numberOfBlocksFast: 10,
+      numberOfBlocksAverage: 10,
+      numberOfBlocksSlow: 10,
+      fast: MoneroTransactionPriority.fast.raw!,
+      medium: MoneroTransactionPriority.regular.raw!,
+      slow: MoneroTransactionPriority.slow.raw!,
+    );
   }
 
   @override
@@ -868,8 +872,9 @@ class MoneroWallet extends CoinServiceAPI {
   Future<int> get maxFee async {
     var bal = await availableBalance;
     var fee = walletBase!.calculateEstimatedFee(
-            monero.getDefaultTransactionPriority(), bal.toBigInt().toInt()) ~/
-        10000;
+      monero.getDefaultTransactionPriority(),
+      Format.decimalAmountToSatoshis(bal, coin),
+    );
 
     return fee;
   }
@@ -1372,7 +1377,6 @@ class MoneroWallet extends CoinServiceAPI {
   }
 
   @override
-  // TODO: implement availableBalance
   Future<Decimal> get availableBalance async {
     var bal = 0;
     for (var element in walletBase!.balance!.entries) {
@@ -1421,13 +1425,13 @@ class MoneroWallet extends CoinServiceAPI {
     try {
       final feeRate = args?["feeRate"];
       if (feeRate is FeeRateType) {
-        MoneroTransactionPriority feePriority = MoneroTransactionPriority.slow;
+        MoneroTransactionPriority feePriority;
         switch (feeRate) {
           case FeeRateType.fast:
-            feePriority = MoneroTransactionPriority.fastest;
+            feePriority = MoneroTransactionPriority.fast;
             break;
           case FeeRateType.average:
-            feePriority = MoneroTransactionPriority.medium;
+            feePriority = MoneroTransactionPriority.regular;
             break;
           case FeeRateType.slow:
             feePriority = MoneroTransactionPriority.slow;
@@ -1440,15 +1444,14 @@ class MoneroWallet extends CoinServiceAPI {
           bool isSendAll = false;
           final balance = await availableBalance;
           final satInDecimal = ((Decimal.fromInt(satoshiAmount) /
-                      Decimal.fromInt(Constants.satsPerCoinMonero))
-                  .toDecimal() *
-              Decimal.fromInt(10000));
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
+              .toDecimal());
           if (satInDecimal == balance) {
             isSendAll = true;
           }
           Logging.instance
               .log("$toAddress $amount $args", level: LogLevel.Info);
-          String amountToSend = moneroAmountToString(amount: amount * 10000);
+          String amountToSend = moneroAmountToString(amount: amount);
           Logging.instance.log("$amount $amountToSend", level: LogLevel.Info);
 
           monero_output.Output output = monero_output.Output(walletBase!);
@@ -1470,10 +1473,9 @@ class MoneroWallet extends CoinServiceAPI {
 
         PendingMoneroTransaction pendingMoneroTransaction =
             await (awaitPendingTransaction!) as PendingMoneroTransaction;
-        int realfee = (Decimal.parse(pendingMoneroTransaction.feeFormatted) *
-                100000000.toDecimal())
-            .toBigInt()
-            .toInt();
+
+        int realfee = Format.decimalAmountToSatoshis(
+            Decimal.parse(pendingMoneroTransaction.feeFormatted), coin);
         debugPrint("fee? $realfee");
         Map<String, dynamic> txData = {
           "pendingMoneroTransaction": pendingMoneroTransaction,
@@ -1506,12 +1508,13 @@ class MoneroWallet extends CoinServiceAPI {
 
   @override
   Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
-    MoneroTransactionPriority? priority;
-    FeeRateType feeRateType = FeeRateType.slow;
+    MoneroTransactionPriority priority;
+    FeeRateType feeRateType;
+
     switch (feeRate) {
       case 1:
         priority = MoneroTransactionPriority.regular;
-        feeRateType = FeeRateType.slow;
+        feeRateType = FeeRateType.average;
         break;
       case 2:
         priority = MoneroTransactionPriority.medium;
@@ -1519,7 +1522,7 @@ class MoneroWallet extends CoinServiceAPI {
         break;
       case 3:
         priority = MoneroTransactionPriority.fast;
-        feeRateType = FeeRateType.average;
+        feeRateType = FeeRateType.fast;
         break;
       case 4:
         priority = MoneroTransactionPriority.fastest;
@@ -1531,27 +1534,29 @@ class MoneroWallet extends CoinServiceAPI {
         feeRateType = FeeRateType.slow;
         break;
     }
-    var aprox;
+    // int? aprox;
 
-    await estimateFeeMutex.protect(() async {
-      {
-        try {
-          aprox = (await prepareSend(
-              // This address is only used for getting an approximate fee, never for sending
-              address:
-                  "8347huhmj6Ggzr1BpZPJAD5oa96ob5Fe8GtQdGZDYVVYVsCgtUNH3pEEzExDuaAVZdC16D4FkAb24J6wUfsKkcZtC8EPXB7",
-              satoshiAmount: satoshiAmount,
-              args: {"feeRate": feeRateType}))['fee'];
-          await Future.delayed(const Duration(milliseconds: 1000));
-        } catch (e, s) {
-          Logging.instance.log("$feeRateType $e $s", level: LogLevel.Error);
-          aprox = -9999999999999999;
-        }
-      }
-    });
+    // corrupted size vs. prev_size occurs but not sure if related to fees or just generating monero transactions in general
+
+    // await estimateFeeMutex.protect(() async {
+    //   {
+    //     try {
+    //       aprox = (await prepareSend(
+    //           // This address is only used for getting an approximate fee, never for sending
+    //           address:
+    //               "8347huhmj6Ggzr1BpZPJAD5oa96ob5Fe8GtQdGZDYVVYVsCgtUNH3pEEzExDuaAVZdC16D4FkAb24J6wUfsKkcZtC8EPXB7",
+    //           satoshiAmount: satoshiAmount,
+    //           args: {"feeRate": feeRateType}))['fee'] as int?;
+    //       await Future<void>.delayed(const Duration(milliseconds: 1000));
+    //     } catch (e, s) {
+    //       Logging.instance.log("$feeRateType $e $s", level: LogLevel.Error);
+    final aprox = walletBase!.calculateEstimatedFee(priority, satoshiAmount);
+    //     }
+    //   }
+    // });
 
     print("this is the aprox fee $aprox for $satoshiAmount");
-    final fee = (aprox as int);
+    final fee = aprox;
     return fee;
   }
 
diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart
index c8c84fb27..142bfb379 100644
--- a/lib/services/coins/namecoin/namecoin_wallet.dart
+++ b/lib/services/coins/namecoin/namecoin_wallet.dart
@@ -196,19 +196,21 @@ class NamecoinWallet extends CoinServiceAPI {
   Future<Decimal> get availableBalance async {
     final data = await utxoData;
     return Format.satoshisToAmount(
-        data.satoshiBalance - data.satoshiBalanceUnconfirmed);
+        data.satoshiBalance - data.satoshiBalanceUnconfirmed,
+        coin: coin);
   }
 
   @override
   Future<Decimal> get pendingBalance async {
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed);
+    return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin);
   }
 
   @override
   Future<Decimal> get balanceMinusMaxFee async =>
       (await availableBalance) -
-      (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
+      (Decimal.fromInt((await maxFee)) /
+              Decimal.fromInt(Constants.satsPerCoin(coin)))
           .toDecimal();
 
   @override
@@ -218,13 +220,13 @@ class NamecoinWallet extends CoinServiceAPI {
           .get<dynamic>(boxName: walletId, key: 'totalBalance') as int?;
       if (totalBalance == null) {
         final data = await utxoData;
-        return Format.satoshisToAmount(data.satoshiBalance);
+        return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
       } else {
-        return Format.satoshisToAmount(totalBalance);
+        return Format.satoshisToAmount(totalBalance, coin: coin);
       }
     }
     final data = await utxoData;
-    return Format.satoshisToAmount(data.satoshiBalance);
+    return Format.satoshisToAmount(data.satoshiBalance, coin: coin);
   }
 
   @override
@@ -262,7 +264,8 @@ class NamecoinWallet extends CoinServiceAPI {
   @override
   Future<int> get maxFee async {
     final fee = (await fees).fast as String;
-    final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin);
+    final satsFee =
+        Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin(coin));
     return satsFee.floor().toBigInt().toInt();
   }
 
@@ -1086,7 +1089,8 @@ class NamecoinWallet extends CoinServiceAPI {
 
         // check for send all
         bool isSendAll = false;
-        final balance = Format.decimalAmountToSatoshis(await availableBalance);
+        final balance =
+            Format.decimalAmountToSatoshis(await availableBalance, coin);
         if (satoshiAmount == balance) {
           isSendAll = true;
         }
@@ -1290,7 +1294,7 @@ class NamecoinWallet extends CoinServiceAPI {
     final String worthNow = Format.localizedStringAsFixed(
         value:
             ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2),
         decimalPlaces: 2,
         locale: locale!);
@@ -1490,9 +1494,9 @@ class NamecoinWallet extends CoinServiceAPI {
         numberOfBlocksFast: f,
         numberOfBlocksAverage: m,
         numberOfBlocksSlow: s,
-        fast: Format.decimalAmountToSatoshis(fast),
-        medium: Format.decimalAmountToSatoshis(medium),
-        slow: Format.decimalAmountToSatoshis(slow),
+        fast: Format.decimalAmountToSatoshis(fast, coin),
+        medium: Format.decimalAmountToSatoshis(medium, coin),
+        slow: Format.decimalAmountToSatoshis(slow, coin),
       );
 
       Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info);
@@ -1965,7 +1969,7 @@ class NamecoinWallet extends CoinServiceAPI {
           utxo["status"]["block_time"] = txn["blocktime"];
 
           final fiatValue = ((Decimal.fromInt(value) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
           utxo["rawWorth"] = fiatValue;
           utxo["fiatWorth"] = fiatValue.toString();
@@ -1975,15 +1979,16 @@ class NamecoinWallet extends CoinServiceAPI {
 
       Decimal currencyBalanceRaw =
           ((Decimal.fromInt(satoshiBalance) * currentPrice) /
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toDecimal(scaleOnInfinitePrecision: 2);
 
       final Map<String, dynamic> result = {
         "total_user_currency": currencyBalanceRaw.toString(),
         "total_sats": satoshiBalance,
         "total_btc": (Decimal.fromInt(satoshiBalance) /
-                Decimal.fromInt(Constants.satsPerCoin))
-            .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
+                Decimal.fromInt(Constants.satsPerCoin(coin)))
+            .toDecimal(
+                scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin))
             .toString(),
         "outputArray": outputArray,
         "unconfirmed": satoshiBalancePending,
@@ -2540,7 +2545,7 @@ class NamecoinWallet extends CoinServiceAPI {
             if (prevOut == out["n"]) {
               inputAmtSentFromWallet +=
                   (Decimal.parse(out["value"]!.toString()) *
-                          Decimal.fromInt(Constants.satsPerCoin))
+                          Decimal.fromInt(Constants.satsPerCoin(coin)))
                       .toBigInt()
                       .toInt();
             }
@@ -2554,7 +2559,7 @@ class NamecoinWallet extends CoinServiceAPI {
           final address = output["scriptPubKey"]["address"];
           final value = output["value"];
           final _value = (Decimal.parse(value.toString()) *
-                  Decimal.fromInt(Constants.satsPerCoin))
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
               .toBigInt()
               .toInt();
           totalOutput += _value;
@@ -2582,7 +2587,7 @@ class NamecoinWallet extends CoinServiceAPI {
           }
           if (address != null) {
             final value = (Decimal.parse(output["value"].toString()) *
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toBigInt()
                 .toInt();
             totalOut += value;
@@ -2605,7 +2610,7 @@ class NamecoinWallet extends CoinServiceAPI {
           for (final out in tx["vout"] as List) {
             if (prevOut == out["n"]) {
               totalIn += (Decimal.parse(out["value"].toString()) *
-                      Decimal.fromInt(Constants.satsPerCoin))
+                      Decimal.fromInt(Constants.satsPerCoin(coin)))
                   .toBigInt()
                   .toInt();
             }
@@ -2627,7 +2632,7 @@ class NamecoinWallet extends CoinServiceAPI {
         midSortedTx["amount"] = inputAmtSentFromWallet;
         final String worthNow =
             ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -2637,7 +2642,7 @@ class NamecoinWallet extends CoinServiceAPI {
         midSortedTx["amount"] = outputAmtAddressedToWallet;
         final worthNow =
             ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
-                    Decimal.fromInt(Constants.satsPerCoin))
+                    Decimal.fromInt(Constants.satsPerCoin(coin)))
                 .toDecimal(scaleOnInfinitePrecision: 2)
                 .toStringAsFixed(2);
         midSortedTx["worthNow"] = worthNow;
@@ -3772,7 +3777,8 @@ class NamecoinWallet extends CoinServiceAPI {
 
   @override
   Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
-    final available = Format.decimalAmountToSatoshis(await availableBalance);
+    final available =
+        Format.decimalAmountToSatoshis(await availableBalance, coin);
 
     if (available == satoshiAmount) {
       return satoshiAmount - sweepAllEstimate(feeRate);
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index e6a531b78..686dcd08c 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -45,6 +45,7 @@ import 'package:stackwallet/utilities/default_nodes.dart';
 import 'package:stackwallet/utilities/enums/coin_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/prefs.dart';
 import 'package:stackwallet/utilities/stack_file_system.dart';
@@ -534,8 +535,7 @@ class WowneroWallet extends CoinServiceAPI {
   @override
   Future<Decimal> get balanceMinusMaxFee async =>
       (await availableBalance) -
-      (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin))
-          .toDecimal();
+      Format.satoshisToAmount(await maxFee, coin: Coin.wownero);
 
   @override
   Future<String> get currentReceivingAddress =>
@@ -563,13 +563,15 @@ class WowneroWallet extends CoinServiceAPI {
   Future<String>? _currentReceivingAddress;
 
   Future<FeeObject> _getFees() async {
+    // TODO: not use hard coded values here
     return FeeObject(
-        numberOfBlocksFast: 10,
-        numberOfBlocksAverage: 10,
-        numberOfBlocksSlow: 10,
-        fast: 4,
-        medium: 2,
-        slow: 0);
+      numberOfBlocksFast: 10,
+      numberOfBlocksAverage: 10,
+      numberOfBlocksSlow: 10,
+      fast: MoneroTransactionPriority.fast.raw!,
+      medium: MoneroTransactionPriority.regular.raw!,
+      slow: MoneroTransactionPriority.slow.raw!,
+    );
   }
 
   @override
@@ -873,8 +875,9 @@ class WowneroWallet extends CoinServiceAPI {
   Future<int> get maxFee async {
     var bal = await availableBalance;
     var fee = walletBase!.calculateEstimatedFee(
-            wownero.getDefaultTransactionPriority(), bal.toBigInt().toInt()) ~/
-        10000;
+      wownero.getDefaultTransactionPriority(),
+      Format.decimalAmountToSatoshis(bal, coin),
+    );
 
     return fee;
   }
@@ -1446,13 +1449,13 @@ class WowneroWallet extends CoinServiceAPI {
     try {
       final feeRate = args?["feeRate"];
       if (feeRate is FeeRateType) {
-        MoneroTransactionPriority feePriority = MoneroTransactionPriority.slow;
+        MoneroTransactionPriority feePriority;
         switch (feeRate) {
           case FeeRateType.fast:
-            feePriority = MoneroTransactionPriority.fastest;
+            feePriority = MoneroTransactionPriority.fast;
             break;
           case FeeRateType.average:
-            feePriority = MoneroTransactionPriority.medium;
+            feePriority = MoneroTransactionPriority.regular;
             break;
           case FeeRateType.slow:
             feePriority = MoneroTransactionPriority.slow;
@@ -1465,15 +1468,14 @@ class WowneroWallet extends CoinServiceAPI {
           bool isSendAll = false;
           final balance = await availableBalance;
           final satInDecimal = ((Decimal.fromInt(satoshiAmount) /
-                      Decimal.fromInt(Constants.satsPerCoinWownero))
-                  .toDecimal() *
-              Decimal.fromInt(1000));
+                  Decimal.fromInt(Constants.satsPerCoin(coin)))
+              .toDecimal());
           if (satInDecimal == balance) {
             isSendAll = true;
           }
           Logging.instance
               .log("$toAddress $amount $args", level: LogLevel.Info);
-          String amountToSend = wowneroAmountToString(amount: amount * 1000);
+          String amountToSend = wowneroAmountToString(amount: amount);
           Logging.instance.log("$amount $amountToSend", level: LogLevel.Info);
 
           wownero_output.Output output = wownero_output.Output(walletBase!);
@@ -1495,10 +1497,8 @@ class WowneroWallet extends CoinServiceAPI {
 
         PendingWowneroTransaction pendingWowneroTransaction =
             await (awaitPendingTransaction!) as PendingWowneroTransaction;
-        int realfee = (Decimal.parse(pendingWowneroTransaction.feeFormatted) *
-                100000000.toDecimal())
-            .toBigInt()
-            .toInt();
+        int realfee = Format.decimalAmountToSatoshis(
+            Decimal.parse(pendingWowneroTransaction.feeFormatted), coin);
         debugPrint("fee? $realfee");
         Map<String, dynamic> txData = {
           "pendingWowneroTransaction": pendingWowneroTransaction,
@@ -1531,12 +1531,12 @@ class WowneroWallet extends CoinServiceAPI {
 
   @override
   Future<int> estimateFeeFor(int satoshiAmount, int feeRate) async {
-    MoneroTransactionPriority? priority;
+    MoneroTransactionPriority priority;
     FeeRateType feeRateType = FeeRateType.slow;
     switch (feeRate) {
       case 1:
         priority = MoneroTransactionPriority.regular;
-        feeRateType = FeeRateType.slow;
+        feeRateType = FeeRateType.average;
         break;
       case 2:
         priority = MoneroTransactionPriority.medium;
@@ -1544,7 +1544,7 @@ class WowneroWallet extends CoinServiceAPI {
         break;
       case 3:
         priority = MoneroTransactionPriority.fast;
-        feeRateType = FeeRateType.average;
+        feeRateType = FeeRateType.fast;
         break;
       case 4:
         priority = MoneroTransactionPriority.fastest;
@@ -1568,7 +1568,7 @@ class WowneroWallet extends CoinServiceAPI {
               args: {"feeRate": feeRateType}))['fee'];
           await Future.delayed(const Duration(milliseconds: 500));
         } catch (e, s) {
-          aprox = -9999999999999999;
+          aprox = walletBase!.calculateEstimatedFee(priority, satoshiAmount);
         }
       }
     });
diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart
index 0a062de67..3263d526e 100644
--- a/lib/utilities/constants.dart
+++ b/lib/utilities/constants.dart
@@ -23,12 +23,12 @@ abstract class Constants {
   static bool enableExchange = Util.isDesktop || !Platform.isIOS;
 
   //TODO: correct for monero?
-  static const int satsPerCoinMonero = 1000000000000;
-  static const int satsPerCoinWownero = 100000000000;
-  static const int satsPerCoin = 100000000;
-  static const int decimalPlaces = 8;
-  static const int decimalPlacesWownero = 11;
-  static const int decimalPlacesMonero = 12;
+  static const int _satsPerCoinMonero = 1000000000000;
+  static const int _satsPerCoinWownero = 100000000000;
+  static const int _satsPerCoin = 100000000;
+  static const int _decimalPlaces = 8;
+  static const int _decimalPlacesWownero = 11;
+  static const int _decimalPlacesMonero = 12;
 
   static const int notificationsMax = 0xFFFFFFFF;
   static const Duration networkAliveTimerDuration = Duration(seconds: 10);
@@ -40,6 +40,30 @@ abstract class Constants {
 
   static const int currentHiveDbVersion = 3;
 
+  static int satsPerCoin(Coin coin) {
+    switch (coin) {
+      case Coin.bitcoin:
+      case Coin.litecoin:
+      case Coin.litecoinTestNet:
+      case Coin.bitcoincash:
+      case Coin.bitcoincashTestnet:
+      case Coin.dogecoin:
+      case Coin.firo:
+      case Coin.bitcoinTestNet:
+      case Coin.dogecoinTestNet:
+      case Coin.firoTestNet:
+      case Coin.epicCash:
+      case Coin.namecoin:
+        return _satsPerCoin;
+
+      case Coin.wownero:
+        return _satsPerCoinWownero;
+
+      case Coin.monero:
+        return _satsPerCoinMonero;
+    }
+  }
+
   static int decimalPlacesForCoin(Coin coin) {
     switch (coin) {
       case Coin.bitcoin:
@@ -54,13 +78,13 @@ abstract class Constants {
       case Coin.firoTestNet:
       case Coin.epicCash:
       case Coin.namecoin:
-        return decimalPlaces;
+        return _decimalPlaces;
 
       case Coin.wownero:
-        return decimalPlacesWownero;
+        return _decimalPlacesWownero;
 
       case Coin.monero:
-        return decimalPlacesMonero;
+        return _decimalPlacesMonero;
     }
   }
 
diff --git a/lib/utilities/format.dart b/lib/utilities/format.dart
index 775780833..136ec5b95 100644
--- a/lib/utilities/format.dart
+++ b/lib/utilities/format.dart
@@ -8,46 +8,28 @@ import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 abstract class Format {
-  static Decimal satoshisToAmount(int sats, {Coin? coin}) {
-    late final int satsPerCoin;
-
-    switch (coin) {
-      case Coin.wownero:
-        satsPerCoin = Constants.satsPerCoinWownero;
-        break;
-      case Coin.monero:
-        satsPerCoin = Constants.satsPerCoinMonero;
-        break;
-      case Coin.bitcoin:
-      case Coin.bitcoincash:
-      case Coin.dogecoin:
-      case Coin.epicCash:
-      case Coin.firo:
-      case Coin.litecoin:
-      case Coin.namecoin:
-      case Coin.bitcoinTestNet:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincashTestnet:
-      case Coin.dogecoinTestNet:
-      case Coin.firoTestNet:
-      default:
-        satsPerCoin = Constants.satsPerCoin;
-    }
-
-    return (Decimal.fromInt(sats) / Decimal.fromInt(satsPerCoin))
-        .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces);
+  static Decimal satoshisToAmount(int sats, {required Coin coin}) {
+    return (Decimal.fromInt(sats) /
+            Decimal.fromInt(Constants.satsPerCoin(coin)))
+        .toDecimal(
+            scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin));
   }
 
   ///
-  static String satoshiAmountToPrettyString(int sats, String locale) {
-    final amount = satoshisToAmount(sats);
+  static String satoshiAmountToPrettyString(
+      int sats, String locale, Coin coin) {
+    final amount = satoshisToAmount(sats, coin: coin);
     return localizedStringAsFixed(
-        value: amount, locale: locale, decimalPlaces: Constants.decimalPlaces);
+      value: amount,
+      locale: locale,
+      decimalPlaces: Constants.decimalPlacesForCoin(coin),
+    );
   }
 
-  static int decimalAmountToSatoshis(Decimal amount) {
-    final value =
-        (Decimal.fromInt(Constants.satsPerCoin) * amount).floor().toBigInt();
+  static int decimalAmountToSatoshis(Decimal amount, Coin coin) {
+    final value = (Decimal.fromInt(Constants.satsPerCoin(coin)) * amount)
+        .floor()
+        .toBigInt();
     return value.toInt();
   }
 
diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart
index 15dcf2b4d..4389573c3 100644
--- a/lib/widgets/transaction_card.dart
+++ b/lib/widgets/transaction_card.dart
@@ -9,7 +9,6 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_deta
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -198,13 +197,9 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
                               fit: BoxFit.scaleDown,
                               child: Builder(
                                 builder: (_) {
-                                  final amount = coin == Coin.monero
-                                      ? (_transaction.amount ~/ 10000)
-                                      : coin == Coin.wownero
-                                          ? (_transaction.amount ~/ 1000)
-                                          : _transaction.amount;
+                                  final amount = _transaction.amount;
                                   return Text(
-                                    "$prefix${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}",
+                                    "$prefix${Format.satoshiAmountToPrettyString(amount, locale, coin)} ${coin.ticker}",
                                     style:
                                         STextStyles.itemSubtitle12_600(context),
                                   );
@@ -242,17 +237,12 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
                                 fit: BoxFit.scaleDown,
                                 child: Builder(
                                   builder: (_) {
-                                    // TODO: modify Format.<functions> to take optional Coin parameter so this type oif check isn't done in ui
                                     int value = _transaction.amount;
-                                    if (coin == Coin.monero) {
-                                      value = (value ~/ 10000);
-                                    } else if (coin == Coin.wownero) {
-                                      value = (value ~/ 1000);
-                                    }
 
                                     return Text(
                                       "$prefix${Format.localizedStringAsFixed(
-                                        value: Format.satoshisToAmount(value) *
+                                        value: Format.satoshisToAmount(value,
+                                                coin: coin) *
                                             price,
                                         locale: locale,
                                         decimalPlaces: 2,

From ffe9a83abf170b7082a24f030b5219daefe9d203 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 23 Nov 2022 12:38:36 -0600
Subject: [PATCH 396/426] Format tests updated

---
 test/formet_test.dart | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/test/formet_test.dart b/test/formet_test.dart
index 4f7136cd4..e27293114 100644
--- a/test/formet_test.dart
+++ b/test/formet_test.dart
@@ -1,54 +1,64 @@
 import 'package:decimal/decimal.dart';
 import 'package:flutter_test/flutter_test.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 
 void main() {
   group("satoshisToAmount", () {
     test("12345", () {
-      expect(Format.satoshisToAmount(12345), Decimal.parse("0.00012345"));
+      expect(Format.satoshisToAmount(12345, coin: Coin.bitcoin),
+          Decimal.parse("0.00012345"));
     });
 
     test("100012345", () {
-      expect(Format.satoshisToAmount(100012345), Decimal.parse("1.00012345"));
+      expect(Format.satoshisToAmount(100012345, coin: Coin.bitcoin),
+          Decimal.parse("1.00012345"));
     });
 
     test("0", () {
-      expect(Format.satoshisToAmount(0), Decimal.zero);
+      expect(Format.satoshisToAmount(0, coin: Coin.bitcoin), Decimal.zero);
     });
 
     test("1000000000", () {
-      expect(Format.satoshisToAmount(1000000000), Decimal.parse("10"));
+      expect(Format.satoshisToAmount(1000000000, coin: Coin.bitcoin),
+          Decimal.parse("10"));
     });
   });
 
   group("satoshiAmountToPrettyString", () {
     const locale = "en_US";
     test("12345", () {
-      expect(Format.satoshiAmountToPrettyString(12345, locale), "0.00012345");
+      expect(Format.satoshiAmountToPrettyString(12345, locale, Coin.bitcoin),
+          "0.00012345");
     });
 
     test("100012345", () {
       expect(
-          Format.satoshiAmountToPrettyString(100012345, locale), "1.00012345");
+          Format.satoshiAmountToPrettyString(100012345, locale, Coin.bitcoin),
+          "1.00012345");
     });
 
     test("123450000", () {
       expect(
-          Format.satoshiAmountToPrettyString(123450000, locale), "1.23450000");
+          Format.satoshiAmountToPrettyString(123450000, locale, Coin.bitcoin),
+          "1.23450000");
     });
 
     test("1230045000", () {
-      expect(Format.satoshiAmountToPrettyString(1230045000, locale),
+      expect(
+          Format.satoshiAmountToPrettyString(1230045000, locale, Coin.bitcoin),
           "12.30045000");
     });
 
     test("1000000000", () {
-      expect(Format.satoshiAmountToPrettyString(1000000000, locale),
+      expect(
+          Format.satoshiAmountToPrettyString(1000000000, locale, Coin.bitcoin),
           "10.00000000");
     });
 
     test("0", () {
-      expect(Format.satoshiAmountToPrettyString(0, locale), "0.00000000");
+      expect(Format.satoshiAmountToPrettyString(0, locale, Coin.bitcoin),
+          "0.00000000");
     });
   });
 

From 85b9fdc2f3c07f353166deb2a087bbf52ca50ef4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 23 Nov 2022 12:42:08 -0600
Subject: [PATCH 397/426] random hardcoded values :/

---
 lib/services/coins/monero/monero_wallet.dart   | 6 +++---
 lib/services/coins/wownero/wownero_wallet.dart | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart
index 58bd36c72..6f1e49ee5 100644
--- a/lib/services/coins/monero/monero_wallet.dart
+++ b/lib/services/coins/monero/monero_wallet.dart
@@ -564,11 +564,11 @@ class MoneroWallet extends CoinServiceAPI {
   Future<String>? _currentReceivingAddress;
 
   Future<FeeObject> _getFees() async {
-    // TODO: not use hard coded values here
+    // TODO: not use random hard coded values here
     return FeeObject(
       numberOfBlocksFast: 10,
-      numberOfBlocksAverage: 10,
-      numberOfBlocksSlow: 10,
+      numberOfBlocksAverage: 15,
+      numberOfBlocksSlow: 20,
       fast: MoneroTransactionPriority.fast.raw!,
       medium: MoneroTransactionPriority.regular.raw!,
       slow: MoneroTransactionPriority.slow.raw!,
diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart
index 686dcd08c..72580ea4a 100644
--- a/lib/services/coins/wownero/wownero_wallet.dart
+++ b/lib/services/coins/wownero/wownero_wallet.dart
@@ -563,11 +563,11 @@ class WowneroWallet extends CoinServiceAPI {
   Future<String>? _currentReceivingAddress;
 
   Future<FeeObject> _getFees() async {
-    // TODO: not use hard coded values here
+    // TODO: not use random hard coded values here
     return FeeObject(
       numberOfBlocksFast: 10,
-      numberOfBlocksAverage: 10,
-      numberOfBlocksSlow: 10,
+      numberOfBlocksAverage: 15,
+      numberOfBlocksSlow: 20,
       fast: MoneroTransactionPriority.fast.raw!,
       medium: MoneroTransactionPriority.regular.raw!,
       slow: MoneroTransactionPriority.slow.raw!,

From d14593407df61ebf656028bc88985fa0e27172ad Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Wed, 23 Nov 2022 17:48:58 -0700
Subject: [PATCH 398/426] v1.5.19 build 91

---
 pubspec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index f79879f61..7ca368d29 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.18+90
+version: 1.5.19+91
 
 environment:
   sdk: ">=2.17.0 <3.0.0"

From 08c6fb72ac8fe2cd4eed91c403d83be65459e874 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Wed, 23 Nov 2022 14:55:04 -0600
Subject: [PATCH 399/426] mobile confirm send button height fix

---
 lib/pages/send_view/confirm_transaction_view.dart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index 1ddeb3c9f..fd5341dd9 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -780,7 +780,7 @@ class _ConfirmTransactionViewState
                   : const EdgeInsets.all(0),
               child: PrimaryButton(
                 label: "Send",
-                buttonHeight: ButtonHeight.l,
+                buttonHeight: isDesktop ? ButtonHeight.l : null,
                 onPressed: () async {
                   final dynamic unlocked;
 

From 3bda6620efdb24210667d207cd151c7b601e6142 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 24 Nov 2022 18:07:17 -0600
Subject: [PATCH 400/426] reduce minimum height and set starting height lower
 on linux

---
 lib/main.dart           | 2 +-
 linux/my_application.cc | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/main.dart b/lib/main.dart
index 728152951..11a851b79 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -77,7 +77,7 @@ void main() async {
 
   if (Util.isDesktop) {
     setWindowTitle('Stack Wallet');
-    setWindowMinSize(const Size(1220, 900));
+    setWindowMinSize(const Size(1220, 100));
     setWindowMaxSize(Size.infinite);
   }
 
diff --git a/linux/my_application.cc b/linux/my_application.cc
index 9cb3acebd..d342c1506 100644
--- a/linux/my_application.cc
+++ b/linux/my_application.cc
@@ -47,7 +47,7 @@ static void my_application_activate(GApplication* application) {
     gtk_window_set_title(window, "Stack Wallet");
   }
 
-  gtk_window_set_default_size(window, 1220, 900);
+  gtk_window_set_default_size(window, 1220, 500);
   gtk_widget_show(GTK_WIDGET(window));
 
   g_autoptr(FlDartProject) project = fl_dart_project_new();

From 286f6a552b07294ad9f4d6795f74e7d834162376 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 24 Nov 2022 18:16:26 -0600
Subject: [PATCH 401/426] desktop send to coin ticker fixed

---
 .../exchange_view/confirm_change_now_send.dart     | 11 ++++++++---
 lib/pages/send_view/confirm_transaction_view.dart  | 13 ++++++++++---
 .../wallet_view/sub_widgets/desktop_auth_send.dart | 14 +++++++++-----
 3 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index 0e1eef755..810ea2541 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -157,6 +157,9 @@ class _ConfirmChangeNowSendViewState
   Future<void> _confirmSend() async {
     final dynamic unlocked;
 
+    final coin =
+        ref.read(walletsChangeNotifierProvider).getManager(walletId).coin;
+
     if (Util.isDesktop) {
       unlocked = await showDialog<bool?>(
         context: context,
@@ -172,13 +175,15 @@ class _ConfirmChangeNowSendViewState
                   DesktopDialogCloseButton(),
                 ],
               ),
-              const Padding(
-                padding: EdgeInsets.only(
+              Padding(
+                padding: const EdgeInsets.only(
                   left: 32,
                   right: 32,
                   bottom: 32,
                 ),
-                child: DesktopAuthSend(),
+                child: DesktopAuthSend(
+                  coin: coin,
+                ),
               ),
             ],
           ),
diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index fd5341dd9..16de6cf55 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -784,6 +784,11 @@ class _ConfirmTransactionViewState
                 onPressed: () async {
                   final dynamic unlocked;
 
+                  final coin = ref
+                      .read(walletsChangeNotifierProvider)
+                      .getManager(walletId)
+                      .coin;
+
                   if (isDesktop) {
                     unlocked = await showDialog<bool?>(
                       context: context,
@@ -799,13 +804,15 @@ class _ConfirmTransactionViewState
                                 DesktopDialogCloseButton(),
                               ],
                             ),
-                            const Padding(
-                              padding: EdgeInsets.only(
+                            Padding(
+                              padding: const EdgeInsets.only(
                                 left: 32,
                                 right: 32,
                                 bottom: 32,
                               ),
-                              child: DesktopAuthSend(),
+                              child: DesktopAuthSend(
+                                coin: coin,
+                              ),
                             ),
                           ],
                         ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
index a8d1ea497..20bb3f95a 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
@@ -6,17 +6,21 @@ import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 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/stack_text_field.dart';
 
-import '../../../../../notifications/show_flush_bar.dart';
-import '../../../../../widgets/loading_indicator.dart';
-
 class DesktopAuthSend extends ConsumerStatefulWidget {
-  const DesktopAuthSend({Key? key}) : super(key: key);
+  const DesktopAuthSend({
+    Key? key,
+    required this.coin,
+  }) : super(key: key);
+
+  final Coin coin;
 
   @override
   ConsumerState<DesktopAuthSend> createState() => _DesktopAuthSendState();
@@ -72,7 +76,7 @@ class _DesktopAuthSendState extends ConsumerState<DesktopAuthSend> {
           height: 16,
         ),
         Text(
-          "Enter your wallet password to send BTC",
+          "Enter your wallet password to send ${widget.coin.ticker.toUpperCase()}",
           style: STextStyles.desktopTextMedium(context).copyWith(
             color: Theme.of(context).extension<StackColors>()!.textDark3,
           ),

From d71899d1dff48ded1ec45d02abb3c88a0b1c37c8 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Thu, 24 Nov 2022 18:22:35 -0600
Subject: [PATCH 402/426] mobile exchange form top padding added

---
 lib/pages/exchange_view/exchange_view.dart | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/pages/exchange_view/exchange_view.dart b/lib/pages/exchange_view/exchange_view.dart
index 84e054eac..ed99047b2 100644
--- a/lib/pages/exchange_view/exchange_view.dart
+++ b/lib/pages/exchange_view/exchange_view.dart
@@ -43,7 +43,11 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
               handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
               sliver: const SliverToBoxAdapter(
                 child: Padding(
-                  padding: EdgeInsets.symmetric(horizontal: 16),
+                  padding: EdgeInsets.only(
+                    left: 16,
+                    right: 16,
+                    top: 16,
+                  ),
                   child: ExchangeForm(),
                 ),
               ),

From 7db3abab473af403c156d26be580713e3d1e4a4f Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 25 Nov 2022 09:01:09 -0600
Subject: [PATCH 403/426] desktop starting to height be 3/4 screen height or
 900, whichever is smaller

---
 lib/main.dart | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lib/main.dart b/lib/main.dart
index 11a851b79..d5980409f 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,5 +1,6 @@
 import 'dart:async';
 import 'dart:io';
+import 'dart:math';
 
 import 'package:cw_core/node.dart';
 import 'package:cw_core/unspent_coins_info.dart';
@@ -79,6 +80,15 @@ void main() async {
     setWindowTitle('Stack Wallet');
     setWindowMinSize(const Size(1220, 100));
     setWindowMaxSize(Size.infinite);
+    final screen = await getCurrentScreen();
+    final screenHeight = screen?.frame.height;
+    if (screenHeight != null) {
+      // starting to height be 3/4 screen height or 900, whichever is smaller
+      final height = min<double>(screenHeight * 0.75, 900);
+      setWindowFrame(
+        Rect.fromLTWH(0, 0, 1220, height),
+      );
+    }
   }
 
   // FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);

From 42aad5dcd53c9367ffd9f6672299b81b29af8f8a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 25 Nov 2022 13:24:01 -0600
Subject: [PATCH 404/426] themed background gradient option and background
 image, as well as various button height fixes for mobile

---
 assets/svg/oceanBreeze/bg.svg                 |   11 +
 .../add_wallet_view/add_wallet_view.dart      |   67 +-
 .../create_or_restore_wallet_view.dart        |   83 +-
 .../name_your_wallet_view.dart                |   65 +-
 .../new_wallet_recovery_phrase_view.dart      |    1 -
 .../address_book_views/address_book_view.dart |  184 +-
 .../subviews/add_address_book_entry_view.dart |  115 +-
 .../add_new_contact_address_view.dart         |   80 +-
 .../subviews/address_book_filter_view.dart    |   97 +-
 .../subviews/contact_details_view.dart        |  764 ++---
 .../subviews/edit_contact_address_view.dart   |   80 +-
 .../edit_contact_name_emoji_view.dart         |   80 +-
 .../exchange_view/choose_from_stack_view.dart |  154 +-
 .../confirm_change_now_send.dart              |   77 +-
 .../exchange_view/edit_trade_note_view.dart   |  190 +-
 .../fixed_rate_pair_coin_selection_view.dart  |   50 +-
 ...floating_rate_currency_selection_view.dart |   50 +-
 .../exchange_step_views/step_1_view.dart      |  304 +-
 .../exchange_step_views/step_2_view.dart      | 1077 +++----
 .../exchange_step_views/step_3_view.dart      |  522 ++--
 .../exchange_step_views/step_4_view.dart      | 1034 +++----
 lib/pages/exchange_view/send_from_view.dart   |   33 +-
 .../exchange_view/trade_details_view.dart     |   40 +-
 .../wallet_initiated_exchange_view.dart       |  131 +-
 lib/pages/home_view/home_view.dart            |  232 +-
 lib/pages/intro_view.dart                     |  193 +-
 lib/pages/loading_view.dart                   |   37 +-
 .../notifications_view.dart                   |  113 +-
 lib/pages/pinpad_views/create_pin_view.dart   |  403 +--
 lib/pages/pinpad_views/lock_screen_view.dart  |  299 +-
 .../generate_receiving_uri_qr_code_view.dart  |   87 +-
 lib/pages/receive_view/receive_view.dart      |  266 +-
 .../send_view/confirm_transaction_view.dart   |   76 +-
 lib/pages/send_view/send_view.dart            | 2567 +++++++++--------
 .../global_settings_view/about_view.dart      |  802 ++---
 .../advanced_settings_view.dart               |  289 +-
 .../advanced_views/debug_view.dart            |  869 +++---
 .../appearance_settings_view.dart             |  223 +-
 .../global_settings_view/currency_view.dart   |   54 +-
 .../global_settings_view.dart                 |  478 +--
 .../global_settings_view/hidden_settings.dart |  270 +-
 .../global_settings_view/language_view.dart   |  368 +--
 .../add_edit_node_view.dart                   |  160 +-
 .../manage_nodes_views/coin_nodes_view.dart   |  117 +-
 .../manage_nodes_views/manage_nodes_view.dart |  156 +-
 .../manage_nodes_views/node_details_view.dart |  147 +-
 .../change_pin_view/change_pin_view.dart      |  335 +--
 .../security_views/security_view.dart         |  226 +-
 .../stack_backup_views/auto_backup_view.dart  |  450 +--
 .../create_auto_backup_view.dart              | 1051 +++----
 .../create_backup_information_view.dart       |  129 +-
 .../create_backup_view.dart                   |   70 +-
 .../edit_auto_backup_view.dart                |   54 +-
 .../restore_from_encrypted_string_view.dart   |  365 +--
 .../restore_from_file_view.dart               |   71 +-
 .../stack_backup_views/stack_backup_view.dart |  259 +-
 .../startup_preferences_view.dart             |  463 +--
 .../startup_wallet_selection_view.dart        |  308 +-
 .../global_settings_view/support_view.dart    |   33 +-
 .../syncing_options_view.dart                 |   57 +-
 .../syncing_preferences_view.dart             |  240 +-
 .../wallet_syncing_options_view.dart          |   45 +-
 .../wallet_backup_view.dart                   |  333 +--
 .../wallet_network_settings_view.dart         |  209 +-
 .../wallet_settings_view.dart                 |  370 +--
 .../delete_wallet_recovery_phrase_view.dart   |  308 +-
 .../delete_wallet_warning_view.dart           |  162 +-
 .../rename_wallet_view.dart                   |  186 +-
 .../wallet_settings_wallet_settings_view.dart |  275 +-
 .../transaction_views/edit_note_view.dart     |  271 +-
 .../transaction_details_view.dart             | 1962 ++++++-------
 .../transaction_search_filter_view.dart       |   73 +-
 lib/pages/wallet_view/wallet_view.dart        |  737 ++---
 .../desktop_login_view.dart                   |    1 -
 .../home/desktop_home_view.dart               |   33 +-
 .../home/my_stack_view/my_stack_view.dart     |   59 +-
 lib/utilities/assets.dart                     |   11 +
 lib/utilities/theme/color_theme.dart          |    7 +-
 lib/utilities/theme/dark_colors.dart          |    5 +
 lib/utilities/theme/light_colors.dart         |    5 +
 lib/utilities/theme/ocean_breeze_colors.dart  |   14 +-
 lib/utilities/theme/stack_colors.dart         |   17 +
 lib/widgets/background.dart                   |   67 +
 lib/widgets/desktop/desktop_scaffold.dart     |   36 +-
 pubspec.yaml                                  |    1 +
 85 files changed, 11664 insertions(+), 11129 deletions(-)
 create mode 100644 assets/svg/oceanBreeze/bg.svg
 create mode 100644 lib/widgets/background.dart

diff --git a/assets/svg/oceanBreeze/bg.svg b/assets/svg/oceanBreeze/bg.svg
new file mode 100644
index 000000000..35fbda281
--- /dev/null
+++ b/assets/svg/oceanBreeze/bg.svg
@@ -0,0 +1,11 @@
+<svg width="360" height="480" viewBox="0 0 360 480" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M48 174.503C45.4098 171.437 39.6642 169.267 34.578 176.625C29.4917 183.983 22.3192 180.197 19.7431 176.625C16.682 172.38 8.86422 166.438 2.08257 176.625C-0.507645 179.926 -7.2422 184.549 -13.4587 176.625C-19.6752 168.702 -26.4098 171.909 -29 174.503" stroke="#D3EAF3" stroke-width="2" stroke-linecap="round"/>
+<path d="M48 188.503C45.4098 185.437 39.6642 183.267 34.578 190.625C29.4917 197.983 22.3192 194.197 19.7431 190.625C16.682 186.38 8.86422 180.438 2.08257 190.625C-0.507645 193.926 -7.2422 198.549 -13.4587 190.625C-19.6752 182.702 -26.4098 185.909 -29 188.503" stroke="#D3EAF3" stroke-width="2" stroke-linecap="round"/>
+<path d="M48 202.503C45.4098 199.437 39.6642 197.267 34.578 204.625C29.4917 211.983 22.3192 208.197 19.7431 204.625C16.682 200.38 8.86422 194.438 2.08257 204.625C-0.507645 207.926 -7.2422 212.549 -13.4587 204.625C-19.6752 196.702 -26.4098 199.909 -29 202.503" stroke="#D3EAF3" stroke-width="2" stroke-linecap="round"/>
+<path d="M389 444.503C386.41 441.437 380.664 439.267 375.578 446.625C370.492 453.983 363.319 450.197 360.743 446.625C357.682 442.38 349.864 436.438 343.083 446.625C340.492 449.926 333.758 454.549 327.541 446.625C321.325 438.702 314.59 441.909 312 444.503" stroke="#D3EAF3" stroke-width="2" stroke-linecap="round"/>
+<path d="M389 458.503C386.41 455.437 380.664 453.267 375.578 460.625C370.492 467.983 363.319 464.197 360.743 460.625C357.682 456.38 349.864 450.438 343.083 460.625C340.492 463.926 333.758 468.549 327.541 460.625C321.325 452.702 314.59 455.909 312 458.503" stroke="#D3EAF3" stroke-width="2" stroke-linecap="round"/>
+<path d="M389 472.503C386.41 469.437 380.664 467.267 375.578 474.625C370.492 481.983 363.319 478.197 360.743 474.625C357.682 470.38 349.864 464.438 343.083 474.625C340.492 477.926 333.758 482.549 327.541 474.625C321.325 466.702 314.59 469.909 312 472.503" stroke="#D3EAF3" stroke-width="2" stroke-linecap="round"/>
+<path d="M389 4.5028C386.41 1.4371 380.664 -0.732664 375.578 6.62502C370.492 13.9827 363.319 10.1971 360.743 6.62502C357.682 2.38025 349.864 -3.56244 343.083 6.62502C340.492 9.92648 333.758 14.5485 327.541 6.62502C321.325 -1.29849 314.59 1.90875 312 4.5028" stroke="#D3EAF3" stroke-width="2" stroke-linecap="round"/>
+<path d="M389 18.5028C386.41 15.4371 380.664 13.2673 375.578 20.625C370.492 27.9827 363.319 24.1971 360.743 20.625C357.682 16.3802 349.864 10.4376 343.083 20.625C340.492 23.9265 333.758 28.5485 327.541 20.625C321.325 12.7015 314.59 15.9087 312 18.5028" stroke="#D3EAF3" stroke-width="2" stroke-linecap="round"/>
+<path d="M389 32.5028C386.41 29.4371 380.664 27.2673 375.578 34.625C370.492 41.9827 363.319 38.1971 360.743 34.625C357.682 30.3802 349.864 24.4376 343.083 34.625C340.492 37.9265 333.758 42.5485 327.541 34.625C321.325 26.7015 314.59 29.9087 312 32.5028" stroke="#D3EAF3" stroke-width="2" stroke-linecap="round"/>
+</svg>
diff --git a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
index e964610ae..29bae26c1 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
@@ -11,6 +11,7 @@ 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/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
@@ -182,39 +183,43 @@ class _AddWalletViewState extends State<AddWalletView> {
         ),
       );
     } else {
-      return Scaffold(
-        appBar: AppBar(
-          leading: AppBarBackButton(
-            onPressed: () {
-              Navigator.of(context).pop();
-            },
+      return Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
+            ),
           ),
-        ),
-        body: Container(
-          color: Theme.of(context).extension<StackColors>()!.background,
-          child: Padding(
-            padding: const EdgeInsets.all(16),
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.stretch,
-              children: [
-                const AddWalletText(
-                  isDesktop: false,
-                ),
-                const SizedBox(
-                  height: 16,
-                ),
-                Expanded(
-                  child: MobileCoinList(
-                    coins: coins,
+          body: Container(
+            color: Theme.of(context).extension<StackColors>()!.background,
+            child: Padding(
+              padding: const EdgeInsets.all(16),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: [
+                  const AddWalletText(
+                    isDesktop: false,
                   ),
-                ),
-                const SizedBox(
-                  height: 16,
-                ),
-                const AddWalletNextButton(
-                  isDesktop: false,
-                ),
-              ],
+                  const SizedBox(
+                    height: 16,
+                  ),
+                  Expanded(
+                    child: MobileCoinList(
+                      coins: coins,
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 16,
+                  ),
+                  const AddWalletNextButton(
+                    isDesktop: false,
+                  ),
+                ],
+              ),
             ),
           ),
         ),
diff --git a/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart b/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart
index b3be99e25..1dfdc2a53 100644
--- a/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my
 import 'package:stackwallet/utilities/enums/coin_enum.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
@@ -77,49 +78,53 @@ class CreateOrRestoreWalletView extends StatelessWidget {
         ),
       );
     } else {
-      return Scaffold(
-        appBar: AppBar(
-          leading: AppBarBackButton(
-            onPressed: () {
-              Navigator.of(context).pop();
-            },
+      return Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
+            ),
           ),
-        ),
-        body: Container(
-          color: Theme.of(context).extension<StackColors>()!.background,
-          child: Padding(
-            padding: const EdgeInsets.all(16),
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.stretch,
-              children: [
-                Padding(
-                  padding: const EdgeInsets.all(31),
-                  child: CoinImage(
+          body: Container(
+            color: Theme.of(context).extension<StackColors>()!.background,
+            child: Padding(
+              padding: const EdgeInsets.all(16),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: [
+                  Padding(
+                    padding: const EdgeInsets.all(31),
+                    child: CoinImage(
+                      coin: coin,
+                      isDesktop: isDesktop,
+                    ),
+                  ),
+                  const Spacer(
+                    flex: 2,
+                  ),
+                  CreateRestoreWalletTitle(
                     coin: coin,
                     isDesktop: isDesktop,
                   ),
-                ),
-                const Spacer(
-                  flex: 2,
-                ),
-                CreateRestoreWalletTitle(
-                  coin: coin,
-                  isDesktop: isDesktop,
-                ),
-                const SizedBox(
-                  height: 8,
-                ),
-                CreateRestoreWalletSubTitle(
-                  isDesktop: isDesktop,
-                ),
-                const Spacer(
-                  flex: 5,
-                ),
-                CreateWalletButtonGroup(
-                  coin: coin,
-                  isDesktop: isDesktop,
-                ),
-              ],
+                  const SizedBox(
+                    height: 8,
+                  ),
+                  CreateRestoreWalletSubTitle(
+                    isDesktop: isDesktop,
+                  ),
+                  const Spacer(
+                    flex: 5,
+                  ),
+                  CreateWalletButtonGroup(
+                    coin: coin,
+                    isDesktop: isDesktop,
+                  ),
+                ],
+              ),
             ),
           ),
         ),
diff --git a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
index 8bc01b124..e435e285d 100644
--- a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
+++ b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
@@ -17,6 +17,7 @@ import 'package:stackwallet/utilities/name_generator.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
@@ -108,40 +109,44 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
         ),
       );
     } else {
-      return Scaffold(
-        appBar: AppBar(
-          leading: AppBarBackButton(
-            onPressed: () {
-              if (textFieldFocusNode.hasFocus) {
-                textFieldFocusNode.unfocus();
-                Future<void>.delayed(const Duration(milliseconds: 100))
-                    .then((value) => Navigator.of(context).pop());
-              } else {
-                if (mounted) {
-                  Navigator.of(context).pop();
+      return Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                if (textFieldFocusNode.hasFocus) {
+                  textFieldFocusNode.unfocus();
+                  Future<void>.delayed(const Duration(milliseconds: 100))
+                      .then((value) => Navigator.of(context).pop());
+                } else {
+                  if (mounted) {
+                    Navigator.of(context).pop();
+                  }
                 }
-              }
-            },
-          ),
-        ),
-        body: Container(
-          color: Theme.of(context).extension<StackColors>()!.background,
-          child: Padding(
-            padding: const EdgeInsets.all(16),
-            child: LayoutBuilder(
-              builder: (ctx, constraints) {
-                return SingleChildScrollView(
-                  child: ConstrainedBox(
-                    constraints:
-                        BoxConstraints(minHeight: constraints.maxHeight),
-                    child: IntrinsicHeight(
-                      child: _content(),
-                    ),
-                  ),
-                );
               },
             ),
           ),
+          body: Container(
+            color: Theme.of(context).extension<StackColors>()!.background,
+            child: Padding(
+              padding: const EdgeInsets.all(16),
+              child: LayoutBuilder(
+                builder: (ctx, constraints) {
+                  return SingleChildScrollView(
+                    child: ConstrainedBox(
+                      constraints:
+                          BoxConstraints(minHeight: constraints.maxHeight),
+                      child: IntrinsicHeight(
+                        child: _content(),
+                      ),
+                    ),
+                  );
+                },
+              ),
+            ),
+          ),
         ),
       );
     }
diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart
index faab6d08c..b3ceb0968 100644
--- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart
+++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart
@@ -16,7 +16,6 @@ import 'package:stackwallet/services/coins/manager.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/flush_bar_type.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index c87906870..0fbf334a7 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -15,6 +15,7 @@ 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/address_book_card.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/icon_widgets/x_icon.dart';
@@ -108,110 +109,115 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            leading: AppBarBackButton(
-              onPressed: () {
-                Navigator.of(context).pop();
-              },
-            ),
-            title: Text(
-              "Address book",
-              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("addressBookFilterViewButton"),
-                    size: 36,
-                    shadows: const [],
-                    color:
-                        Theme.of(context).extension<StackColors>()!.background,
-                    icon: SvgPicture.asset(
-                      Assets.svg.filter,
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              leading: AppBarBackButton(
+                onPressed: () {
+                  Navigator.of(context).pop();
+                },
+              ),
+              title: Text(
+                "Address book",
+                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("addressBookFilterViewButton"),
+                      size: 36,
+                      shadows: const [],
                       color: Theme.of(context)
                           .extension<StackColors>()!
-                          .accentColorDark,
-                      width: 20,
-                      height: 20,
+                          .background,
+                      icon: SvgPicture.asset(
+                        Assets.svg.filter,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark,
+                        width: 20,
+                        height: 20,
+                      ),
+                      onPressed: () {
+                        Navigator.of(context).pushNamed(
+                          AddressBookFilterView.routeName,
+                        );
+                      },
                     ),
-                    onPressed: () {
-                      Navigator.of(context).pushNamed(
-                        AddressBookFilterView.routeName,
-                      );
-                    },
                   ),
                 ),
-              ),
-              Padding(
-                padding: const EdgeInsets.only(
-                  top: 10,
-                  bottom: 10,
-                  right: 10,
-                ),
-                child: AspectRatio(
-                  aspectRatio: 1,
-                  child: AppBarIconButton(
-                    key: const Key("addressBookAddNewContactViewButton"),
-                    size: 36,
-                    shadows: const [],
-                    color:
-                        Theme.of(context).extension<StackColors>()!.background,
-                    icon: SvgPicture.asset(
-                      Assets.svg.plus,
+                Padding(
+                  padding: const EdgeInsets.only(
+                    top: 10,
+                    bottom: 10,
+                    right: 10,
+                  ),
+                  child: AspectRatio(
+                    aspectRatio: 1,
+                    child: AppBarIconButton(
+                      key: const Key("addressBookAddNewContactViewButton"),
+                      size: 36,
+                      shadows: const [],
                       color: Theme.of(context)
                           .extension<StackColors>()!
-                          .accentColorDark,
-                      width: 20,
-                      height: 20,
+                          .background,
+                      icon: SvgPicture.asset(
+                        Assets.svg.plus,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark,
+                        width: 20,
+                        height: 20,
+                      ),
+                      onPressed: () {
+                        Navigator.of(context).pushNamed(
+                          AddAddressBookEntryView.routeName,
+                        );
+                      },
                     ),
-                    onPressed: () {
-                      Navigator.of(context).pushNamed(
-                        AddAddressBookEntryView.routeName,
-                      );
-                    },
                   ),
                 ),
-              ),
-            ],
-          ),
-          body: LayoutBuilder(
-            builder: (builderContext, constraints) {
-              return Padding(
-                padding: const EdgeInsets.only(
-                  left: 12,
-                  top: 12,
-                  right: 12,
-                ),
-                child: SingleChildScrollView(
-                  child: ConstrainedBox(
-                    constraints: BoxConstraints(
-                      minHeight: constraints.maxHeight - 24,
-                    ),
-                    child: IntrinsicHeight(
-                      child: Padding(
-                        padding: const EdgeInsets.all(4),
-                        child: ConstrainedBox(
-                          constraints: BoxConstraints(
-                            minHeight: MediaQuery.of(context).size.height - 271,
+              ],
+            ),
+            body: LayoutBuilder(
+              builder: (builderContext, constraints) {
+                return Padding(
+                  padding: const EdgeInsets.only(
+                    left: 12,
+                    top: 12,
+                    right: 12,
+                  ),
+                  child: SingleChildScrollView(
+                    child: ConstrainedBox(
+                      constraints: BoxConstraints(
+                        minHeight: constraints.maxHeight - 24,
+                      ),
+                      child: IntrinsicHeight(
+                        child: Padding(
+                          padding: const EdgeInsets.all(4),
+                          child: ConstrainedBox(
+                            constraints: BoxConstraints(
+                              minHeight:
+                                  MediaQuery.of(context).size.height - 271,
+                            ),
+                            child: child,
                           ),
-                          child: child,
                         ),
                       ),
                     ),
                   ),
-                ),
-              );
-            },
+                );
+              },
+            ),
           ),
         );
       },
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 2759e9cb1..36191e0b7 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
@@ -16,6 +16,7 @@ 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/custom_buttons/blue_text_button.dart';
@@ -116,65 +117,67 @@ class _AddAddressBookEntryViewState
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-            backgroundColor:
-                Theme.of(context).extension<StackColors>()!.background,
-            appBar: AppBar(
-              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(
-                "New contact",
-                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("addAddressBookEntryFavoriteButtonKey"),
-                      size: 36,
-                      shadows: const [],
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .background,
-                      icon: SvgPicture.asset(
-                        Assets.svg.star,
-                        color: _isFavorite
-                            ? Theme.of(context)
-                                .extension<StackColors>()!
-                                .favoriteStarActive
-                            : Theme.of(context)
-                                .extension<StackColors>()!
-                                .favoriteStarInactive,
-                        width: 20,
-                        height: 20,
+        return Background(
+          child: Scaffold(
+              backgroundColor:
+                  Theme.of(context).extension<StackColors>()!.background,
+              appBar: AppBar(
+                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(
+                  "New contact",
+                  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("addAddressBookEntryFavoriteButtonKey"),
+                        size: 36,
+                        shadows: const [],
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .background,
+                        icon: SvgPicture.asset(
+                          Assets.svg.star,
+                          color: _isFavorite
+                              ? Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .favoriteStarActive
+                              : Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .favoriteStarInactive,
+                          width: 20,
+                          height: 20,
+                        ),
+                        onPressed: () {
+                          setState(() {
+                            _isFavorite = !_isFavorite;
+                          });
+                        },
                       ),
-                      onPressed: () {
-                        setState(() {
-                          _isFavorite = !_isFavorite;
-                        });
-                      },
                     ),
                   ),
-                ),
-              ],
-            ),
-            body: child);
+                ],
+              ),
+              body: child),
+        );
       },
       child: ConditionalParent(
         condition: isDesktop,
diff --git a/lib/pages/address_book_views/subviews/add_new_contact_address_view.dart b/lib/pages/address_book_views/subviews/add_new_contact_address_view.dart
index dc25c3dc1..de2dfe90c 100644
--- a/lib/pages/address_book_views/subviews/add_new_contact_address_view.dart
+++ b/lib/pages/address_book_views/subviews/add_new_contact_address_view.dart
@@ -13,6 +13,7 @@ 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/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/primary_button.dart';
@@ -63,48 +64,51 @@ class _AddNewContactAddressViewState
 
     return ConditionalParent(
       condition: !isDesktop,
-      builder: (child) => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          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();
-              }
-            },
+      builder: (child) => Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            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(
+              "Add new address",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
-          title: Text(
-            "Add new address",
-            style: STextStyles.navBarTitle(context),
-          ),
-        ),
-        body: LayoutBuilder(
-          builder: (context, constraints) {
-            return Padding(
-              padding: const EdgeInsets.only(
-                left: 12,
-                top: 12,
-                right: 12,
-              ),
-              child: SingleChildScrollView(
-                child: ConstrainedBox(
-                  constraints: BoxConstraints(
-                    minHeight: constraints.maxHeight - 24,
-                  ),
-                  child: IntrinsicHeight(
-                    child: Padding(
-                      padding: const EdgeInsets.all(4),
-                      child: child,
+          body: LayoutBuilder(
+            builder: (context, constraints) {
+              return Padding(
+                padding: const EdgeInsets.only(
+                  left: 12,
+                  top: 12,
+                  right: 12,
+                ),
+                child: SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight - 24,
+                    ),
+                    child: IntrinsicHeight(
+                      child: Padding(
+                        padding: const EdgeInsets.all(4),
+                        child: child,
+                      ),
                     ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
       child: Column(
diff --git a/lib/pages/address_book_views/subviews/address_book_filter_view.dart b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
index 55c3d47ac..9f410aae7 100644
--- a/lib/pages/address_book_views/subviews/address_book_filter_view.dart
+++ b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
@@ -6,6 +6,7 @@ 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/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';
@@ -50,60 +51,62 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
+        return Background(
+          child: Scaffold(
             backgroundColor:
                 Theme.of(context).extension<StackColors>()!.background,
-            leading: AppBarBackButton(
-              onPressed: () async {
-                Navigator.of(context).pop();
-              },
+            appBar: AppBar(
+              backgroundColor:
+                  Theme.of(context).extension<StackColors>()!.background,
+              leading: AppBarBackButton(
+                onPressed: () async {
+                  Navigator.of(context).pop();
+                },
+              ),
+              title: Text(
+                "Filter addresses",
+                style: STextStyles.navBarTitle(context),
+              ),
             ),
-            title: Text(
-              "Filter addresses",
-              style: STextStyles.navBarTitle(context),
-            ),
-          ),
-          body: Padding(
-            padding: const EdgeInsets.all(12),
-            child: LayoutBuilder(builder: (builderContext, constraints) {
-              return SingleChildScrollView(
-                child: ConstrainedBox(
-                  constraints: BoxConstraints(
-                    minHeight: constraints.maxHeight,
-                  ),
-                  child: IntrinsicHeight(
-                    child: Padding(
-                      padding: const EdgeInsets.all(4),
-                      child: Column(
-                        crossAxisAlignment: CrossAxisAlignment.stretch,
-                        children: [
-                          RoundedWhiteContainer(
-                            child: Text(
-                              "Only selected cryptocurrency addresses will be displayed.",
-                              style: STextStyles.itemSubtitle(context),
+            body: Padding(
+              padding: const EdgeInsets.all(12),
+              child: LayoutBuilder(builder: (builderContext, constraints) {
+                return SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight,
+                    ),
+                    child: IntrinsicHeight(
+                      child: Padding(
+                        padding: const EdgeInsets.all(4),
+                        child: Column(
+                          crossAxisAlignment: CrossAxisAlignment.stretch,
+                          children: [
+                            RoundedWhiteContainer(
+                              child: Text(
+                                "Only selected cryptocurrency addresses will be displayed.",
+                                style: STextStyles.itemSubtitle(context),
+                              ),
                             ),
-                          ),
-                          const SizedBox(
-                            height: 12,
-                          ),
-                          Text(
-                            "Select cryptocurrency",
-                            style: STextStyles.smallMed12(context),
-                          ),
-                          const SizedBox(
-                            height: 12,
-                          ),
-                          child,
-                        ],
+                            const SizedBox(
+                              height: 12,
+                            ),
+                            Text(
+                              "Select cryptocurrency",
+                              style: STextStyles.smallMed12(context),
+                            ),
+                            const SizedBox(
+                              height: 12,
+                            ),
+                            child,
+                          ],
+                        ),
                       ),
                     ),
                   ),
-                ),
-              );
-            }),
+                );
+              }),
+            ),
           ),
         );
       },
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 a48a535c6..0ab6ebba9 100644
--- a/lib/pages/address_book_views/subviews/contact_details_view.dart
+++ b/lib/pages/address_book_views/subviews/contact_details_view.dart
@@ -18,6 +18,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
@@ -104,335 +105,203 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
     final _contact = ref.watch(addressBookServiceProvider
         .select((value) => value.getContactById(_contactId)));
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Contact details",
-          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("contactDetails"),
-                size: 36,
-                shadows: const [],
-                color: Theme.of(context).extension<StackColors>()!.background,
-                icon: SvgPicture.asset(
-                  Assets.svg.star,
-                  color: _contact.isFavorite
-                      ? Theme.of(context)
-                          .extension<StackColors>()!
-                          .favoriteStarActive
-                      : Theme.of(context)
-                          .extension<StackColors>()!
-                          .favoriteStarInactive,
-                  width: 20,
-                  height: 20,
-                ),
-                onPressed: () {
-                  bool isFavorite = _contact.isFavorite;
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Contact details",
+            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("contactDetails"),
+                  size: 36,
+                  shadows: const [],
+                  color: Theme.of(context).extension<StackColors>()!.background,
+                  icon: SvgPicture.asset(
+                    Assets.svg.star,
+                    color: _contact.isFavorite
+                        ? Theme.of(context)
+                            .extension<StackColors>()!
+                            .favoriteStarActive
+                        : Theme.of(context)
+                            .extension<StackColors>()!
+                            .favoriteStarInactive,
+                    width: 20,
+                    height: 20,
+                  ),
+                  onPressed: () {
+                    bool isFavorite = _contact.isFavorite;
 
-                  ref
-                      .read(addressBookServiceProvider)
-                      .editContact(_contact.copyWith(isFavorite: !isFavorite));
-                },
+                    ref.read(addressBookServiceProvider).editContact(
+                        _contact.copyWith(isFavorite: !isFavorite));
+                  },
+                ),
               ),
             ),
-          ),
-          Padding(
-            padding: const EdgeInsets.only(
-              top: 10,
-              bottom: 10,
-              right: 10,
-            ),
-            child: AspectRatio(
-              aspectRatio: 1,
-              child: AppBarIconButton(
-                key: const Key("contactDetailsViewDeleteContactButtonKey"),
-                size: 36,
-                shadows: const [],
-                color: Theme.of(context).extension<StackColors>()!.background,
-                icon: SvgPicture.asset(
-                  Assets.svg.trash,
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .accentColorDark,
-                  width: 20,
-                  height: 20,
-                ),
-                onPressed: () {
-                  showDialog<dynamic>(
-                    context: context,
-                    useSafeArea: true,
-                    barrierDismissible: true,
-                    builder: (_) => StackDialog(
-                      title: "Delete ${_contact.name}?",
-                      message: "Contact will be deleted permanently!",
-                      leftButton: TextButton(
-                        style: Theme.of(context)
-                            .extension<StackColors>()!
-                            .getSecondaryEnabledButtonColor(context),
-                        child: Text(
-                          "Cancel",
-                          style: STextStyles.itemSubtitle12(context),
+            Padding(
+              padding: const EdgeInsets.only(
+                top: 10,
+                bottom: 10,
+                right: 10,
+              ),
+              child: AspectRatio(
+                aspectRatio: 1,
+                child: AppBarIconButton(
+                  key: const Key("contactDetailsViewDeleteContactButtonKey"),
+                  size: 36,
+                  shadows: const [],
+                  color: Theme.of(context).extension<StackColors>()!.background,
+                  icon: SvgPicture.asset(
+                    Assets.svg.trash,
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .accentColorDark,
+                    width: 20,
+                    height: 20,
+                  ),
+                  onPressed: () {
+                    showDialog<dynamic>(
+                      context: context,
+                      useSafeArea: true,
+                      barrierDismissible: true,
+                      builder: (_) => StackDialog(
+                        title: "Delete ${_contact.name}?",
+                        message: "Contact will be deleted permanently!",
+                        leftButton: TextButton(
+                          style: Theme.of(context)
+                              .extension<StackColors>()!
+                              .getSecondaryEnabledButtonColor(context),
+                          child: Text(
+                            "Cancel",
+                            style: STextStyles.itemSubtitle12(context),
+                          ),
+                          onPressed: () {
+                            Navigator.of(context).pop();
+                          },
+                        ),
+                        rightButton: TextButton(
+                          style: Theme.of(context)
+                              .extension<StackColors>()!
+                              .getPrimaryEnabledButtonColor(context),
+                          child: Text(
+                            "Delete",
+                            style: STextStyles.button(context),
+                          ),
+                          onPressed: () {
+                            ref
+                                .read(addressBookServiceProvider)
+                                .removeContact(_contact.id);
+                            Navigator.of(context).pop();
+                            Navigator.of(context).pop();
+                            showFloatingFlushBar(
+                              type: FlushBarType.success,
+                              message: "${_contact.name} deleted",
+                              context: context,
+                            );
+                          },
                         ),
-                        onPressed: () {
-                          Navigator.of(context).pop();
-                        },
                       ),
-                      rightButton: TextButton(
-                        style: Theme.of(context)
-                            .extension<StackColors>()!
-                            .getPrimaryEnabledButtonColor(context),
-                        child: Text(
-                          "Delete",
-                          style: STextStyles.button(context),
+                    );
+                  },
+                ),
+              ),
+            ),
+          ],
+        ),
+        body: Padding(
+          padding: const EdgeInsets.symmetric(
+            horizontal: 12,
+          ),
+          child: SingleChildScrollView(
+            child: Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 4),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  const SizedBox(
+                    height: 12,
+                  ),
+                  Row(
+                    children: [
+                      Container(
+                        height: 48,
+                        width: 48,
+                        decoration: BoxDecoration(
+                          borderRadius: BorderRadius.circular(24),
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textFieldActiveBG,
                         ),
+                        child: Center(
+                          child: _contact.emojiChar == null
+                              ? SvgPicture.asset(
+                                  Assets.svg.user,
+                                  height: 24,
+                                  width: 24,
+                                )
+                              : Text(
+                                  _contact.emojiChar!,
+                                  style: STextStyles.pageTitleH1(context),
+                                ),
+                        ),
+                      ),
+                      const SizedBox(
+                        width: 16,
+                      ),
+                      FittedBox(
+                        fit: BoxFit.scaleDown,
+                        child: Text(
+                          _contact.name,
+                          textAlign: TextAlign.left,
+                          style: STextStyles.pageTitleH2(context),
+                        ),
+                      ),
+                      const Spacer(),
+                      TextButton(
                         onPressed: () {
-                          ref
-                              .read(addressBookServiceProvider)
-                              .removeContact(_contact.id);
-                          Navigator.of(context).pop();
-                          Navigator.of(context).pop();
-                          showFloatingFlushBar(
-                            type: FlushBarType.success,
-                            message: "${_contact.name} deleted",
-                            context: context,
+                          Navigator.of(context).pushNamed(
+                            EditContactNameEmojiView.routeName,
+                            arguments: _contact.id,
                           );
                         },
-                      ),
-                    ),
-                  );
-                },
-              ),
-            ),
-          ),
-        ],
-      ),
-      body: Padding(
-        padding: const EdgeInsets.symmetric(
-          horizontal: 12,
-        ),
-        child: SingleChildScrollView(
-          child: Padding(
-            padding: const EdgeInsets.symmetric(horizontal: 4),
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                const SizedBox(
-                  height: 12,
-                ),
-                Row(
-                  children: [
-                    Container(
-                      height: 48,
-                      width: 48,
-                      decoration: BoxDecoration(
-                        borderRadius: BorderRadius.circular(24),
-                        color: Theme.of(context)
+                        style: Theme.of(context)
                             .extension<StackColors>()!
-                            .textFieldActiveBG,
-                      ),
-                      child: Center(
-                        child: _contact.emojiChar == null
-                            ? SvgPicture.asset(
-                                Assets.svg.user,
-                                height: 24,
-                                width: 24,
-                              )
-                            : Text(
-                                _contact.emojiChar!,
-                                style: STextStyles.pageTitleH1(context),
-                              ),
-                      ),
-                    ),
-                    const SizedBox(
-                      width: 16,
-                    ),
-                    FittedBox(
-                      fit: BoxFit.scaleDown,
-                      child: Text(
-                        _contact.name,
-                        textAlign: TextAlign.left,
-                        style: STextStyles.pageTitleH2(context),
-                      ),
-                    ),
-                    const Spacer(),
-                    TextButton(
-                      onPressed: () {
-                        Navigator.of(context).pushNamed(
-                          EditContactNameEmojiView.routeName,
-                          arguments: _contact.id,
-                        );
-                      },
-                      style: Theme.of(context)
-                          .extension<StackColors>()!
-                          .getSecondaryEnabledButtonColor(context)!
-                          .copyWith(
-                            minimumSize: MaterialStateProperty.all<Size>(
-                                const Size(46, 32)),
-                          ),
-                      child: Padding(
-                        padding: const EdgeInsets.symmetric(horizontal: 12),
-                        child: Row(
-                          children: [
-                            SvgPicture.asset(Assets.svg.pencil,
-                                width: 10,
-                                height: 10,
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorDark),
-                            const SizedBox(
-                              width: 4,
+                            .getSecondaryEnabledButtonColor(context)!
+                            .copyWith(
+                              minimumSize: MaterialStateProperty.all<Size>(
+                                  const Size(46, 32)),
                             ),
-                            Text(
-                              "Edit",
-                              style: STextStyles.buttonSmall(context),
-                            ),
-                          ],
-                        ),
-                      ),
-                    ),
-                  ],
-                ),
-                const SizedBox(
-                  height: 24,
-                ),
-                Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  children: [
-                    Text(
-                      "Addresses",
-                      style: STextStyles.itemSubtitle(context),
-                    ),
-                    BlueTextButton(
-                      text: "Add new",
-                      onTap: () {
-                        Navigator.of(context).pushNamed(
-                          AddNewContactAddressView.routeName,
-                          arguments: _contact.id,
-                        );
-                      },
-                    ),
-                  ],
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                RoundedWhiteContainer(
-                  padding: const EdgeInsets.all(0),
-                  child: Column(
-                    children: [
-                      ..._contact.addresses.map(
-                        (e) => Padding(
-                          padding: const EdgeInsets.all(12),
+                        child: Padding(
+                          padding: const EdgeInsets.symmetric(horizontal: 12),
                           child: Row(
                             children: [
-                              SvgPicture.asset(
-                                Assets.svg.iconFor(coin: e.coin),
-                                height: 24,
-                              ),
-                              const SizedBox(
-                                width: 12,
-                              ),
-                              Expanded(
-                                child: Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "${e.label} (${e.coin.ticker})",
-                                      style:
-                                          STextStyles.itemSubtitle12(context),
-                                    ),
-                                    const SizedBox(
-                                      height: 2,
-                                    ),
-                                    FittedBox(
-                                      fit: BoxFit.scaleDown,
-                                      child: Text(
-                                        e.address,
-                                        style: STextStyles.itemSubtitle(context)
-                                            .copyWith(
-                                          fontSize: 8,
-                                        ),
-                                      ),
-                                    ),
-                                  ],
-                                ),
-                              ),
-                              GestureDetector(
-                                onTap: () {
-                                  ref
-                                      .read(addressEntryDataProvider(0))
-                                      .address = e.address;
-                                  ref
-                                      .read(addressEntryDataProvider(0))
-                                      .addressLabel = e.label;
-                                  ref.read(addressEntryDataProvider(0)).coin =
-                                      e.coin;
-
-                                  Navigator.of(context).pushNamed(
-                                    EditContactAddressView.routeName,
-                                    arguments: Tuple2(_contact.id, e),
-                                  );
-                                },
-                                child: RoundedContainer(
+                              SvgPicture.asset(Assets.svg.pencil,
+                                  width: 10,
+                                  height: 10,
                                   color: Theme.of(context)
                                       .extension<StackColors>()!
-                                      .textFieldDefaultBG,
-                                  padding: const EdgeInsets.all(6),
-                                  child: SvgPicture.asset(
-                                    Assets.svg.pencil,
-                                    width: 14,
-                                    height: 14,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .accentColorDark,
-                                  ),
-                                ),
-                              ),
+                                      .accentColorDark),
                               const SizedBox(
                                 width: 4,
                               ),
-                              GestureDetector(
-                                onTap: () {
-                                  clipboard.setData(
-                                    ClipboardData(text: e.address),
-                                  );
-                                  showFloatingFlushBar(
-                                    type: FlushBarType.info,
-                                    message: "Copied to clipboard",
-                                    iconAsset: Assets.svg.copy,
-                                    context: context,
-                                  );
-                                },
-                                child: RoundedContainer(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textFieldDefaultBG,
-                                  padding: const EdgeInsets.all(6),
-                                  child: SvgPicture.asset(
-                                    Assets.svg.copy,
-                                    width: 16,
-                                    height: 16,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .accentColorDark,
-                                  ),
-                                ),
+                              Text(
+                                "Edit",
+                                style: STextStyles.buttonSmall(context),
                               ),
                             ],
                           ),
@@ -440,81 +309,216 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
                       ),
                     ],
                   ),
-                ),
-                const SizedBox(
-                  height: 24,
-                ),
-                Text(
-                  "Transaction history",
-                  style: STextStyles.itemSubtitle(context),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                FutureBuilder(
-                  future: _filteredTransactionsByContact(
-                      ref.watch(walletsChangeNotifierProvider).managers),
-                  builder: (_,
-                      AsyncSnapshot<List<Tuple2<String, Transaction>>>
-                          snapshot) {
-                    if (snapshot.connectionState == ConnectionState.done &&
-                        snapshot.hasData) {
-                      _cachedTransactions = snapshot.data!;
-
-                      if (_cachedTransactions.isNotEmpty) {
-                        return RoundedWhiteContainer(
-                          padding: const EdgeInsets.all(0),
-                          child: Column(
-                            children: [
-                              ..._cachedTransactions.map(
-                                (e) => TransactionCard(
-                                  key: Key(
-                                      "contactDetailsTransaction_${e.item1}_${e.item2.txid}_cardKey"),
-                                  transaction: e.item2,
-                                  walletId: e.item1,
+                  const SizedBox(
+                    height: 24,
+                  ),
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Text(
+                        "Addresses",
+                        style: STextStyles.itemSubtitle(context),
+                      ),
+                      BlueTextButton(
+                        text: "Add new",
+                        onTap: () {
+                          Navigator.of(context).pushNamed(
+                            AddNewContactAddressView.routeName,
+                            arguments: _contact.id,
+                          );
+                        },
+                      ),
+                    ],
+                  ),
+                  const SizedBox(
+                    height: 12,
+                  ),
+                  RoundedWhiteContainer(
+                    padding: const EdgeInsets.all(0),
+                    child: Column(
+                      children: [
+                        ..._contact.addresses.map(
+                          (e) => Padding(
+                            padding: const EdgeInsets.all(12),
+                            child: Row(
+                              children: [
+                                SvgPicture.asset(
+                                  Assets.svg.iconFor(coin: e.coin),
+                                  height: 24,
                                 ),
-                              ),
-                            ],
-                          ),
-                        );
-                      } else {
-                        return RoundedWhiteContainer(
-                          child: Center(
-                            child: Text(
-                              "No transactions found",
-                              style: STextStyles.itemSubtitle(context),
+                                const SizedBox(
+                                  width: 12,
+                                ),
+                                Expanded(
+                                  child: Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.start,
+                                    children: [
+                                      Text(
+                                        "${e.label} (${e.coin.ticker})",
+                                        style:
+                                            STextStyles.itemSubtitle12(context),
+                                      ),
+                                      const SizedBox(
+                                        height: 2,
+                                      ),
+                                      FittedBox(
+                                        fit: BoxFit.scaleDown,
+                                        child: Text(
+                                          e.address,
+                                          style:
+                                              STextStyles.itemSubtitle(context)
+                                                  .copyWith(
+                                            fontSize: 8,
+                                          ),
+                                        ),
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                                GestureDetector(
+                                  onTap: () {
+                                    ref
+                                        .read(addressEntryDataProvider(0))
+                                        .address = e.address;
+                                    ref
+                                        .read(addressEntryDataProvider(0))
+                                        .addressLabel = e.label;
+                                    ref.read(addressEntryDataProvider(0)).coin =
+                                        e.coin;
+
+                                    Navigator.of(context).pushNamed(
+                                      EditContactAddressView.routeName,
+                                      arguments: Tuple2(_contact.id, e),
+                                    );
+                                  },
+                                  child: RoundedContainer(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textFieldDefaultBG,
+                                    padding: const EdgeInsets.all(6),
+                                    child: SvgPicture.asset(
+                                      Assets.svg.pencil,
+                                      width: 14,
+                                      height: 14,
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .accentColorDark,
+                                    ),
+                                  ),
+                                ),
+                                const SizedBox(
+                                  width: 4,
+                                ),
+                                GestureDetector(
+                                  onTap: () {
+                                    clipboard.setData(
+                                      ClipboardData(text: e.address),
+                                    );
+                                    showFloatingFlushBar(
+                                      type: FlushBarType.info,
+                                      message: "Copied to clipboard",
+                                      iconAsset: Assets.svg.copy,
+                                      context: context,
+                                    );
+                                  },
+                                  child: RoundedContainer(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textFieldDefaultBG,
+                                    padding: const EdgeInsets.all(6),
+                                    child: SvgPicture.asset(
+                                      Assets.svg.copy,
+                                      width: 16,
+                                      height: 16,
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .accentColorDark,
+                                    ),
+                                  ),
+                                ),
+                              ],
                             ),
                           ),
-                        );
-                      }
-                    } else {
-                      // TODO: proper loading animation
-                      if (_cachedTransactions.isEmpty) {
-                        return const LoadingIndicator();
-                      } else {
-                        return RoundedWhiteContainer(
-                          padding: const EdgeInsets.all(0),
-                          child: Column(
-                            children: [
-                              ..._cachedTransactions.map(
-                                (e) => TransactionCard(
-                                  key: Key(
-                                      "contactDetailsTransaction_${e.item1}_${e.item2.txid}_cardKey"),
-                                  transaction: e.item2,
-                                  walletId: e.item1,
+                        ),
+                      ],
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 24,
+                  ),
+                  Text(
+                    "Transaction history",
+                    style: STextStyles.itemSubtitle(context),
+                  ),
+                  const SizedBox(
+                    height: 12,
+                  ),
+                  FutureBuilder(
+                    future: _filteredTransactionsByContact(
+                        ref.watch(walletsChangeNotifierProvider).managers),
+                    builder: (_,
+                        AsyncSnapshot<List<Tuple2<String, Transaction>>>
+                            snapshot) {
+                      if (snapshot.connectionState == ConnectionState.done &&
+                          snapshot.hasData) {
+                        _cachedTransactions = snapshot.data!;
+
+                        if (_cachedTransactions.isNotEmpty) {
+                          return RoundedWhiteContainer(
+                            padding: const EdgeInsets.all(0),
+                            child: Column(
+                              children: [
+                                ..._cachedTransactions.map(
+                                  (e) => TransactionCard(
+                                    key: Key(
+                                        "contactDetailsTransaction_${e.item1}_${e.item2.txid}_cardKey"),
+                                    transaction: e.item2,
+                                    walletId: e.item1,
+                                  ),
                                 ),
+                              ],
+                            ),
+                          );
+                        } else {
+                          return RoundedWhiteContainer(
+                            child: Center(
+                              child: Text(
+                                "No transactions found",
+                                style: STextStyles.itemSubtitle(context),
                               ),
-                            ],
-                          ),
-                        );
+                            ),
+                          );
+                        }
+                      } else {
+                        // TODO: proper loading animation
+                        if (_cachedTransactions.isEmpty) {
+                          return const LoadingIndicator();
+                        } else {
+                          return RoundedWhiteContainer(
+                            padding: const EdgeInsets.all(0),
+                            child: Column(
+                              children: [
+                                ..._cachedTransactions.map(
+                                  (e) => TransactionCard(
+                                    key: Key(
+                                        "contactDetailsTransaction_${e.item1}_${e.item2.txid}_cardKey"),
+                                    transaction: e.item2,
+                                    walletId: e.item1,
+                                  ),
+                                ),
+                              ],
+                            ),
+                          );
+                        }
                       }
-                    }
-                  },
-                ),
-                const SizedBox(
-                  height: 16,
-                ),
-              ],
+                    },
+                  ),
+                  const SizedBox(
+                    height: 16,
+                  ),
+                ],
+              ),
             ),
           ),
         ),
diff --git a/lib/pages/address_book_views/subviews/edit_contact_address_view.dart b/lib/pages/address_book_views/subviews/edit_contact_address_view.dart
index f0143d39d..0454903c3 100644
--- a/lib/pages/address_book_views/subviews/edit_contact_address_view.dart
+++ b/lib/pages/address_book_views/subviews/edit_contact_address_view.dart
@@ -13,6 +13,7 @@ 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/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/primary_button.dart';
@@ -103,48 +104,51 @@ class _EditContactAddressViewState
 
     return ConditionalParent(
       condition: !isDesktop,
-      builder: (child) => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          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();
-              }
-            },
+      builder: (child) => Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            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 address",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
-          title: Text(
-            "Edit address",
-            style: STextStyles.navBarTitle(context),
-          ),
-        ),
-        body: LayoutBuilder(
-          builder: (context, constraints) {
-            return Padding(
-              padding: const EdgeInsets.only(
-                left: 12,
-                top: 12,
-                right: 12,
-              ),
-              child: SingleChildScrollView(
-                child: ConstrainedBox(
-                  constraints: BoxConstraints(
-                    minHeight: constraints.maxHeight - 24,
-                  ),
-                  child: IntrinsicHeight(
-                    child: Padding(
-                      padding: const EdgeInsets.all(4),
-                      child: child,
+          body: LayoutBuilder(
+            builder: (context, constraints) {
+              return Padding(
+                padding: const EdgeInsets.only(
+                  left: 12,
+                  top: 12,
+                  right: 12,
+                ),
+                child: SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight - 24,
+                    ),
+                    child: IntrinsicHeight(
+                      child: Padding(
+                        padding: const EdgeInsets.all(4),
+                        child: child,
+                      ),
                     ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
       child: Column(
diff --git a/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart b/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart
index a9b264b3c..99638ad2c 100644
--- a/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart
+++ b/lib/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart
@@ -10,6 +10,7 @@ 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.dart';
@@ -79,48 +80,51 @@ class _EditContactNameEmojiViewState
 
     return ConditionalParent(
       condition: !isDesktop,
-      builder: (child) => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          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();
-              }
-            },
+      builder: (child) => Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            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 contact",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
-          title: Text(
-            "Edit contact",
-            style: STextStyles.navBarTitle(context),
-          ),
-        ),
-        body: LayoutBuilder(
-          builder: (context, constraints) {
-            return Padding(
-              padding: const EdgeInsets.only(
-                left: 12,
-                top: 12,
-                right: 12,
-              ),
-              child: SingleChildScrollView(
-                child: ConstrainedBox(
-                  constraints: BoxConstraints(
-                    minHeight: constraints.maxHeight - 24,
-                  ),
-                  child: IntrinsicHeight(
-                    child: Padding(
-                      padding: const EdgeInsets.all(4),
-                      child: child,
+          body: LayoutBuilder(
+            builder: (context, constraints) {
+              return Padding(
+                padding: const EdgeInsets.only(
+                  left: 12,
+                  top: 12,
+                  right: 12,
+                ),
+                child: SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight - 24,
+                    ),
+                    child: IntrinsicHeight(
+                      child: Padding(
+                        padding: const EdgeInsets.all(4),
+                        child: child,
+                      ),
                     ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
       child: Column(
diff --git a/lib/pages/exchange_view/choose_from_stack_view.dart b/lib/pages/exchange_view/choose_from_stack_view.dart
index f54a7552c..7c7669430 100644
--- a/lib/pages/exchange_view/choose_from_stack_view.dart
+++ b/lib/pages/exchange_view/choose_from_stack_view.dart
@@ -5,6 +5,7 @@ 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';
+import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_balance_future.dart';
@@ -39,89 +40,92 @@ class _ChooseFromStackViewState extends ConsumerState<ChooseFromStackView> {
     final walletIds = ref.watch(walletsChangeNotifierProvider
         .select((value) => value.getWalletIdsFor(coin: coin)));
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: const AppBarBackButton(),
-        title: Text(
-          "Choose your ${coin.ticker.toUpperCase()} wallet",
-          style: STextStyles.navBarTitle(context),
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: const AppBarBackButton(),
+          title: Text(
+            "Choose your ${coin.ticker.toUpperCase()} wallet",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: walletIds.isEmpty
-            ? Column(
-                children: [
-                  RoundedWhiteContainer(
-                    child: Center(
-                      child: Text(
-                        "No ${coin.ticker.toUpperCase()} wallets",
-                        style: STextStyles.itemSubtitle(context),
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: walletIds.isEmpty
+              ? Column(
+                  children: [
+                    RoundedWhiteContainer(
+                      child: Center(
+                        child: Text(
+                          "No ${coin.ticker.toUpperCase()} wallets",
+                          style: STextStyles.itemSubtitle(context),
+                        ),
                       ),
                     ),
-                  ),
-                ],
-              )
-            : ListView.builder(
-                itemCount: walletIds.length,
-                itemBuilder: (context, index) {
-                  final manager = ref.watch(walletsChangeNotifierProvider
-                      .select((value) => value.getManager(walletIds[index])));
+                  ],
+                )
+              : ListView.builder(
+                  itemCount: walletIds.length,
+                  itemBuilder: (context, index) {
+                    final manager = ref.watch(walletsChangeNotifierProvider
+                        .select((value) => value.getManager(walletIds[index])));
 
-                  return Padding(
-                    padding: const EdgeInsets.symmetric(vertical: 5.0),
-                    child: RawMaterialButton(
-                      splashColor:
-                          Theme.of(context).extension<StackColors>()!.highlight,
-                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                      shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(
-                          Constants.size.circularBorderRadius,
+                    return Padding(
+                      padding: const EdgeInsets.symmetric(vertical: 5.0),
+                      child: RawMaterialButton(
+                        splashColor: Theme.of(context)
+                            .extension<StackColors>()!
+                            .highlight,
+                        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                        shape: RoundedRectangleBorder(
+                          borderRadius: BorderRadius.circular(
+                            Constants.size.circularBorderRadius,
+                          ),
                         ),
-                      ),
-                      padding: const EdgeInsets.all(0),
-                      // color: Theme.of(context).extension<StackColors>()!.popupBG,
-                      elevation: 0,
-                      onPressed: () async {
-                        if (mounted) {
-                          Navigator.of(context).pop(manager.walletId);
-                        }
-                      },
-                      child: RoundedWhiteContainer(
-                        // color: Colors.transparent,
-                        child: Row(
-                          children: [
-                            WalletInfoCoinIcon(coin: coin),
-                            const SizedBox(
-                              width: 12,
-                            ),
-                            Expanded(
-                              child: Column(
-                                mainAxisSize: MainAxisSize.min,
-                                crossAxisAlignment: CrossAxisAlignment.start,
-                                children: [
-                                  Text(
-                                    manager.walletName,
-                                    style: STextStyles.titleBold12(context),
-                                    overflow: TextOverflow.ellipsis,
-                                  ),
-                                  const SizedBox(
-                                    height: 2,
-                                  ),
-                                  WalletInfoRowBalanceFuture(
-                                    walletId: walletIds[index],
-                                  ),
-                                ],
+                        padding: const EdgeInsets.all(0),
+                        // color: Theme.of(context).extension<StackColors>()!.popupBG,
+                        elevation: 0,
+                        onPressed: () async {
+                          if (mounted) {
+                            Navigator.of(context).pop(manager.walletId);
+                          }
+                        },
+                        child: RoundedWhiteContainer(
+                          // color: Colors.transparent,
+                          child: Row(
+                            children: [
+                              WalletInfoCoinIcon(coin: coin),
+                              const SizedBox(
+                                width: 12,
                               ),
-                            )
-                          ],
+                              Expanded(
+                                child: Column(
+                                  mainAxisSize: MainAxisSize.min,
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      manager.walletName,
+                                      style: STextStyles.titleBold12(context),
+                                      overflow: TextOverflow.ellipsis,
+                                    ),
+                                    const SizedBox(
+                                      height: 2,
+                                    ),
+                                    WalletInfoRowBalanceFuture(
+                                      walletId: walletIds[index],
+                                    ),
+                                  ],
+                                ),
+                              )
+                            ],
+                          ),
                         ),
                       ),
-                    ),
-                  );
-                },
-              ),
+                    );
+                  },
+                ),
+        ),
       ),
     );
   }
diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index 810ea2541..25ae51ecf 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -18,6 +18,7 @@ import 'package:stackwallet/utilities/format.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.dart';
@@ -232,49 +233,51 @@ class _ConfirmChangeNowSendViewState
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
+        return Background(
+          child: Scaffold(
             backgroundColor:
                 Theme.of(context).extension<StackColors>()!.background,
-            leading: AppBarBackButton(
-              onPressed: () async {
-                // if (FocusScope.of(context).hasFocus) {
-                //   FocusScope.of(context).unfocus();
-                //   await Future<void>.delayed(Duration(milliseconds: 50));
-                // }
-                Navigator.of(context).pop();
-              },
+            appBar: 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(Duration(milliseconds: 50));
+                  // }
+                  Navigator.of(context).pop();
+                },
+              ),
+              title: Text(
+                "Confirm transaction",
+                style: STextStyles.navBarTitle(context),
+              ),
             ),
-            title: Text(
-              "Confirm transaction",
-              style: STextStyles.navBarTitle(context),
-            ),
-          ),
-          body: LayoutBuilder(
-            builder: (builderContext, constraints) {
-              return Padding(
-                padding: const EdgeInsets.only(
-                  left: 12,
-                  top: 12,
-                  right: 12,
-                ),
-                child: SingleChildScrollView(
-                  child: ConstrainedBox(
-                    constraints: BoxConstraints(
-                      minHeight: constraints.maxHeight - 24,
-                    ),
-                    child: IntrinsicHeight(
-                      child: Padding(
-                        padding: const EdgeInsets.all(4),
-                        child: child,
+            body: LayoutBuilder(
+              builder: (builderContext, constraints) {
+                return Padding(
+                  padding: const EdgeInsets.only(
+                    left: 12,
+                    top: 12,
+                    right: 12,
+                  ),
+                  child: SingleChildScrollView(
+                    child: ConstrainedBox(
+                      constraints: BoxConstraints(
+                        minHeight: constraints.maxHeight - 24,
+                      ),
+                      child: IntrinsicHeight(
+                        child: Padding(
+                          padding: const EdgeInsets.all(4),
+                          child: child,
+                        ),
                       ),
                     ),
                   ),
-                ),
-              );
-            },
+                );
+              },
+            ),
           ),
         );
       },
diff --git a/lib/pages/exchange_view/edit_trade_note_view.dart b/lib/pages/exchange_view/edit_trade_note_view.dart
index e2a72d1b4..19804b7c5 100644
--- a/lib/pages/exchange_view/edit_trade_note_view.dart
+++ b/lib/pages/exchange_view/edit_trade_note_view.dart
@@ -4,13 +4,13 @@ import 'package:stackwallet/providers/exchange/trade_note_service_provider.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/custom_buttons/app_bar_icon_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';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class EditTradeNoteView extends ConsumerStatefulWidget {
   const EditTradeNoteView({
     Key? key,
@@ -47,105 +47,109 @@ class _EditNoteViewState extends ConsumerState<EditTradeNoteView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
+    return Background(
+      child: Scaffold(
         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();
-            }
-          },
+        appBar: 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 trade note",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Edit trade note",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: 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: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            controller: _noteController,
-                            style: STextStyles.field(context),
-                            focusNode: noteFieldFocusNode,
-                            onChanged: (_) => setState(() {}),
-                            decoration: standardInputDecoration(
-                              "Note",
-                              noteFieldFocusNode,
-                              context,
-                            ).copyWith(
-                              suffixIcon: _noteController.text.isNotEmpty
-                                  ? Padding(
-                                      padding: const EdgeInsets.only(right: 0),
-                                      child: UnconstrainedBox(
-                                        child: Row(
-                                          children: [
-                                            TextFieldIconButton(
-                                              child: const XIcon(),
-                                              onTap: () async {
-                                                setState(() {
-                                                  _noteController.text = "";
-                                                });
-                                              },
-                                            ),
-                                          ],
+        body: 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: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          ClipRRect(
+                            borderRadius: BorderRadius.circular(
+                              Constants.size.circularBorderRadius,
+                            ),
+                            child: TextField(
+                              autocorrect: Util.isDesktop ? false : true,
+                              enableSuggestions: Util.isDesktop ? false : true,
+                              controller: _noteController,
+                              style: STextStyles.field(context),
+                              focusNode: noteFieldFocusNode,
+                              onChanged: (_) => setState(() {}),
+                              decoration: standardInputDecoration(
+                                "Note",
+                                noteFieldFocusNode,
+                                context,
+                              ).copyWith(
+                                suffixIcon: _noteController.text.isNotEmpty
+                                    ? Padding(
+                                        padding:
+                                            const EdgeInsets.only(right: 0),
+                                        child: UnconstrainedBox(
+                                          child: Row(
+                                            children: [
+                                              TextFieldIconButton(
+                                                child: const XIcon(),
+                                                onTap: () async {
+                                                  setState(() {
+                                                    _noteController.text = "";
+                                                  });
+                                                },
+                                              ),
+                                            ],
+                                          ),
                                         ),
-                                      ),
-                                    )
-                                  : null,
+                                      )
+                                    : null,
+                              ),
                             ),
                           ),
-                        ),
-                        const Spacer(),
-                        TextButton(
-                          onPressed: () async {
-                            await ref.read(tradeNoteServiceProvider).set(
-                                  tradeId: widget.tradeId,
-                                  note: _noteController.text,
-                                );
-                            if (mounted) {
-                              Navigator.of(context).pop();
-                            }
-                          },
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context),
-                          child: Text(
-                            "Save",
-                            style: STextStyles.button(context),
-                          ),
-                        )
-                      ],
+                          const Spacer(),
+                          TextButton(
+                            onPressed: () async {
+                              await ref.read(tradeNoteServiceProvider).set(
+                                    tradeId: widget.tradeId,
+                                    note: _noteController.text,
+                                  );
+                              if (mounted) {
+                                Navigator.of(context).pop();
+                              }
+                            },
+                            style: Theme.of(context)
+                                .extension<StackColors>()!
+                                .getPrimaryEnabledButtonColor(context),
+                            child: Text(
+                              "Save",
+                              style: STextStyles.button(context),
+                            ),
+                          )
+                        ],
+                      ),
                     ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
     );
diff --git a/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart b/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart
index 779d99306..fdc1e027a 100644
--- a/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart
+++ b/lib/pages/exchange_view/exchange_coin_selection/fixed_rate_pair_coin_selection_view.dart
@@ -9,6 +9,7 @@ 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/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
@@ -124,32 +125,35 @@ class _FixedRateMarketPairCoinSelectionViewState
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            leading: AppBarBackButton(
-              onPressed: () async {
-                if (FocusScope.of(context).hasFocus) {
-                  FocusScope.of(context).unfocus();
-                  await Future<void>.delayed(const Duration(milliseconds: 50));
-                }
-                if (mounted) {
-                  Navigator.of(context).pop();
-                }
-              },
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              leading: AppBarBackButton(
+                onPressed: () async {
+                  if (FocusScope.of(context).hasFocus) {
+                    FocusScope.of(context).unfocus();
+                    await Future<void>.delayed(
+                        const Duration(milliseconds: 50));
+                  }
+                  if (mounted) {
+                    Navigator.of(context).pop();
+                  }
+                },
+              ),
+              title: Text(
+                "Choose a coin to exchange",
+                style: STextStyles.pageTitleH2(context),
+              ),
             ),
-            title: Text(
-              "Choose a coin to exchange",
-              style: STextStyles.pageTitleH2(context),
+            body: Padding(
+              padding: const EdgeInsets.symmetric(
+                horizontal: 16,
+              ),
+              child: child,
             ),
           ),
-          body: Padding(
-            padding: const EdgeInsets.symmetric(
-              horizontal: 16,
-            ),
-            child: child,
-          ),
         );
       },
       child: Column(
diff --git a/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart b/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart
index eb7a99299..1a82e5ec5 100644
--- a/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart
+++ b/lib/pages/exchange_view/exchange_coin_selection/floating_rate_currency_selection_view.dart
@@ -7,6 +7,7 @@ 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/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
@@ -80,32 +81,35 @@ class _FloatingRateCurrencySelectionViewState
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            leading: AppBarBackButton(
-              onPressed: () async {
-                if (FocusScope.of(context).hasFocus) {
-                  FocusScope.of(context).unfocus();
-                  await Future<void>.delayed(const Duration(milliseconds: 50));
-                }
-                if (mounted) {
-                  Navigator.of(context).pop();
-                }
-              },
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              leading: AppBarBackButton(
+                onPressed: () async {
+                  if (FocusScope.of(context).hasFocus) {
+                    FocusScope.of(context).unfocus();
+                    await Future<void>.delayed(
+                        const Duration(milliseconds: 50));
+                  }
+                  if (mounted) {
+                    Navigator.of(context).pop();
+                  }
+                },
+              ),
+              title: Text(
+                "Choose a coin to exchange",
+                style: STextStyles.pageTitleH2(context),
+              ),
             ),
-            title: Text(
-              "Choose a coin to exchange",
-              style: STextStyles.pageTitleH2(context),
+            body: Padding(
+              padding: const EdgeInsets.symmetric(
+                horizontal: 16,
+              ),
+              child: child,
             ),
           ),
-          body: Padding(
-            padding: const EdgeInsets.symmetric(
-              horizontal: 16,
-            ),
-            child: child,
-          ),
         );
       },
       child: Column(
diff --git a/lib/pages/exchange_view/exchange_step_views/step_1_view.dart b/lib/pages/exchange_view/exchange_step_views/step_1_view.dart
index 95f086003..b51bccc55 100644
--- a/lib/pages/exchange_view/exchange_step_views/step_1_view.dart
+++ b/lib/pages/exchange_view/exchange_step_views/step_1_view.dart
@@ -6,6 +6,7 @@ import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
@@ -39,166 +40,169 @@ class _Step1ViewState extends State<Step1View> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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();
-            }
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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(
+            "Exchange",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Exchange",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (context, constraints) {
-          final width = MediaQuery.of(context).size.width - 32;
-          return Padding(
-            padding: const EdgeInsets.all(12),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        StepRow(
-                          count: 4,
-                          current: 0,
-                          width: width,
-                        ),
-                        const SizedBox(
-                          height: 14,
-                        ),
-                        Text(
-                          "Confirm amount",
-                          style: STextStyles.pageTitleH1(context),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        Text(
-                          "Network fees and other exchange charges are included in the rate.",
-                          style: STextStyles.itemSubtitle(context),
-                        ),
-                        const SizedBox(
-                          height: 24,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "You send",
-                                style: STextStyles.itemSubtitle(context)
-                                    .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .infoItemText),
-                              ),
-                              Text(
-                                "${model.sendAmount.toStringAsFixed(8)} ${model.sendTicker.toUpperCase()}",
-                                style: STextStyles.itemSubtitle12(context)
-                                    .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .infoItemText),
-                              ),
-                            ],
+        body: LayoutBuilder(
+          builder: (context, constraints) {
+            final width = MediaQuery.of(context).size.width - 32;
+            return Padding(
+              padding: const EdgeInsets.all(12),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          StepRow(
+                            count: 4,
+                            current: 0,
+                            width: width,
                           ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "You receive",
-                                style: STextStyles.itemSubtitle(context)
-                                    .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .infoItemText),
-                              ),
-                              Text(
-                                "~${model.receiveAmount.toStringAsFixed(8)} ${model.receiveTicker.toUpperCase()}",
-                                style: STextStyles.itemSubtitle12(context)
-                                    .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .infoItemText),
-                              ),
-                            ],
+                          const SizedBox(
+                            height: 14,
                           ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                model.rateType == ExchangeRateType.estimated
-                                    ? "Estimated rate"
-                                    : "Fixed rate",
-                                style:
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .infoItemLabel,
+                          Text(
+                            "Confirm amount",
+                            style: STextStyles.pageTitleH1(context),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          Text(
+                            "Network fees and other exchange charges are included in the rate.",
+                            style: STextStyles.itemSubtitle(context),
+                          ),
+                          const SizedBox(
+                            height: 24,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              children: [
+                                Text(
+                                  "You send",
+                                  style: STextStyles.itemSubtitle(context)
+                                      .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .infoItemText),
                                 ),
-                              ),
-                              Text(
-                                model.rateInfo,
-                                style: STextStyles.itemSubtitle12(context)
-                                    .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .infoItemText),
-                              ),
-                            ],
+                                Text(
+                                  "${model.sendAmount.toStringAsFixed(8)} ${model.sendTicker.toUpperCase()}",
+                                  style: STextStyles.itemSubtitle12(context)
+                                      .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .infoItemText),
+                                ),
+                              ],
+                            ),
                           ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        const Spacer(),
-                        TextButton(
-                          onPressed: () {
-                            Navigator.of(context).pushNamed(Step2View.routeName,
-                                arguments: model);
-                          },
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context),
-                          child: Text(
-                            "Next",
-                            style: STextStyles.button(context),
+                          const SizedBox(
+                            height: 12,
                           ),
-                        ),
-                      ],
+                          RoundedWhiteContainer(
+                            child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              children: [
+                                Text(
+                                  "You receive",
+                                  style: STextStyles.itemSubtitle(context)
+                                      .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .infoItemText),
+                                ),
+                                Text(
+                                  "~${model.receiveAmount.toStringAsFixed(8)} ${model.receiveTicker.toUpperCase()}",
+                                  style: STextStyles.itemSubtitle12(context)
+                                      .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .infoItemText),
+                                ),
+                              ],
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              children: [
+                                Text(
+                                  model.rateType == ExchangeRateType.estimated
+                                      ? "Estimated rate"
+                                      : "Fixed rate",
+                                  style: STextStyles.itemSubtitle(context)
+                                      .copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .infoItemLabel,
+                                  ),
+                                ),
+                                Text(
+                                  model.rateInfo,
+                                  style: STextStyles.itemSubtitle12(context)
+                                      .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .infoItemText),
+                                ),
+                              ],
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          const Spacer(),
+                          TextButton(
+                            onPressed: () {
+                              Navigator.of(context).pushNamed(
+                                  Step2View.routeName,
+                                  arguments: model);
+                            },
+                            style: Theme.of(context)
+                                .extension<StackColors>()!
+                                .getPrimaryEnabledButtonColor(context),
+                            child: Text(
+                              "Next",
+                              style: STextStyles.button(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 030f91cb7..d943adcfa 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
@@ -16,6 +16,7 @@ import 'package:stackwallet/utilities/enums/coin_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/background.dart';
 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/desktop/primary_button.dart';
@@ -122,188 +123,285 @@ class _Step2ViewState extends ConsumerState<Step2View> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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();
-            }
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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(
+            "Exchange",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Exchange",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (context, constraints) {
-          final width = MediaQuery.of(context).size.width - 32;
-          return Padding(
-            padding: const EdgeInsets.all(12),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        StepRow(
-                          count: 4,
-                          current: 1,
-                          width: width,
-                        ),
-                        const SizedBox(
-                          height: 14,
-                        ),
-                        Text(
-                          "Exchange details",
-                          style: STextStyles.pageTitleH1(context),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        Text(
-                          "Enter your recipient and refund addresses",
-                          style: STextStyles.itemSubtitle(context),
-                        ),
-                        const SizedBox(
-                          height: 24,
-                        ),
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: [
-                            Text(
-                              "Recipient Wallet",
-                              style: STextStyles.smallMed12(context),
-                            ),
-                            if (isStackCoin(model.receiveTicker))
-                              BlueTextButton(
-                                text: "Choose from stack",
-                                onTap: () {
-                                  try {
-                                    final coin = coinFromTickerCaseInsensitive(
-                                      model.receiveTicker,
-                                    );
-                                    Navigator.of(context)
-                                        .pushNamed(
-                                      ChooseFromStackView.routeName,
-                                      arguments: coin,
-                                    )
-                                        .then((value) async {
-                                      if (value is String) {
-                                        final manager = ref
-                                            .read(walletsChangeNotifierProvider)
-                                            .getManager(value);
-
-                                        _toController.text = manager.walletName;
-                                        model.recipientAddress = await manager
-                                            .currentReceivingAddress;
-
-                                        setState(() {
-                                          enableNext = _toController
-                                                  .text.isNotEmpty &&
-                                              _refundController.text.isNotEmpty;
-                                        });
-                                      }
-                                    });
-                                  } catch (e, s) {
-                                    Logging.instance
-                                        .log("$e\n$s", level: LogLevel.Info);
-                                  }
-                                },
-                              ),
-                          ],
-                        ),
-                        const SizedBox(
-                          height: 4,
-                        ),
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
+        body: LayoutBuilder(
+          builder: (context, constraints) {
+            final width = MediaQuery.of(context).size.width - 32;
+            return Padding(
+              padding: const EdgeInsets.all(12),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          StepRow(
+                            count: 4,
+                            current: 1,
+                            width: width,
                           ),
-                          child: TextField(
-                            onTap: () {},
-                            key: const Key(
-                                "recipientExchangeStep2ViewAddressFieldKey"),
-                            controller: _toController,
-                            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,
-                            ),
-                            focusNode: _toFocusNode,
-                            style: STextStyles.field(context),
-                            onChanged: (value) {
-                              setState(() {});
-                            },
-                            decoration: standardInputDecoration(
-                              "Enter the ${model.receiveTicker.toUpperCase()} payout address",
-                              _toFocusNode,
-                              context,
-                            ).copyWith(
-                              contentPadding: const EdgeInsets.only(
-                                left: 16,
-                                top: 6,
-                                bottom: 8,
-                                right: 5,
+                          const SizedBox(
+                            height: 14,
+                          ),
+                          Text(
+                            "Exchange details",
+                            style: STextStyles.pageTitleH1(context),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          Text(
+                            "Enter your recipient and refund addresses",
+                            style: STextStyles.itemSubtitle(context),
+                          ),
+                          const SizedBox(
+                            height: 24,
+                          ),
+                          Row(
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            children: [
+                              Text(
+                                "Recipient Wallet",
+                                style: STextStyles.smallMed12(context),
                               ),
-                              suffixIcon: Padding(
-                                padding: _toController.text.isEmpty
-                                    ? const EdgeInsets.only(right: 8)
-                                    : const EdgeInsets.only(right: 0),
-                                child: UnconstrainedBox(
-                                  child: Row(
-                                    mainAxisAlignment:
-                                        MainAxisAlignment.spaceAround,
-                                    children: [
-                                      _toController.text.isNotEmpty
-                                          ? TextFieldIconButton(
-                                              key: const Key(
-                                                  "sendViewClearAddressFieldButtonKey"),
-                                              onTap: () {
-                                                _toController.text = "";
-                                                model.recipientAddress =
-                                                    _toController.text;
+                              if (isStackCoin(model.receiveTicker))
+                                BlueTextButton(
+                                  text: "Choose from stack",
+                                  onTap: () {
+                                    try {
+                                      final coin =
+                                          coinFromTickerCaseInsensitive(
+                                        model.receiveTicker,
+                                      );
+                                      Navigator.of(context)
+                                          .pushNamed(
+                                        ChooseFromStackView.routeName,
+                                        arguments: coin,
+                                      )
+                                          .then((value) async {
+                                        if (value is String) {
+                                          final manager = ref
+                                              .read(
+                                                  walletsChangeNotifierProvider)
+                                              .getManager(value);
 
+                                          _toController.text =
+                                              manager.walletName;
+                                          model.recipientAddress = await manager
+                                              .currentReceivingAddress;
+
+                                          setState(() {
+                                            enableNext =
+                                                _toController.text.isNotEmpty &&
+                                                    _refundController
+                                                        .text.isNotEmpty;
+                                          });
+                                        }
+                                      });
+                                    } catch (e, s) {
+                                      Logging.instance
+                                          .log("$e\n$s", level: LogLevel.Info);
+                                    }
+                                  },
+                                ),
+                            ],
+                          ),
+                          const SizedBox(
+                            height: 4,
+                          ),
+                          ClipRRect(
+                            borderRadius: BorderRadius.circular(
+                              Constants.size.circularBorderRadius,
+                            ),
+                            child: TextField(
+                              onTap: () {},
+                              key: const Key(
+                                  "recipientExchangeStep2ViewAddressFieldKey"),
+                              controller: _toController,
+                              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,
+                              ),
+                              focusNode: _toFocusNode,
+                              style: STextStyles.field(context),
+                              onChanged: (value) {
+                                setState(() {});
+                              },
+                              decoration: standardInputDecoration(
+                                "Enter the ${model.receiveTicker.toUpperCase()} payout address",
+                                _toFocusNode,
+                                context,
+                              ).copyWith(
+                                contentPadding: const EdgeInsets.only(
+                                  left: 16,
+                                  top: 6,
+                                  bottom: 8,
+                                  right: 5,
+                                ),
+                                suffixIcon: Padding(
+                                  padding: _toController.text.isEmpty
+                                      ? const EdgeInsets.only(right: 8)
+                                      : const EdgeInsets.only(right: 0),
+                                  child: UnconstrainedBox(
+                                    child: Row(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceAround,
+                                      children: [
+                                        _toController.text.isNotEmpty
+                                            ? TextFieldIconButton(
+                                                key: const Key(
+                                                    "sendViewClearAddressFieldButtonKey"),
+                                                onTap: () {
+                                                  _toController.text = "";
+                                                  model.recipientAddress =
+                                                      _toController.text;
+
+                                                  setState(() {
+                                                    enableNext = _toController
+                                                            .text.isNotEmpty &&
+                                                        _refundController
+                                                            .text.isNotEmpty;
+                                                  });
+                                                },
+                                                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) {
+                                                    final content =
+                                                        data.text!.trim();
+
+                                                    _toController.text =
+                                                        content;
+                                                    model.recipientAddress =
+                                                        _toController.text;
+
+                                                    setState(() {
+                                                      enableNext = _toController
+                                                              .text
+                                                              .isNotEmpty &&
+                                                          _refundController
+                                                              .text.isNotEmpty;
+                                                    });
+                                                  }
+                                                },
+                                                child:
+                                                    _toController.text.isEmpty
+                                                        ? const ClipboardIcon()
+                                                        : const XIcon(),
+                                              ),
+                                        if (_toController.text.isEmpty)
+                                          TextFieldIconButton(
+                                            key: const Key(
+                                                "sendViewAddressBookButtonKey"),
+                                            onTap: () {
+                                              ref
+                                                  .read(
+                                                      exchangeFlowIsActiveStateProvider
+                                                          .state)
+                                                  .state = true;
+                                              Navigator.of(context)
+                                                  .pushNamed(
+                                                AddressBookView.routeName,
+                                              )
+                                                  .then((_) {
+                                                ref
+                                                    .read(
+                                                        exchangeFlowIsActiveStateProvider
+                                                            .state)
+                                                    .state = false;
+
+                                                final address = ref
+                                                    .read(
+                                                        exchangeFromAddressBookAddressStateProvider
+                                                            .state)
+                                                    .state;
+                                                if (address.isNotEmpty) {
+                                                  _toController.text = address;
+                                                  model.recipientAddress =
+                                                      _toController.text;
+                                                  ref
+                                                      .read(
+                                                          exchangeFromAddressBookAddressStateProvider
+                                                              .state)
+                                                      .state = "";
+                                                }
                                                 setState(() {
                                                   enableNext = _toController
                                                           .text.isNotEmpty &&
                                                       _refundController
                                                           .text.isNotEmpty;
                                                 });
-                                              },
-                                              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) {
-                                                  final content =
-                                                      data.text!.trim();
+                                              });
+                                            },
+                                            child: const AddressBookIcon(),
+                                          ),
+                                        if (_toController.text.isEmpty)
+                                          TextFieldIconButton(
+                                            key: const Key(
+                                                "sendViewScanQrButtonKey"),
+                                            onTap: () async {
+                                              try {
+                                                final qrResult =
+                                                    await scanner.scan();
 
-                                                  _toController.text = content;
+                                                final results =
+                                                    AddressUtils.parseUri(
+                                                        qrResult.rawContent);
+                                                if (results.isNotEmpty) {
+                                                  // auto fill address
+                                                  _toController.text =
+                                                      results["address"] ?? "";
+                                                  model.recipientAddress =
+                                                      _toController.text;
+
+                                                  setState(() {
+                                                    enableNext = _toController
+                                                            .text.isNotEmpty &&
+                                                        _refundController
+                                                            .text.isNotEmpty;
+                                                  });
+                                                } else {
+                                                  _toController.text =
+                                                      qrResult.rawContent;
                                                   model.recipientAddress =
                                                       _toController.text;
 
@@ -314,248 +412,247 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                             .text.isNotEmpty;
                                                   });
                                                 }
-                                              },
-                                              child: _toController.text.isEmpty
-                                                  ? const ClipboardIcon()
-                                                  : const XIcon(),
-                                            ),
-                                      if (_toController.text.isEmpty)
-                                        TextFieldIconButton(
-                                          key: const Key(
-                                              "sendViewAddressBookButtonKey"),
-                                          onTap: () {
-                                            ref
-                                                .read(
-                                                    exchangeFlowIsActiveStateProvider
-                                                        .state)
-                                                .state = true;
-                                            Navigator.of(context)
-                                                .pushNamed(
-                                              AddressBookView.routeName,
-                                            )
-                                                .then((_) {
-                                              ref
-                                                  .read(
-                                                      exchangeFlowIsActiveStateProvider
-                                                          .state)
-                                                  .state = false;
-
-                                              final address = ref
-                                                  .read(
-                                                      exchangeFromAddressBookAddressStateProvider
-                                                          .state)
-                                                  .state;
-                                              if (address.isNotEmpty) {
-                                                _toController.text = address;
-                                                model.recipientAddress =
-                                                    _toController.text;
-                                                ref
-                                                    .read(
-                                                        exchangeFromAddressBookAddressStateProvider
-                                                            .state)
-                                                    .state = "";
+                                              } on PlatformException catch (e, s) {
+                                                Logging.instance.log(
+                                                  "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
+                                                  level: LogLevel.Warning,
+                                                );
                                               }
-                                              setState(() {
-                                                enableNext = _toController
-                                                        .text.isNotEmpty &&
-                                                    _refundController
-                                                        .text.isNotEmpty;
-                                              });
-                                            });
-                                          },
-                                          child: const AddressBookIcon(),
-                                        ),
-                                      if (_toController.text.isEmpty)
-                                        TextFieldIconButton(
-                                          key: const Key(
-                                              "sendViewScanQrButtonKey"),
-                                          onTap: () async {
-                                            try {
-                                              final qrResult =
-                                                  await scanner.scan();
-
-                                              final results =
-                                                  AddressUtils.parseUri(
-                                                      qrResult.rawContent);
-                                              if (results.isNotEmpty) {
-                                                // auto fill address
-                                                _toController.text =
-                                                    results["address"] ?? "";
-                                                model.recipientAddress =
-                                                    _toController.text;
-
-                                                setState(() {
-                                                  enableNext = _toController
-                                                          .text.isNotEmpty &&
-                                                      _refundController
-                                                          .text.isNotEmpty;
-                                                });
-                                              } else {
-                                                _toController.text =
-                                                    qrResult.rawContent;
-                                                model.recipientAddress =
-                                                    _toController.text;
-
-                                                setState(() {
-                                                  enableNext = _toController
-                                                          .text.isNotEmpty &&
-                                                      _refundController
-                                                          .text.isNotEmpty;
-                                                });
-                                              }
-                                            } on PlatformException catch (e, s) {
-                                              Logging.instance.log(
-                                                "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
-                                                level: LogLevel.Warning,
-                                              );
-                                            }
-                                          },
-                                          child: const QrCodeIcon(),
-                                        ),
-                                    ],
+                                            },
+                                            child: const QrCodeIcon(),
+                                          ),
+                                      ],
+                                    ),
                                   ),
                                 ),
                               ),
                             ),
                           ),
-                        ),
-                        const SizedBox(
-                          height: 6,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Text(
-                            "This is the wallet where your ${model.receiveTicker.toUpperCase()} will be sent to.",
-                            style: STextStyles.label(context),
+                          const SizedBox(
+                            height: 6,
                           ),
-                        ),
-                        const SizedBox(
-                          height: 24,
-                        ),
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: [
-                            Text(
-                              "Refund Wallet (required)",
-                              style: STextStyles.smallMed12(context),
+                          RoundedWhiteContainer(
+                            child: Text(
+                              "This is the wallet where your ${model.receiveTicker.toUpperCase()} will be sent to.",
+                              style: STextStyles.label(context),
                             ),
-                            if (isStackCoin(model.sendTicker))
-                              BlueTextButton(
-                                text: "Choose from stack",
-                                onTap: () {
-                                  try {
-                                    final coin = coinFromTickerCaseInsensitive(
-                                      model.sendTicker,
-                                    );
-                                    Navigator.of(context)
-                                        .pushNamed(
-                                      ChooseFromStackView.routeName,
-                                      arguments: coin,
-                                    )
-                                        .then((value) async {
-                                      if (value is String) {
-                                        final manager = ref
-                                            .read(walletsChangeNotifierProvider)
-                                            .getManager(value);
+                          ),
+                          const SizedBox(
+                            height: 24,
+                          ),
+                          Row(
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            children: [
+                              Text(
+                                "Refund Wallet (required)",
+                                style: STextStyles.smallMed12(context),
+                              ),
+                              if (isStackCoin(model.sendTicker))
+                                BlueTextButton(
+                                  text: "Choose from stack",
+                                  onTap: () {
+                                    try {
+                                      final coin =
+                                          coinFromTickerCaseInsensitive(
+                                        model.sendTicker,
+                                      );
+                                      Navigator.of(context)
+                                          .pushNamed(
+                                        ChooseFromStackView.routeName,
+                                        arguments: coin,
+                                      )
+                                          .then((value) async {
+                                        if (value is String) {
+                                          final manager = ref
+                                              .read(
+                                                  walletsChangeNotifierProvider)
+                                              .getManager(value);
 
-                                        _refundController.text =
-                                            manager.walletName;
-                                        model.refundAddress = await manager
-                                            .currentReceivingAddress;
-                                      }
-                                      setState(() {
-                                        enableNext = _toController
-                                                .text.isNotEmpty &&
-                                            _refundController.text.isNotEmpty;
+                                          _refundController.text =
+                                              manager.walletName;
+                                          model.refundAddress = await manager
+                                              .currentReceivingAddress;
+                                        }
+                                        setState(() {
+                                          enableNext = _toController
+                                                  .text.isNotEmpty &&
+                                              _refundController.text.isNotEmpty;
+                                        });
                                       });
-                                    });
-                                  } catch (e, s) {
-                                    Logging.instance
-                                        .log("$e\n$s", level: LogLevel.Info);
-                                  }
-                                },
-                              ),
-                          ],
-                        ),
-                        const SizedBox(
-                          height: 4,
-                        ),
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
+                                    } catch (e, s) {
+                                      Logging.instance
+                                          .log("$e\n$s", level: LogLevel.Info);
+                                    }
+                                  },
+                                ),
+                            ],
                           ),
-                          child: TextField(
-                            key: const Key(
-                                "refundExchangeStep2ViewAddressFieldKey"),
-                            controller: _refundController,
-                            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,
+                          const SizedBox(
+                            height: 4,
+                          ),
+                          ClipRRect(
+                            borderRadius: BorderRadius.circular(
+                              Constants.size.circularBorderRadius,
                             ),
-                            focusNode: _refundFocusNode,
-                            style: STextStyles.field(context),
-                            onChanged: (value) {
-                              setState(() {});
-                            },
-                            decoration: standardInputDecoration(
-                              "Enter ${model.sendTicker.toUpperCase()} refund address",
-                              _refundFocusNode,
-                              context,
-                            ).copyWith(
-                              contentPadding: const EdgeInsets.only(
-                                left: 16,
-                                top: 6,
-                                bottom: 8,
-                                right: 5,
+                            child: TextField(
+                              key: const Key(
+                                  "refundExchangeStep2ViewAddressFieldKey"),
+                              controller: _refundController,
+                              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: _refundController.text.isEmpty
-                                    ? const EdgeInsets.only(right: 16)
-                                    : const EdgeInsets.only(right: 0),
-                                child: UnconstrainedBox(
-                                  child: Row(
-                                    mainAxisAlignment:
-                                        MainAxisAlignment.spaceAround,
-                                    children: [
-                                      _refundController.text.isNotEmpty
-                                          ? TextFieldIconButton(
-                                              key: const Key(
-                                                  "sendViewClearAddressFieldButtonKey"),
-                                              onTap: () {
-                                                _refundController.text = "";
-                                                model.refundAddress =
-                                                    _refundController.text;
+                              focusNode: _refundFocusNode,
+                              style: STextStyles.field(context),
+                              onChanged: (value) {
+                                setState(() {});
+                              },
+                              decoration: standardInputDecoration(
+                                "Enter ${model.sendTicker.toUpperCase()} refund address",
+                                _refundFocusNode,
+                                context,
+                              ).copyWith(
+                                contentPadding: const EdgeInsets.only(
+                                  left: 16,
+                                  top: 6,
+                                  bottom: 8,
+                                  right: 5,
+                                ),
+                                suffixIcon: Padding(
+                                  padding: _refundController.text.isEmpty
+                                      ? const EdgeInsets.only(right: 16)
+                                      : const EdgeInsets.only(right: 0),
+                                  child: UnconstrainedBox(
+                                    child: Row(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceAround,
+                                      children: [
+                                        _refundController.text.isNotEmpty
+                                            ? TextFieldIconButton(
+                                                key: const Key(
+                                                    "sendViewClearAddressFieldButtonKey"),
+                                                onTap: () {
+                                                  _refundController.text = "";
+                                                  model.refundAddress =
+                                                      _refundController.text;
 
+                                                  setState(() {
+                                                    enableNext = _toController
+                                                            .text.isNotEmpty &&
+                                                        _refundController
+                                                            .text.isNotEmpty;
+                                                  });
+                                                },
+                                                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) {
+                                                    final content =
+                                                        data.text!.trim();
+
+                                                    _refundController.text =
+                                                        content;
+                                                    model.refundAddress =
+                                                        _refundController.text;
+
+                                                    setState(() {
+                                                      enableNext = _toController
+                                                              .text
+                                                              .isNotEmpty &&
+                                                          _refundController
+                                                              .text.isNotEmpty;
+                                                    });
+                                                  }
+                                                },
+                                                child: _refundController
+                                                        .text.isEmpty
+                                                    ? const ClipboardIcon()
+                                                    : const XIcon(),
+                                              ),
+                                        if (_refundController.text.isEmpty)
+                                          TextFieldIconButton(
+                                            key: const Key(
+                                                "sendViewAddressBookButtonKey"),
+                                            onTap: () {
+                                              ref
+                                                  .read(
+                                                      exchangeFlowIsActiveStateProvider
+                                                          .state)
+                                                  .state = true;
+                                              Navigator.of(context)
+                                                  .pushNamed(
+                                                AddressBookView.routeName,
+                                              )
+                                                  .then((_) {
+                                                ref
+                                                    .read(
+                                                        exchangeFlowIsActiveStateProvider
+                                                            .state)
+                                                    .state = false;
+                                                final address = ref
+                                                    .read(
+                                                        exchangeFromAddressBookAddressStateProvider
+                                                            .state)
+                                                    .state;
+                                                if (address.isNotEmpty) {
+                                                  _refundController.text =
+                                                      address;
+                                                  model.refundAddress =
+                                                      _refundController.text;
+                                                }
                                                 setState(() {
                                                   enableNext = _toController
                                                           .text.isNotEmpty &&
                                                       _refundController
                                                           .text.isNotEmpty;
                                                 });
-                                              },
-                                              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) {
-                                                  final content =
-                                                      data.text!.trim();
+                                              });
+                                            },
+                                            child: const AddressBookIcon(),
+                                          ),
+                                        if (_refundController.text.isEmpty)
+                                          TextFieldIconButton(
+                                            key: const Key(
+                                                "sendViewScanQrButtonKey"),
+                                            onTap: () async {
+                                              try {
+                                                final qrResult =
+                                                    await scanner.scan();
 
+                                                final results =
+                                                    AddressUtils.parseUri(
+                                                        qrResult.rawContent);
+                                                if (results.isNotEmpty) {
+                                                  // auto fill address
                                                   _refundController.text =
-                                                      content;
+                                                      results["address"] ?? "";
+                                                  model.refundAddress =
+                                                      _refundController.text;
+
+                                                  setState(() {
+                                                    enableNext = _toController
+                                                            .text.isNotEmpty &&
+                                                        _refundController
+                                                            .text.isNotEmpty;
+                                                  });
+                                                } else {
+                                                  _refundController.text =
+                                                      qrResult.rawContent;
                                                   model.refundAddress =
                                                       _refundController.text;
 
@@ -566,162 +663,78 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                                             .text.isNotEmpty;
                                                   });
                                                 }
-                                              },
-                                              child:
-                                                  _refundController.text.isEmpty
-                                                      ? const ClipboardIcon()
-                                                      : const XIcon(),
-                                            ),
-                                      if (_refundController.text.isEmpty)
-                                        TextFieldIconButton(
-                                          key: const Key(
-                                              "sendViewAddressBookButtonKey"),
-                                          onTap: () {
-                                            ref
-                                                .read(
-                                                    exchangeFlowIsActiveStateProvider
-                                                        .state)
-                                                .state = true;
-                                            Navigator.of(context)
-                                                .pushNamed(
-                                              AddressBookView.routeName,
-                                            )
-                                                .then((_) {
-                                              ref
-                                                  .read(
-                                                      exchangeFlowIsActiveStateProvider
-                                                          .state)
-                                                  .state = false;
-                                              final address = ref
-                                                  .read(
-                                                      exchangeFromAddressBookAddressStateProvider
-                                                          .state)
-                                                  .state;
-                                              if (address.isNotEmpty) {
-                                                _refundController.text =
-                                                    address;
-                                                model.refundAddress =
-                                                    _refundController.text;
+                                              } on PlatformException catch (e, s) {
+                                                Logging.instance.log(
+                                                  "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
+                                                  level: LogLevel.Warning,
+                                                );
                                               }
-                                              setState(() {
-                                                enableNext = _toController
-                                                        .text.isNotEmpty &&
-                                                    _refundController
-                                                        .text.isNotEmpty;
-                                              });
-                                            });
-                                          },
-                                          child: const AddressBookIcon(),
-                                        ),
-                                      if (_refundController.text.isEmpty)
-                                        TextFieldIconButton(
-                                          key: const Key(
-                                              "sendViewScanQrButtonKey"),
-                                          onTap: () async {
-                                            try {
-                                              final qrResult =
-                                                  await scanner.scan();
-
-                                              final results =
-                                                  AddressUtils.parseUri(
-                                                      qrResult.rawContent);
-                                              if (results.isNotEmpty) {
-                                                // auto fill address
-                                                _refundController.text =
-                                                    results["address"] ?? "";
-                                                model.refundAddress =
-                                                    _refundController.text;
-
-                                                setState(() {
-                                                  enableNext = _toController
-                                                          .text.isNotEmpty &&
-                                                      _refundController
-                                                          .text.isNotEmpty;
-                                                });
-                                              } else {
-                                                _refundController.text =
-                                                    qrResult.rawContent;
-                                                model.refundAddress =
-                                                    _refundController.text;
-
-                                                setState(() {
-                                                  enableNext = _toController
-                                                          .text.isNotEmpty &&
-                                                      _refundController
-                                                          .text.isNotEmpty;
-                                                });
-                                              }
-                                            } on PlatformException catch (e, s) {
-                                              Logging.instance.log(
-                                                "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
-                                                level: LogLevel.Warning,
-                                              );
-                                            }
-                                          },
-                                          child: const QrCodeIcon(),
-                                        ),
-                                    ],
+                                            },
+                                            child: const QrCodeIcon(),
+                                          ),
+                                      ],
+                                    ),
                                   ),
                                 ),
                               ),
                             ),
                           ),
-                        ),
-                        const SizedBox(
-                          height: 6,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Text(
-                            "In case something goes wrong during the exchange, we might need a refund address so we can return your coins back to you.",
-                            style: STextStyles.label(context),
+                          const SizedBox(
+                            height: 6,
                           ),
-                        ),
-                        const Spacer(),
-                        Row(
-                          children: [
-                            Expanded(
-                              child: TextButton(
-                                onPressed: () {
-                                  Navigator.of(context).pop();
-                                },
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getSecondaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Back",
-                                  style: STextStyles.button(context).copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .buttonTextSecondary,
+                          RoundedWhiteContainer(
+                            child: Text(
+                              "In case something goes wrong during the exchange, we might need a refund address so we can return your coins back to you.",
+                              style: STextStyles.label(context),
+                            ),
+                          ),
+                          const Spacer(),
+                          Row(
+                            children: [
+                              Expanded(
+                                child: TextButton(
+                                  onPressed: () {
+                                    Navigator.of(context).pop();
+                                  },
+                                  style: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .getSecondaryEnabledButtonColor(context),
+                                  child: Text(
+                                    "Back",
+                                    style: STextStyles.button(context).copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .buttonTextSecondary,
+                                    ),
                                   ),
                                 ),
                               ),
-                            ),
-                            const SizedBox(
-                              width: 16,
-                            ),
-                            Expanded(
-                              child: PrimaryButton(
-                                label: "Next",
-                                enabled: enableNext,
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                    Step3View.routeName,
-                                    arguments: model,
-                                  );
-                                },
+                              const SizedBox(
+                                width: 16,
                               ),
-                            ),
-                          ],
-                        ),
-                      ],
+                              Expanded(
+                                child: PrimaryButton(
+                                  label: "Next",
+                                  enabled: enableNext,
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                      Step3View.routeName,
+                                      arguments: model,
+                                    );
+                                  },
+                                ),
+                              ),
+                            ],
+                          ),
+                        ],
+                      ),
                     ),
                   ),
                 ),
               ),
-            ),
-          );
-        },
+            );
+          },
+        ),
       ),
     );
   }
diff --git a/lib/pages/exchange_view/exchange_step_views/step_3_view.dart b/lib/pages/exchange_view/exchange_step_views/step_3_view.dart
index 0f03d4216..467a3b9e7 100644
--- a/lib/pages/exchange_view/exchange_step_views/step_3_view.dart
+++ b/lib/pages/exchange_view/exchange_step_views/step_3_view.dart
@@ -15,6 +15,7 @@ import 'package:stackwallet/utilities/assets.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_loading_overlay.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -50,290 +51,295 @@ class _Step3ViewState extends ConsumerState<Step3View> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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();
-            }
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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(
+            "Exchange",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Exchange",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (context, constraints) {
-          final width = MediaQuery.of(context).size.width - 32;
-          return Padding(
-            padding: const EdgeInsets.all(12),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        StepRow(
-                          count: 4,
-                          current: 2,
-                          width: width,
-                        ),
-                        const SizedBox(
-                          height: 14,
-                        ),
-                        Text(
-                          "Confirm exchange details",
-                          style: STextStyles.pageTitleH1(context),
-                        ),
-                        const SizedBox(
-                          height: 24,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            children: [
-                              Text(
-                                "You send",
-                                style: STextStyles.itemSubtitle(context),
-                              ),
-                              const Spacer(),
-                              Text(
-                                "${model.sendAmount.toString()} ${model.sendTicker.toUpperCase()}",
-                                style: STextStyles.itemSubtitle12(context),
-                              )
-                            ],
+        body: LayoutBuilder(
+          builder: (context, constraints) {
+            final width = MediaQuery.of(context).size.width - 32;
+            return Padding(
+              padding: const EdgeInsets.all(12),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          StepRow(
+                            count: 4,
+                            current: 2,
+                            width: width,
                           ),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            children: [
-                              Text(
-                                "You receive",
-                                style: STextStyles.itemSubtitle(context),
-                              ),
-                              const Spacer(),
-                              Text(
-                                "${model.receiveAmount.toString()} ${model.receiveTicker.toUpperCase()}",
-                                style: STextStyles.itemSubtitle12(context),
-                              )
-                            ],
+                          const SizedBox(
+                            height: 14,
                           ),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            children: [
-                              Text(
-                                "Estimated rate",
-                                style: STextStyles.itemSubtitle(context),
-                              ),
-                              const Spacer(),
-                              Text(
-                                model.rateInfo,
-                                style: STextStyles.itemSubtitle12(context),
-                              )
-                            ],
+                          Text(
+                            "Confirm exchange details",
+                            style: STextStyles.pageTitleH1(context),
                           ),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              Text(
-                                "Recipient ${model.receiveTicker.toUpperCase()} address",
-                                style: STextStyles.itemSubtitle(context),
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              Text(
-                                model.recipientAddress!,
-                                style: STextStyles.itemSubtitle12(context),
-                              )
-                            ],
+                          const SizedBox(
+                            height: 24,
                           ),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              Text(
-                                "Refund ${model.sendTicker.toUpperCase()} address",
-                                style: STextStyles.itemSubtitle(context),
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              Text(
-                                model.refundAddress!,
-                                style: STextStyles.itemSubtitle12(context),
-                              )
-                            ],
+                          RoundedWhiteContainer(
+                            child: Row(
+                              children: [
+                                Text(
+                                  "You send",
+                                  style: STextStyles.itemSubtitle(context),
+                                ),
+                                const Spacer(),
+                                Text(
+                                  "${model.sendAmount.toString()} ${model.sendTicker.toUpperCase()}",
+                                  style: STextStyles.itemSubtitle12(context),
+                                )
+                              ],
+                            ),
                           ),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        const Spacer(),
-                        Row(
-                          children: [
-                            Expanded(
-                              child: TextButton(
-                                onPressed: () {
-                                  Navigator.of(context).pop();
-                                },
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getSecondaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Back",
-                                  style: STextStyles.button(context).copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .buttonTextSecondary,
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Row(
+                              children: [
+                                Text(
+                                  "You receive",
+                                  style: STextStyles.itemSubtitle(context),
+                                ),
+                                const Spacer(),
+                                Text(
+                                  "${model.receiveAmount.toString()} ${model.receiveTicker.toUpperCase()}",
+                                  style: STextStyles.itemSubtitle12(context),
+                                )
+                              ],
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Row(
+                              children: [
+                                Text(
+                                  "Estimated rate",
+                                  style: STextStyles.itemSubtitle(context),
+                                ),
+                                const Spacer(),
+                                Text(
+                                  model.rateInfo,
+                                  style: STextStyles.itemSubtitle12(context),
+                                )
+                              ],
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Column(
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                Text(
+                                  "Recipient ${model.receiveTicker.toUpperCase()} address",
+                                  style: STextStyles.itemSubtitle(context),
+                                ),
+                                const SizedBox(
+                                  height: 4,
+                                ),
+                                Text(
+                                  model.recipientAddress!,
+                                  style: STextStyles.itemSubtitle12(context),
+                                )
+                              ],
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Column(
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                Text(
+                                  "Refund ${model.sendTicker.toUpperCase()} address",
+                                  style: STextStyles.itemSubtitle(context),
+                                ),
+                                const SizedBox(
+                                  height: 4,
+                                ),
+                                Text(
+                                  model.refundAddress!,
+                                  style: STextStyles.itemSubtitle12(context),
+                                )
+                              ],
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          const Spacer(),
+                          Row(
+                            children: [
+                              Expanded(
+                                child: TextButton(
+                                  onPressed: () {
+                                    Navigator.of(context).pop();
+                                  },
+                                  style: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .getSecondaryEnabledButtonColor(context),
+                                  child: Text(
+                                    "Back",
+                                    style: STextStyles.button(context).copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .buttonTextSecondary,
+                                    ),
                                   ),
                                 ),
                               ),
-                            ),
-                            const SizedBox(
-                              width: 16,
-                            ),
-                            Expanded(
-                              child: TextButton(
-                                onPressed: () async {
-                                  unawaited(
-                                    showDialog<void>(
-                                      context: context,
-                                      barrierDismissible: false,
-                                      builder: (_) => WillPopScope(
-                                        onWillPop: () async => false,
-                                        child: Container(
-                                          color: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .overlay
-                                              .withOpacity(0.6),
-                                          child: const CustomLoadingOverlay(
-                                            message: "Creating a trade",
-                                            eventBus: null,
+                              const SizedBox(
+                                width: 16,
+                              ),
+                              Expanded(
+                                child: TextButton(
+                                  onPressed: () async {
+                                    unawaited(
+                                      showDialog<void>(
+                                        context: context,
+                                        barrierDismissible: false,
+                                        builder: (_) => WillPopScope(
+                                          onWillPop: () async => false,
+                                          child: Container(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .overlay
+                                                .withOpacity(0.6),
+                                            child: const CustomLoadingOverlay(
+                                              message: "Creating a trade",
+                                              eventBus: null,
+                                            ),
                                           ),
                                         ),
                                       ),
-                                    ),
-                                  );
+                                    );
 
-                                  final ExchangeResponse<Trade> response =
-                                      await ref
-                                          .read(exchangeProvider)
-                                          .createTrade(
-                                            from: model.sendTicker,
-                                            to: model.receiveTicker,
-                                            fixedRate: model.rateType !=
-                                                ExchangeRateType.estimated,
-                                            amount: model.reversed
-                                                ? model.receiveAmount
-                                                : model.sendAmount,
-                                            addressTo: model.recipientAddress!,
-                                            extraId: null,
-                                            addressRefund: model.refundAddress!,
-                                            refundExtraId: "",
-                                            rateId: model.rateId,
-                                            reversed: model.reversed,
-                                          );
+                                    final ExchangeResponse<Trade> response =
+                                        await ref
+                                            .read(exchangeProvider)
+                                            .createTrade(
+                                              from: model.sendTicker,
+                                              to: model.receiveTicker,
+                                              fixedRate: model.rateType !=
+                                                  ExchangeRateType.estimated,
+                                              amount: model.reversed
+                                                  ? model.receiveAmount
+                                                  : model.sendAmount,
+                                              addressTo:
+                                                  model.recipientAddress!,
+                                              extraId: null,
+                                              addressRefund:
+                                                  model.refundAddress!,
+                                              refundExtraId: "",
+                                              rateId: model.rateId,
+                                              reversed: model.reversed,
+                                            );
+
+                                    if (response.value == null) {
+                                      if (mounted) {
+                                        Navigator.of(context).pop();
+                                      }
+
+                                      unawaited(showDialog<void>(
+                                        context: context,
+                                        barrierDismissible: true,
+                                        builder: (_) => StackDialog(
+                                          title: "Failed to create trade",
+                                          message:
+                                              response.exception?.toString(),
+                                        ),
+                                      ));
+                                      return;
+                                    }
+
+                                    // save trade to hive
+                                    await ref.read(tradesServiceProvider).add(
+                                          trade: response.value!,
+                                          shouldNotifyListeners: true,
+                                        );
+
+                                    String status = response.value!.status;
+
+                                    model.trade = response.value!;
+
+                                    // extra info if status is waiting
+                                    if (status == "Waiting") {
+                                      status += " for deposit";
+                                    }
 
-                                  if (response.value == null) {
                                     if (mounted) {
                                       Navigator.of(context).pop();
                                     }
 
-                                    unawaited(showDialog<void>(
-                                      context: context,
-                                      barrierDismissible: true,
-                                      builder: (_) => StackDialog(
-                                        title: "Failed to create trade",
-                                        message: response.exception?.toString(),
-                                      ),
+                                    unawaited(NotificationApi.showNotification(
+                                      changeNowId: model.trade!.tradeId,
+                                      title: status,
+                                      body: "Trade ID ${model.trade!.tradeId}",
+                                      walletId: "",
+                                      iconAssetName: Assets.svg.arrowRotate,
+                                      date: model.trade!.timestamp,
+                                      shouldWatchForUpdates: true,
+                                      coinName: "coinName",
                                     ));
-                                    return;
-                                  }
 
-                                  // save trade to hive
-                                  await ref.read(tradesServiceProvider).add(
-                                        trade: response.value!,
-                                        shouldNotifyListeners: true,
-                                      );
-
-                                  String status = response.value!.status;
-
-                                  model.trade = response.value!;
-
-                                  // extra info if status is waiting
-                                  if (status == "Waiting") {
-                                    status += " for deposit";
-                                  }
-
-                                  if (mounted) {
-                                    Navigator.of(context).pop();
-                                  }
-
-                                  unawaited(NotificationApi.showNotification(
-                                    changeNowId: model.trade!.tradeId,
-                                    title: status,
-                                    body: "Trade ID ${model.trade!.tradeId}",
-                                    walletId: "",
-                                    iconAssetName: Assets.svg.arrowRotate,
-                                    date: model.trade!.timestamp,
-                                    shouldWatchForUpdates: true,
-                                    coinName: "coinName",
-                                  ));
-
-                                  if (mounted) {
-                                    unawaited(Navigator.of(context).pushNamed(
-                                      Step4View.routeName,
-                                      arguments: model,
-                                    ));
-                                  }
-                                },
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getPrimaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Next",
-                                  style: STextStyles.button(context),
+                                    if (mounted) {
+                                      unawaited(Navigator.of(context).pushNamed(
+                                        Step4View.routeName,
+                                        arguments: model,
+                                      ));
+                                    }
+                                  },
+                                  style: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .getPrimaryEnabledButtonColor(context),
+                                  child: Text(
+                                    "Next",
+                                    style: STextStyles.button(context),
+                                  ),
                                 ),
                               ),
-                            ),
-                          ],
-                        ),
-                      ],
+                            ],
+                          ),
+                        ],
+                      ),
                     ),
                   ),
                 ),
               ),
-            ),
-          );
-        },
+            );
+          },
+        ),
       ),
     );
   }
diff --git a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
index f5975a277..101ac637f 100644
--- a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
+++ b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
@@ -21,6 +21,7 @@ import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -106,539 +107,548 @@ class _Step4ViewState extends ConsumerState<Step4View> {
   Widget build(BuildContext context) {
     final bool isWalletCoin =
         _isWalletCoinAndHasWallet(model.trade!.payInCurrency, ref);
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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();
-            }
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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(
+            "Exchange",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Exchange",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (context, constraints) {
-          final width = MediaQuery.of(context).size.width - 32;
-          return Padding(
-            padding: const EdgeInsets.all(12),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        StepRow(
-                          count: 4,
-                          current: 3,
-                          width: width,
-                        ),
-                        const SizedBox(
-                          height: 14,
-                        ),
-                        Text(
-                          "Send ${model.sendTicker.toUpperCase()} to the address below",
-                          style: STextStyles.pageTitleH1(context),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        Text(
-                          "Send ${model.sendTicker.toUpperCase()} to the address below. Once it is received, ${model.trade!.exchangeName} will send the ${model.receiveTicker.toUpperCase()} to the recipient address you provided. You can find this trade details and check its status in the list of trades.",
-                          style: STextStyles.itemSubtitle(context),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedContainer(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .warningBackground,
-                          child: RichText(
-                            text: TextSpan(
-                              text:
-                                  "You must send at least ${model.sendAmount.toString()} ${model.sendTicker}. ",
-                              style: STextStyles.label700(context).copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .warningForeground,
+        body: LayoutBuilder(
+          builder: (context, constraints) {
+            final width = MediaQuery.of(context).size.width - 32;
+            return Padding(
+              padding: const EdgeInsets.all(12),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          StepRow(
+                            count: 4,
+                            current: 3,
+                            width: width,
+                          ),
+                          const SizedBox(
+                            height: 14,
+                          ),
+                          Text(
+                            "Send ${model.sendTicker.toUpperCase()} to the address below",
+                            style: STextStyles.pageTitleH1(context),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          Text(
+                            "Send ${model.sendTicker.toUpperCase()} to the address below. Once it is received, ${model.trade!.exchangeName} will send the ${model.receiveTicker.toUpperCase()} to the recipient address you provided. You can find this trade details and check its status in the list of trades.",
+                            style: STextStyles.itemSubtitle(context),
+                          ),
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          RoundedContainer(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .warningBackground,
+                            child: RichText(
+                              text: TextSpan(
+                                text:
+                                    "You must send at least ${model.sendAmount.toString()} ${model.sendTicker}. ",
+                                style: STextStyles.label700(context).copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .warningForeground,
+                                ),
+                                children: [
+                                  TextSpan(
+                                    text:
+                                        "If you send less than ${model.sendAmount.toString()} ${model.sendTicker}, your transaction may not be converted and it may not be refunded.",
+                                    style: STextStyles.label(context).copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .warningForeground,
+                                    ),
+                                  ),
+                                ],
                               ),
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Column(
+                              crossAxisAlignment: CrossAxisAlignment.start,
                               children: [
-                                TextSpan(
-                                  text:
-                                      "If you send less than ${model.sendAmount.toString()} ${model.sendTicker}, your transaction may not be converted and it may not be refunded.",
-                                  style: STextStyles.label(context).copyWith(
+                                Row(
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  children: [
+                                    Text(
+                                      "Amount",
+                                      style: STextStyles.itemSubtitle(context),
+                                    ),
+                                    GestureDetector(
+                                      onTap: () async {
+                                        final data = ClipboardData(
+                                            text: model.sendAmount.toString());
+                                        await clipboard.setData(data);
+                                        unawaited(showFloatingFlushBar(
+                                          type: FlushBarType.info,
+                                          message: "Copied to clipboard",
+                                          context: context,
+                                        ));
+                                      },
+                                      child: Row(
+                                        children: [
+                                          SvgPicture.asset(
+                                            Assets.svg.copy,
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .infoItemIcons,
+                                            width: 10,
+                                          ),
+                                          const SizedBox(
+                                            width: 4,
+                                          ),
+                                          Text(
+                                            "Copy",
+                                            style: STextStyles.link2(context),
+                                          ),
+                                        ],
+                                      ),
+                                    ),
+                                  ],
+                                ),
+                                const SizedBox(
+                                  height: 4,
+                                ),
+                                Text(
+                                  "${model.sendAmount.toString()} ${model.sendTicker.toUpperCase()}",
+                                  style: STextStyles.itemSubtitle12(context),
+                                ),
+                              ],
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Column(
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                Row(
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  children: [
+                                    Text(
+                                      "Send ${model.sendTicker.toUpperCase()} to this address",
+                                      style: STextStyles.itemSubtitle(context),
+                                    ),
+                                    GestureDetector(
+                                      onTap: () async {
+                                        final data = ClipboardData(
+                                            text: model.trade!.payInAddress);
+                                        await clipboard.setData(data);
+                                        unawaited(showFloatingFlushBar(
+                                          type: FlushBarType.info,
+                                          message: "Copied to clipboard",
+                                          context: context,
+                                        ));
+                                      },
+                                      child: Row(
+                                        children: [
+                                          SvgPicture.asset(
+                                            Assets.svg.copy,
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .infoItemIcons,
+                                            width: 10,
+                                          ),
+                                          const SizedBox(
+                                            width: 4,
+                                          ),
+                                          Text(
+                                            "Copy",
+                                            style: STextStyles.link2(context),
+                                          ),
+                                        ],
+                                      ),
+                                    ),
+                                  ],
+                                ),
+                                const SizedBox(
+                                  height: 4,
+                                ),
+                                Text(
+                                  model.trade!.payInAddress,
+                                  style: STextStyles.itemSubtitle12(context),
+                                ),
+                              ],
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 6,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Row(
+                              children: [
+                                Text(
+                                  "Trade ID",
+                                  style: STextStyles.itemSubtitle(context),
+                                ),
+                                const Spacer(),
+                                Row(
+                                  children: [
+                                    Text(
+                                      model.trade!.tradeId,
+                                      style:
+                                          STextStyles.itemSubtitle12(context),
+                                    ),
+                                    const SizedBox(
+                                      width: 10,
+                                    ),
+                                    GestureDetector(
+                                      onTap: () async {
+                                        final data = ClipboardData(
+                                            text: model.trade!.tradeId);
+                                        await clipboard.setData(data);
+                                        unawaited(showFloatingFlushBar(
+                                          type: FlushBarType.info,
+                                          message: "Copied to clipboard",
+                                          context: context,
+                                        ));
+                                      },
+                                      child: SvgPicture.asset(
+                                        Assets.svg.copy,
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .infoItemIcons,
+                                        width: 12,
+                                      ),
+                                    )
+                                  ],
+                                )
+                              ],
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 6,
+                          ),
+                          RoundedWhiteContainer(
+                            child: Row(
+                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                              children: [
+                                Text(
+                                  "Status",
+                                  style: STextStyles.itemSubtitle(context),
+                                ),
+                                Text(
+                                  _statusString,
+                                  style: STextStyles.itemSubtitle(context)
+                                      .copyWith(
                                     color: Theme.of(context)
                                         .extension<StackColors>()!
-                                        .warningForeground,
+                                        .colorForStatus(_statusString),
                                   ),
                                 ),
                               ],
                             ),
                           ),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              Row(
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
-                                children: [
-                                  Text(
-                                    "Amount",
-                                    style: STextStyles.itemSubtitle(context),
-                                  ),
-                                  GestureDetector(
-                                    onTap: () async {
-                                      final data = ClipboardData(
-                                          text: model.sendAmount.toString());
-                                      await clipboard.setData(data);
-                                      unawaited(showFloatingFlushBar(
-                                        type: FlushBarType.info,
-                                        message: "Copied to clipboard",
-                                        context: context,
-                                      ));
-                                    },
-                                    child: Row(
-                                      children: [
-                                        SvgPicture.asset(
-                                          Assets.svg.copy,
-                                          color: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .infoItemIcons,
-                                          width: 10,
-                                        ),
-                                        const SizedBox(
-                                          width: 4,
-                                        ),
-                                        Text(
-                                          "Copy",
-                                          style: STextStyles.link2(context),
-                                        ),
-                                      ],
-                                    ),
-                                  ),
-                                ],
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              Text(
-                                "${model.sendAmount.toString()} ${model.sendTicker.toUpperCase()}",
-                                style: STextStyles.itemSubtitle12(context),
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Column(
-                            crossAxisAlignment: CrossAxisAlignment.start,
-                            children: [
-                              Row(
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
-                                children: [
-                                  Text(
-                                    "Send ${model.sendTicker.toUpperCase()} to this address",
-                                    style: STextStyles.itemSubtitle(context),
-                                  ),
-                                  GestureDetector(
-                                    onTap: () async {
-                                      final data = ClipboardData(
-                                          text: model.trade!.payInAddress);
-                                      await clipboard.setData(data);
-                                      unawaited(showFloatingFlushBar(
-                                        type: FlushBarType.info,
-                                        message: "Copied to clipboard",
-                                        context: context,
-                                      ));
-                                    },
-                                    child: Row(
-                                      children: [
-                                        SvgPicture.asset(
-                                          Assets.svg.copy,
-                                          color: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .infoItemIcons,
-                                          width: 10,
-                                        ),
-                                        const SizedBox(
-                                          width: 4,
-                                        ),
-                                        Text(
-                                          "Copy",
-                                          style: STextStyles.link2(context),
-                                        ),
-                                      ],
-                                    ),
-                                  ),
-                                ],
-                              ),
-                              const SizedBox(
-                                height: 4,
-                              ),
-                              Text(
-                                model.trade!.payInAddress,
-                                style: STextStyles.itemSubtitle12(context),
-                              ),
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 6,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            children: [
-                              Text(
-                                "Trade ID",
-                                style: STextStyles.itemSubtitle(context),
-                              ),
-                              const Spacer(),
-                              Row(
-                                children: [
-                                  Text(
-                                    model.trade!.tradeId,
-                                    style: STextStyles.itemSubtitle12(context),
-                                  ),
-                                  const SizedBox(
-                                    width: 10,
-                                  ),
-                                  GestureDetector(
-                                    onTap: () async {
-                                      final data = ClipboardData(
-                                          text: model.trade!.tradeId);
-                                      await clipboard.setData(data);
-                                      unawaited(showFloatingFlushBar(
-                                        type: FlushBarType.info,
-                                        message: "Copied to clipboard",
-                                        context: context,
-                                      ));
-                                    },
-                                    child: SvgPicture.asset(
-                                      Assets.svg.copy,
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .infoItemIcons,
-                                      width: 12,
-                                    ),
-                                  )
-                                ],
-                              )
-                            ],
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 6,
-                        ),
-                        RoundedWhiteContainer(
-                          child: Row(
-                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                            children: [
-                              Text(
-                                "Status",
-                                style: STextStyles.itemSubtitle(context),
-                              ),
-                              Text(
-                                _statusString,
-                                style:
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .colorForStatus(_statusString),
-                                ),
-                              ),
-                            ],
-                          ),
-                        ),
-                        const Spacer(),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        TextButton(
-                          onPressed: () {
-                            showDialog<dynamic>(
-                              context: context,
-                              barrierDismissible: true,
-                              builder: (_) {
-                                return StackDialogBase(
-                                  child: Column(
-                                    children: [
-                                      const SizedBox(
-                                        height: 8,
-                                      ),
-                                      Center(
-                                        child: Text(
-                                          "Send ${model.sendTicker} to this address",
-                                          style:
-                                              STextStyles.pageTitleH2(context),
-                                        ),
-                                      ),
-                                      const SizedBox(
-                                        height: 24,
-                                      ),
-                                      Center(
-                                        child: QrImage(
-                                          // TODO: grab coin uri scheme from somewhere
-                                          // data: "${coin.uriScheme}:$receivingAddress",
-                                          data: model.trade!.payInAddress,
-                                          size: MediaQuery.of(context)
-                                                  .size
-                                                  .width /
-                                              2,
-                                          foregroundColor: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .accentColorDark,
-                                        ),
-                                      ),
-                                      const SizedBox(
-                                        height: 24,
-                                      ),
-                                      Row(
-                                        children: [
-                                          const Spacer(),
-                                          Expanded(
-                                            child: TextButton(
-                                              onPressed: () =>
-                                                  Navigator.of(context).pop(),
-                                              style: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .getSecondaryEnabledButtonColor(
-                                                      context),
-                                              child: Text(
-                                                "Cancel",
-                                                style:
-                                                    STextStyles.button(context)
-                                                        .copyWith(
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .buttonTextSecondary,
-                                                ),
-                                              ),
-                                            ),
-                                          ),
-                                        ],
-                                      )
-                                    ],
-                                  ),
-                                );
-                              },
-                            );
-                          },
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context),
-                          child: Text(
-                            "Show QR Code",
-                            style: STextStyles.button(context),
-                          ),
-                        ),
-                        if (isWalletCoin)
+                          const Spacer(),
                           const SizedBox(
                             height: 12,
                           ),
-                        if (isWalletCoin)
-                          Builder(
-                            builder: (context) {
-                              String buttonTitle = "Send from Stack Wallet";
-
-                              final tuple = ref
-                                  .read(exchangeSendFromWalletIdStateProvider
-                                      .state)
-                                  .state;
-                              if (tuple != null &&
-                                  model.sendTicker.toLowerCase() ==
-                                      tuple.item2.ticker.toLowerCase()) {
-                                final walletName = ref
-                                    .read(walletsChangeNotifierProvider)
-                                    .getManager(tuple.item1)
-                                    .walletName;
-                                buttonTitle = "Send from $walletName";
-                              }
-
-                              return TextButton(
-                                onPressed: tuple != null &&
-                                        model.sendTicker.toLowerCase() ==
-                                            tuple.item2.ticker.toLowerCase()
-                                    ? () async {
-                                        final manager = ref
-                                            .read(walletsChangeNotifierProvider)
-                                            .getManager(tuple.item1);
-
-                                        final amount =
-                                            Format.decimalAmountToSatoshis(
-                                                model.sendAmount, manager.coin);
-                                        final address =
-                                            model.trade!.payInAddress;
-
-                                        try {
-                                          bool wasCancelled = false;
-
-                                          unawaited(showDialog<dynamic>(
-                                            context: context,
-                                            useSafeArea: false,
-                                            barrierDismissible: false,
-                                            builder: (context) {
-                                              return BuildingTransactionDialog(
-                                                onCancel: () {
-                                                  wasCancelled = true;
-
-                                                  Navigator.of(context).pop();
-                                                },
-                                              );
-                                            },
-                                          ));
-
-                                          final txData =
-                                              await manager.prepareSend(
-                                            address: address,
-                                            satoshiAmount: amount,
-                                            args: {
-                                              "feeRate": FeeRateType.average,
-                                              // ref.read(feeRateTypeStateProvider)
-                                            },
-                                          );
-
-                                          if (!wasCancelled) {
-                                            // pop building dialog
-
-                                            if (mounted) {
-                                              Navigator.of(context).pop();
-                                            }
-
-                                            txData["note"] =
-                                                "${model.trade!.payInCurrency.toUpperCase()}/${model.trade!.payOutCurrency.toUpperCase()} exchange";
-                                            txData["address"] = address;
-
-                                            if (mounted) {
-                                              unawaited(
-                                                  Navigator.of(context).push(
-                                                RouteGenerator.getRoute(
-                                                  shouldUseMaterialRoute:
-                                                      RouteGenerator
-                                                          .useMaterialPageRoute,
-                                                  builder: (_) =>
-                                                      ConfirmChangeNowSendView(
-                                                    transactionInfo: txData,
-                                                    walletId: tuple.item1,
-                                                    routeOnSuccessName:
-                                                        HomeView.routeName,
-                                                    trade: model.trade!,
-                                                  ),
-                                                  settings: const RouteSettings(
-                                                    name:
-                                                        ConfirmChangeNowSendView
-                                                            .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>()!
-                                                      .getSecondaryEnabledButtonColor(
-                                                          context),
-                                                  child: Text(
-                                                    "Ok",
-                                                    style: STextStyles.button(
-                                                            context)
-                                                        .copyWith(
-                                                      color: Theme.of(context)
-                                                          .extension<
-                                                              StackColors>()!
-                                                          .buttonTextSecondary,
-                                                    ),
-                                                  ),
-                                                  onPressed: () {
-                                                    Navigator.of(context).pop();
-                                                  },
-                                                ),
-                                              );
-                                            },
-                                          ));
-                                          // }
-                                        }
-                                      }
-                                    : () {
-                                        Navigator.of(context).push(
-                                          RouteGenerator.getRoute(
-                                            shouldUseMaterialRoute:
-                                                RouteGenerator
-                                                    .useMaterialPageRoute,
-                                            builder: (BuildContext context) {
-                                              return SendFromView(
-                                                coin:
-                                                    coinFromTickerCaseInsensitive(
-                                                        model.trade!
-                                                            .payInCurrency),
-                                                amount: model.sendAmount,
-                                                address:
-                                                    model.trade!.payInAddress,
-                                                trade: model.trade!,
-                                              );
-                                            },
-                                            settings: const RouteSettings(
-                                              name: SendFromView.routeName,
-                                            ),
+                          TextButton(
+                            onPressed: () {
+                              showDialog<dynamic>(
+                                context: context,
+                                barrierDismissible: true,
+                                builder: (_) {
+                                  return StackDialogBase(
+                                    child: Column(
+                                      children: [
+                                        const SizedBox(
+                                          height: 8,
+                                        ),
+                                        Center(
+                                          child: Text(
+                                            "Send ${model.sendTicker} to this address",
+                                            style: STextStyles.pageTitleH2(
+                                                context),
                                           ),
-                                        );
-                                      },
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getSecondaryEnabledButtonColor(context),
-                                child: Text(
-                                  buttonTitle,
-                                  style: STextStyles.button(context).copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .buttonTextSecondary,
-                                  ),
-                                ),
+                                        ),
+                                        const SizedBox(
+                                          height: 24,
+                                        ),
+                                        Center(
+                                          child: QrImage(
+                                            // TODO: grab coin uri scheme from somewhere
+                                            // data: "${coin.uriScheme}:$receivingAddress",
+                                            data: model.trade!.payInAddress,
+                                            size: MediaQuery.of(context)
+                                                    .size
+                                                    .width /
+                                                2,
+                                            foregroundColor: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .accentColorDark,
+                                          ),
+                                        ),
+                                        const SizedBox(
+                                          height: 24,
+                                        ),
+                                        Row(
+                                          children: [
+                                            const Spacer(),
+                                            Expanded(
+                                              child: TextButton(
+                                                onPressed: () =>
+                                                    Navigator.of(context).pop(),
+                                                style: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .getSecondaryEnabledButtonColor(
+                                                        context),
+                                                child: Text(
+                                                  "Cancel",
+                                                  style: STextStyles.button(
+                                                          context)
+                                                      .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .buttonTextSecondary,
+                                                  ),
+                                                ),
+                                              ),
+                                            ),
+                                          ],
+                                        )
+                                      ],
+                                    ),
+                                  );
+                                },
                               );
                             },
+                            style: Theme.of(context)
+                                .extension<StackColors>()!
+                                .getPrimaryEnabledButtonColor(context),
+                            child: Text(
+                              "Show QR Code",
+                              style: STextStyles.button(context),
+                            ),
                           ),
-                      ],
+                          if (isWalletCoin)
+                            const SizedBox(
+                              height: 12,
+                            ),
+                          if (isWalletCoin)
+                            Builder(
+                              builder: (context) {
+                                String buttonTitle = "Send from Stack Wallet";
+
+                                final tuple = ref
+                                    .read(exchangeSendFromWalletIdStateProvider
+                                        .state)
+                                    .state;
+                                if (tuple != null &&
+                                    model.sendTicker.toLowerCase() ==
+                                        tuple.item2.ticker.toLowerCase()) {
+                                  final walletName = ref
+                                      .read(walletsChangeNotifierProvider)
+                                      .getManager(tuple.item1)
+                                      .walletName;
+                                  buttonTitle = "Send from $walletName";
+                                }
+
+                                return TextButton(
+                                  onPressed: tuple != null &&
+                                          model.sendTicker.toLowerCase() ==
+                                              tuple.item2.ticker.toLowerCase()
+                                      ? () async {
+                                          final manager = ref
+                                              .read(
+                                                  walletsChangeNotifierProvider)
+                                              .getManager(tuple.item1);
+
+                                          final amount =
+                                              Format.decimalAmountToSatoshis(
+                                                  model.sendAmount,
+                                                  manager.coin);
+                                          final address =
+                                              model.trade!.payInAddress;
+
+                                          try {
+                                            bool wasCancelled = false;
+
+                                            unawaited(showDialog<dynamic>(
+                                              context: context,
+                                              useSafeArea: false,
+                                              barrierDismissible: false,
+                                              builder: (context) {
+                                                return BuildingTransactionDialog(
+                                                  onCancel: () {
+                                                    wasCancelled = true;
+
+                                                    Navigator.of(context).pop();
+                                                  },
+                                                );
+                                              },
+                                            ));
+
+                                            final txData =
+                                                await manager.prepareSend(
+                                              address: address,
+                                              satoshiAmount: amount,
+                                              args: {
+                                                "feeRate": FeeRateType.average,
+                                                // ref.read(feeRateTypeStateProvider)
+                                              },
+                                            );
+
+                                            if (!wasCancelled) {
+                                              // pop building dialog
+
+                                              if (mounted) {
+                                                Navigator.of(context).pop();
+                                              }
+
+                                              txData["note"] =
+                                                  "${model.trade!.payInCurrency.toUpperCase()}/${model.trade!.payOutCurrency.toUpperCase()} exchange";
+                                              txData["address"] = address;
+
+                                              if (mounted) {
+                                                unawaited(
+                                                    Navigator.of(context).push(
+                                                  RouteGenerator.getRoute(
+                                                    shouldUseMaterialRoute:
+                                                        RouteGenerator
+                                                            .useMaterialPageRoute,
+                                                    builder: (_) =>
+                                                        ConfirmChangeNowSendView(
+                                                      transactionInfo: txData,
+                                                      walletId: tuple.item1,
+                                                      routeOnSuccessName:
+                                                          HomeView.routeName,
+                                                      trade: model.trade!,
+                                                    ),
+                                                    settings:
+                                                        const RouteSettings(
+                                                      name:
+                                                          ConfirmChangeNowSendView
+                                                              .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>()!
+                                                        .getSecondaryEnabledButtonColor(
+                                                            context),
+                                                    child: Text(
+                                                      "Ok",
+                                                      style: STextStyles.button(
+                                                              context)
+                                                          .copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .buttonTextSecondary,
+                                                      ),
+                                                    ),
+                                                    onPressed: () {
+                                                      Navigator.of(context)
+                                                          .pop();
+                                                    },
+                                                  ),
+                                                );
+                                              },
+                                            ));
+                                            // }
+                                          }
+                                        }
+                                      : () {
+                                          Navigator.of(context).push(
+                                            RouteGenerator.getRoute(
+                                              shouldUseMaterialRoute:
+                                                  RouteGenerator
+                                                      .useMaterialPageRoute,
+                                              builder: (BuildContext context) {
+                                                return SendFromView(
+                                                  coin:
+                                                      coinFromTickerCaseInsensitive(
+                                                          model.trade!
+                                                              .payInCurrency),
+                                                  amount: model.sendAmount,
+                                                  address:
+                                                      model.trade!.payInAddress,
+                                                  trade: model.trade!,
+                                                );
+                                              },
+                                              settings: const RouteSettings(
+                                                name: SendFromView.routeName,
+                                              ),
+                                            ),
+                                          );
+                                        },
+                                  style: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .getSecondaryEnabledButtonColor(context),
+                                  child: Text(
+                                    buttonTitle,
+                                    style: STextStyles.button(context).copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .buttonTextSecondary,
+                                    ),
+                                  ),
+                                );
+                              },
+                            ),
+                        ],
+                      ),
                     ),
                   ),
                 ),
               ),
-            ),
-          );
-        },
+            );
+          },
+        ),
       ),
     );
   }
diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart
index f13971a67..6a7fe5285 100644
--- a/lib/pages/exchange_view/send_from_view.dart
+++ b/lib/pages/exchange_view/send_from_view.dart
@@ -22,6 +22,7 @@ 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/animated_text.dart';
+import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -85,24 +86,26 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            leading: AppBarBackButton(
-              onPressed: () {
-                Navigator.of(context).pop();
-              },
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              leading: AppBarBackButton(
+                onPressed: () {
+                  Navigator.of(context).pop();
+                },
+              ),
+              title: Text(
+                "Send from",
+                style: STextStyles.navBarTitle(context),
+              ),
             ),
-            title: Text(
-              "Send from",
-              style: STextStyles.navBarTitle(context),
+            body: Padding(
+              padding: const EdgeInsets.all(16),
+              child: child,
             ),
           ),
-          body: Padding(
-            padding: const EdgeInsets.all(16),
-            child: child,
-          ),
         );
       },
       child: ConditionalParent(
diff --git a/lib/pages/exchange_view/trade_details_view.dart b/lib/pages/exchange_view/trade_details_view.dart
index 0b7f4b502..5679d5be5 100644
--- a/lib/pages/exchange_view/trade_details_view.dart
+++ b/lib/pages/exchange_view/trade_details_view.dart
@@ -28,6 +28,7 @@ import 'package:stackwallet/utilities/format.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/custom_buttons/blue_text_button.dart';
@@ -167,27 +168,30 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
 
     return ConditionalParent(
       condition: !isDesktop,
-      builder: (child) => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
+      builder: (child) => Background(
+        child: Scaffold(
           backgroundColor:
               Theme.of(context).extension<StackColors>()!.background,
-          leading: AppBarBackButton(
-            onPressed: () async {
-              Navigator.of(context).pop();
-            },
+          appBar: AppBar(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            leading: AppBarBackButton(
+              onPressed: () async {
+                Navigator.of(context).pop();
+              },
+            ),
+            title: Text(
+              "Trade details",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
-          title: Text(
-            "Trade details",
-            style: STextStyles.navBarTitle(context),
-          ),
-        ),
-        body: Padding(
-          padding: const EdgeInsets.all(12),
-          child: SingleChildScrollView(
-            child: Padding(
-              padding: const EdgeInsets.all(4),
-              child: child,
+          body: Padding(
+            padding: const EdgeInsets.all(12),
+            child: SingleChildScrollView(
+              child: Padding(
+                padding: const EdgeInsets.all(4),
+                child: child,
+              ),
             ),
           ),
         ),
diff --git a/lib/pages/exchange_view/wallet_initiated_exchange_view.dart b/lib/pages/exchange_view/wallet_initiated_exchange_view.dart
index c816d4fe8..915fb33ba 100644
--- a/lib/pages/exchange_view/wallet_initiated_exchange_view.dart
+++ b/lib/pages/exchange_view/wallet_initiated_exchange_view.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.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/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 
 class WalletInitiatedExchangeView extends ConsumerStatefulWidget {
@@ -47,75 +48,77 @@ class _WalletInitiatedExchangeViewState
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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();
-            }
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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(
+            "Exchange",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Exchange",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (context, constraints) {
-          final width = MediaQuery.of(context).size.width - 32;
-          return Padding(
-            padding: const EdgeInsets.all(12),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        StepRow(
-                          count: 4,
-                          current: 0,
-                          width: width,
-                        ),
-                        const SizedBox(
-                          height: 14,
-                        ),
-                        Text(
-                          "Exchange amount",
-                          style: STextStyles.pageTitleH1(context),
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        Text(
-                          "Network fees and other exchange charges are included in the rate.",
-                          style: STextStyles.itemSubtitle(context),
-                        ),
-                        const SizedBox(
-                          height: 24,
-                        ),
-                        ExchangeForm(
-                          walletId: walletId,
-                          coin: coin,
-                        ),
-                      ],
+        body: LayoutBuilder(
+          builder: (context, constraints) {
+            final width = MediaQuery.of(context).size.width - 32;
+            return Padding(
+              padding: const EdgeInsets.all(12),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          StepRow(
+                            count: 4,
+                            current: 0,
+                            width: width,
+                          ),
+                          const SizedBox(
+                            height: 14,
+                          ),
+                          Text(
+                            "Exchange amount",
+                            style: STextStyles.pageTitleH1(context),
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          Text(
+                            "Network fees and other exchange charges are included in the rate.",
+                            style: STextStyles.itemSubtitle(context),
+                          ),
+                          const SizedBox(
+                            height: 24,
+                          ),
+                          ExchangeForm(
+                            walletId: walletId,
+                            coin: coin,
+                          ),
+                        ],
+                      ),
                     ),
                   ),
                 ),
               ),
-            ),
-          );
-        },
+            );
+          },
+        ),
       ),
     );
   }
diff --git a/lib/pages/home_view/home_view.dart b/lib/pages/home_view/home_view.dart
index 33744570b..5f41bfb16 100644
--- a/lib/pages/home_view/home_view.dart
+++ b/lib/pages/home_view/home_view.dart
@@ -20,6 +20,7 @@ import 'package:stackwallet/utilities/constants.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/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
@@ -141,129 +142,138 @@ class _HomeViewState extends ConsumerState<HomeView> {
     debugPrint("BUILD: $runtimeType");
     return WillPopScope(
       onWillPop: _onWillPop,
-      child: Scaffold(
-        key: _key,
-        appBar: AppBar(
-          automaticallyImplyLeading: false,
-          title: Row(
-            children: [
-              GestureDetector(
-                onTap: _hiddenOptions,
-                child: SvgPicture.asset(
-                  Assets.svg.stackIcon(context),
-                  width: 24,
-                  height: 24,
-                ),
-              ),
-              const SizedBox(
-                width: 16,
-              ),
-              Text(
-                "My Stack",
-                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("walletsViewAlertsButton"),
-                  size: 36,
-                  shadows: const [],
-                  color: Theme.of(context).extension<StackColors>()!.background,
-                  icon: SvgPicture.asset(
-                    ref.watch(notificationsProvider
-                            .select((value) => value.hasUnreadNotifications))
-                        ? Assets.svg.bellNew(context)
-                        : Assets.svg.bell,
-                    width: 20,
-                    height: 20,
-                    color: ref.watch(notificationsProvider
-                            .select((value) => value.hasUnreadNotifications))
-                        ? null
-                        : Theme.of(context)
-                            .extension<StackColors>()!
-                            .topNavIconPrimary,
+      child: Background(
+        child: Scaffold(
+          backgroundColor: Colors.transparent,
+          key: _key,
+          appBar: AppBar(
+            automaticallyImplyLeading: false,
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.backgroundAppBar,
+            title: Row(
+              children: [
+                GestureDetector(
+                  onTap: _hiddenOptions,
+                  child: SvgPicture.asset(
+                    Assets.svg.stackIcon(context),
+                    width: 24,
+                    height: 24,
                   ),
-                  onPressed: () {
-                    // reset unread state
-                    ref.refresh(unreadNotificationsStateProvider);
-
-                    Navigator.of(context)
-                        .pushNamed(NotificationsView.routeName)
-                        .then((_) {
-                      final Set<int> unreadNotificationIds = ref
-                          .read(unreadNotificationsStateProvider.state)
-                          .state;
-                      if (unreadNotificationIds.isEmpty) return;
-
-                      List<Future<void>> futures = [];
-                      for (int i = 0;
-                          i < unreadNotificationIds.length - 1;
-                          i++) {
-                        futures.add(ref.read(notificationsProvider).markAsRead(
-                            unreadNotificationIds.elementAt(i), false));
-                      }
-
-                      // wait for multiple to update if any
-                      Future.wait(futures).then((_) {
-                        // only notify listeners once
-                        ref
-                            .read(notificationsProvider)
-                            .markAsRead(unreadNotificationIds.last, true);
-                      });
-                    });
-                  },
                 ),
-              ),
+                const SizedBox(
+                  width: 16,
+                ),
+                Text(
+                  "My Stack",
+                  style: STextStyles.navBarTitle(context),
+                )
+              ],
             ),
-            Padding(
-              padding: const EdgeInsets.only(
-                top: 10,
-                bottom: 10,
-                right: 10,
-              ),
-              child: AspectRatio(
-                aspectRatio: 1,
-                child: AppBarIconButton(
-                  key: const Key("walletsViewSettingsButton"),
-                  size: 36,
-                  shadows: const [],
-                  color: Theme.of(context).extension<StackColors>()!.background,
-                  icon: SvgPicture.asset(
-                    Assets.svg.gear,
+            actions: [
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
+                ),
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("walletsViewAlertsButton"),
+                    size: 36,
+                    shadows: const [],
                     color: Theme.of(context)
                         .extension<StackColors>()!
-                        .topNavIconPrimary,
-                    width: 20,
-                    height: 20,
+                        .backgroundAppBar,
+                    icon: SvgPicture.asset(
+                      ref.watch(notificationsProvider
+                              .select((value) => value.hasUnreadNotifications))
+                          ? Assets.svg.bellNew(context)
+                          : Assets.svg.bell,
+                      width: 20,
+                      height: 20,
+                      color: ref.watch(notificationsProvider
+                              .select((value) => value.hasUnreadNotifications))
+                          ? null
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .topNavIconPrimary,
+                    ),
+                    onPressed: () {
+                      // reset unread state
+                      ref.refresh(unreadNotificationsStateProvider);
+
+                      Navigator.of(context)
+                          .pushNamed(NotificationsView.routeName)
+                          .then((_) {
+                        final Set<int> unreadNotificationIds = ref
+                            .read(unreadNotificationsStateProvider.state)
+                            .state;
+                        if (unreadNotificationIds.isEmpty) return;
+
+                        List<Future<void>> futures = [];
+                        for (int i = 0;
+                            i < unreadNotificationIds.length - 1;
+                            i++) {
+                          futures.add(ref
+                              .read(notificationsProvider)
+                              .markAsRead(
+                                  unreadNotificationIds.elementAt(i), false));
+                        }
+
+                        // wait for multiple to update if any
+                        Future.wait(futures).then((_) {
+                          // only notify listeners once
+                          ref
+                              .read(notificationsProvider)
+                              .markAsRead(unreadNotificationIds.last, true);
+                        });
+                      });
+                    },
                   ),
-                  onPressed: () {
-                    debugPrint("main view settings tapped");
-                    Navigator.of(context)
-                        .pushNamed(GlobalSettingsView.routeName);
-                  },
                 ),
               ),
-            ),
-          ],
-        ),
-        body: Container(
-          color: Theme.of(context).extension<StackColors>()!.background,
-          child: Column(
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
+                ),
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("walletsViewSettingsButton"),
+                    size: 36,
+                    shadows: const [],
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .backgroundAppBar,
+                    icon: SvgPicture.asset(
+                      Assets.svg.gear,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .topNavIconPrimary,
+                      width: 20,
+                      height: 20,
+                    ),
+                    onPressed: () {
+                      debugPrint("main view settings tapped");
+                      Navigator.of(context)
+                          .pushNamed(GlobalSettingsView.routeName);
+                    },
+                  ),
+                ),
+              ),
+            ],
+          ),
+          body: Column(
             children: [
               if (Constants.enableExchange)
                 Container(
                   decoration: BoxDecoration(
-                    color:
-                        Theme.of(context).extension<StackColors>()!.background,
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .backgroundAppBar,
                     boxShadow: [
                       Theme.of(context)
                           .extension<StackColors>()!
diff --git a/lib/pages/intro_view.dart b/lib/pages/intro_view.dart
index 494f23973..be0a9b82a 100644
--- a/lib/pages/intro_view.dart
+++ b/lib/pages/intro_view.dart
@@ -3,14 +3,13 @@ import 'package:flutter/material.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/stack_privacy_calls.dart';
 import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/utilities/util.dart';
-import 'package:tuple/tuple.dart';
+import 'package:stackwallet/widgets/background.dart';
 import 'package:url_launcher/url_launcher.dart';
 
-import 'package:stackwallet/utilities/prefs.dart';
-
 class IntroView extends StatefulWidget {
   const IntroView({Key? key}) : super(key: key);
 
@@ -32,118 +31,120 @@ class _IntroViewState extends State<IntroView> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType ");
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      body: Center(
-        child: !isDesktop
-            ? Column(
-                crossAxisAlignment: CrossAxisAlignment.center,
-                children: [
-                  const Spacer(
-                    flex: 2,
-                  ),
-                  Padding(
-                    padding: const EdgeInsets.symmetric(
-                      horizontal: 16,
-                    ),
-                    child: ConstrainedBox(
-                      constraints: const BoxConstraints(
-                        maxWidth: 300,
-                      ),
-                      child: Image(
-                        image: AssetImage(
-                          Assets.png.stack,
-                        ),
-                      ),
-                    ),
-                  ),
-                  const Spacer(
-                    flex: 1,
-                  ),
-                  AppNameText(
-                    isDesktop: isDesktop,
-                  ),
-                  const SizedBox(
-                    height: 8,
-                  ),
-                  Padding(
-                    padding: const EdgeInsets.symmetric(
-                      horizontal: 48,
-                    ),
-                    child: IntroAboutText(
-                      isDesktop: isDesktop,
-                    ),
-                  ),
-                  const Spacer(
-                    flex: 4,
-                  ),
-                  Padding(
-                    padding: const EdgeInsets.symmetric(
-                      horizontal: 32,
-                    ),
-                    child: PrivacyAndTOSText(
-                      isDesktop: isDesktop,
-                    ),
-                  ),
-                  Padding(
-                    padding: const EdgeInsets.symmetric(
-                      horizontal: 16,
-                      vertical: 16,
-                    ),
-                    child: Row(
-                      children: [
-                        Expanded(
-                          child: GetStartedButton(
-                            isDesktop: isDesktop,
-                          ),
-                        ),
-                      ],
-                    ),
-                  ),
-                ],
-              )
-            : SizedBox(
-                width: 350,
-                height: 540,
-                child: Column(
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        body: Center(
+          child: !isDesktop
+              ? Column(
+                  crossAxisAlignment: CrossAxisAlignment.center,
                   children: [
                     const Spacer(
                       flex: 2,
                     ),
-                    SizedBox(
-                      width: 130,
-                      height: 130,
-                      child: SvgPicture.asset(
-                        Assets.svg.stackIcon(context),
+                    Padding(
+                      padding: const EdgeInsets.symmetric(
+                        horizontal: 16,
+                      ),
+                      child: ConstrainedBox(
+                        constraints: const BoxConstraints(
+                          maxWidth: 300,
+                        ),
+                        child: Image(
+                          image: AssetImage(
+                            Assets.png.stack,
+                          ),
+                        ),
                       ),
                     ),
                     const Spacer(
-                      flex: 42,
+                      flex: 1,
                     ),
                     AppNameText(
                       isDesktop: isDesktop,
                     ),
-                    const Spacer(
-                      flex: 24,
+                    const SizedBox(
+                      height: 8,
                     ),
-                    IntroAboutText(
-                      isDesktop: isDesktop,
+                    Padding(
+                      padding: const EdgeInsets.symmetric(
+                        horizontal: 48,
+                      ),
+                      child: IntroAboutText(
+                        isDesktop: isDesktop,
+                      ),
                     ),
                     const Spacer(
-                      flex: 42,
+                      flex: 4,
                     ),
-                    GetStartedButton(
-                      isDesktop: isDesktop,
+                    Padding(
+                      padding: const EdgeInsets.symmetric(
+                        horizontal: 32,
+                      ),
+                      child: PrivacyAndTOSText(
+                        isDesktop: isDesktop,
+                      ),
                     ),
-                    const Spacer(
-                      flex: 65,
-                    ),
-                    PrivacyAndTOSText(
-                      isDesktop: isDesktop,
+                    Padding(
+                      padding: const EdgeInsets.symmetric(
+                        horizontal: 16,
+                        vertical: 16,
+                      ),
+                      child: Row(
+                        children: [
+                          Expanded(
+                            child: GetStartedButton(
+                              isDesktop: isDesktop,
+                            ),
+                          ),
+                        ],
+                      ),
                     ),
                   ],
+                )
+              : SizedBox(
+                  width: 350,
+                  height: 540,
+                  child: Column(
+                    children: [
+                      const Spacer(
+                        flex: 2,
+                      ),
+                      SizedBox(
+                        width: 130,
+                        height: 130,
+                        child: SvgPicture.asset(
+                          Assets.svg.stackIcon(context),
+                        ),
+                      ),
+                      const Spacer(
+                        flex: 42,
+                      ),
+                      AppNameText(
+                        isDesktop: isDesktop,
+                      ),
+                      const Spacer(
+                        flex: 24,
+                      ),
+                      IntroAboutText(
+                        isDesktop: isDesktop,
+                      ),
+                      const Spacer(
+                        flex: 42,
+                      ),
+                      GetStartedButton(
+                        isDesktop: isDesktop,
+                      ),
+                      const Spacer(
+                        flex: 65,
+                      ),
+                      PrivacyAndTOSText(
+                        isDesktop: isDesktop,
+                      ),
+                    ],
+                  ),
                 ),
-              ),
+        ),
       ),
     );
   }
diff --git a/lib/pages/loading_view.dart b/lib/pages/loading_view.dart
index c252913df..b7db1aa58 100644
--- a/lib/pages/loading_view.dart
+++ b/lib/pages/loading_view.dart
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
 import 'package:lottie/lottie.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/background.dart';
 
 class LoadingView extends StatelessWidget {
   const LoadingView({Key? key}) : super(key: key);
@@ -11,25 +12,27 @@ class LoadingView extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     final size = MediaQuery.of(context).size;
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      body: Container(
-        color: Theme.of(context).extension<StackColors>()!.background,
-        child: Center(
-          child: SizedBox(
-            width: min(size.width, size.height) * 0.5,
-            child: Lottie.asset(
-              Assets.lottie.test2,
-              animate: true,
-              repeat: true,
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        body: Container(
+          color: Theme.of(context).extension<StackColors>()!.background,
+          child: Center(
+            child: SizedBox(
+              width: min(size.width, size.height) * 0.5,
+              child: Lottie.asset(
+                Assets.lottie.test2,
+                animate: true,
+                repeat: true,
+              ),
             ),
+            // child: Image(
+            //   image: AssetImage(
+            //     Assets.png.splash,
+            //   ),
+            //   width: MediaQuery.of(context).size.width * 0.5,
+            // ),
           ),
-          // child: Image(
-          //   image: AssetImage(
-          //     Assets.png.splash,
-          //   ),
-          //   width: MediaQuery.of(context).size.width * 0.5,
-          // ),
         ),
       ),
     );
diff --git a/lib/pages/notification_views/notifications_view.dart b/lib/pages/notification_views/notifications_view.dart
index a034a34e4..a574e083d 100644
--- a/lib/pages/notification_views/notifications_view.dart
+++ b/lib/pages/notification_views/notifications_view.dart
@@ -5,6 +5,7 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/ui/unread_notifications_provider.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
@@ -43,66 +44,68 @@ class _NotificationsViewState extends ConsumerState<NotificationsView> {
             .where((element) => element.walletId == widget.walletId)
             .toList(growable: false);
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        title: Text(
-          "Notifications",
-          style: STextStyles.navBarTitle(context),
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          title: Text(
+            "Notifications",
+            style: STextStyles.navBarTitle(context),
+          ),
+          leading: AppBarBackButton(
+            onPressed: () async {
+              Navigator.of(context).pop();
+            },
+          ),
         ),
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(12),
-        child: notifications.isNotEmpty
-            ? Column(
-                children: [
-                  Expanded(
-                    child: ListView.builder(
-                      shrinkWrap: true,
-                      itemCount: notifications.length,
-                      itemBuilder: (builderContext, index) {
-                        final notification = notifications[index];
-                        if (notification.read == false) {
-                          ref
-                              .read(unreadNotificationsStateProvider.state)
-                              .state
-                              .add(notification.id);
-                        }
-                        return Padding(
-                          padding: const EdgeInsets.all(4),
-                          child: NotificationCard(
-                            notification: notifications[index],
-                          ),
-                        );
-                      },
+        body: Padding(
+          padding: const EdgeInsets.all(12),
+          child: notifications.isNotEmpty
+              ? Column(
+                  children: [
+                    Expanded(
+                      child: ListView.builder(
+                        shrinkWrap: true,
+                        itemCount: notifications.length,
+                        itemBuilder: (builderContext, index) {
+                          final notification = notifications[index];
+                          if (notification.read == false) {
+                            ref
+                                .read(unreadNotificationsStateProvider.state)
+                                .state
+                                .add(notification.id);
+                          }
+                          return Padding(
+                            padding: const EdgeInsets.all(4),
+                            child: NotificationCard(
+                              notification: notifications[index],
+                            ),
+                          );
+                        },
+                      ),
                     ),
-                  ),
-                ],
-              )
-            : Column(
-                crossAxisAlignment: CrossAxisAlignment.center,
-                children: [
-                  Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: RoundedWhiteContainer(
-                      child: Center(
-                        child: FittedBox(
-                          fit: BoxFit.scaleDown,
-                          child: Text(
-                            "Notifications will appear here",
-                            style: STextStyles.itemSubtitle(context),
+                  ],
+                )
+              : Column(
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  children: [
+                    Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: RoundedWhiteContainer(
+                        child: Center(
+                          child: FittedBox(
+                            fit: BoxFit.scaleDown,
+                            child: Text(
+                              "Notifications will appear here",
+                              style: STextStyles.itemSubtitle(context),
+                            ),
                           ),
                         ),
                       ),
-                    ),
-                  )
-                ],
-              ),
+                    )
+                  ],
+                ),
+        ),
       ),
     );
   }
diff --git a/lib/pages/pinpad_views/create_pin_view.dart b/lib/pages/pinpad_views/create_pin_view.dart
index 766f10fa5..3180689c2 100644
--- a/lib/pages/pinpad_views/create_pin_view.dart
+++ b/lib/pages/pinpad_views/create_pin_view.dart
@@ -13,6 +13,7 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_pin_put/custom_pin_put.dart';
 
@@ -76,215 +77,219 @@ class _CreatePinViewState extends ConsumerState<CreatePinView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            if (FocusScope.of(context).hasFocus) {
-              FocusScope.of(context).unfocus();
-              await Future<void>.delayed(const Duration(milliseconds: 70));
-            }
-            if (mounted) {
-              Navigator.of(context).pop(widget.popOnSuccess);
-            }
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              if (FocusScope.of(context).hasFocus) {
+                FocusScope.of(context).unfocus();
+                await Future<void>.delayed(const Duration(milliseconds: 70));
+              }
+              if (mounted) {
+                Navigator.of(context).pop(widget.popOnSuccess);
+              }
+            },
+          ),
         ),
-      ),
-      body: SafeArea(
-        child: PageView(
-          controller: _pageController,
-          physics: const NeverScrollableScrollPhysics(),
-          children: [
-            // page 1
-            Column(
-              mainAxisAlignment: MainAxisAlignment.center,
-              children: [
-                Text(
-                  "Create a PIN",
-                  style: STextStyles.pageTitleH1(context),
-                ),
-                const SizedBox(
-                  height: 8,
-                ),
-                Text(
-                  "This PIN protects access to your wallet.",
-                  style: STextStyles.subtitle(context),
-                ),
-                const SizedBox(
-                  height: 36,
-                ),
-                CustomPinPut(
-                  fieldsCount: Constants.pinLength,
-                  eachFieldHeight: 12,
-                  eachFieldWidth: 12,
-                  textStyle: STextStyles.label(context).copyWith(
-                    fontSize: 1,
+        body: SafeArea(
+          child: PageView(
+            controller: _pageController,
+            physics: const NeverScrollableScrollPhysics(),
+            children: [
+              // page 1
+              Column(
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: [
+                  Text(
+                    "Create a PIN",
+                    style: STextStyles.pageTitleH1(context),
                   ),
-                  focusNode: _pinPutFocusNode1,
-                  controller: _pinPutController1,
-                  useNativeKeyboard: false,
-                  obscureText: "",
-                  inputDecoration: InputDecoration(
-                    border: InputBorder.none,
-                    enabledBorder: InputBorder.none,
-                    focusedBorder: InputBorder.none,
-                    disabledBorder: InputBorder.none,
-                    errorBorder: InputBorder.none,
-                    focusedErrorBorder: InputBorder.none,
-                    fillColor:
-                        Theme.of(context).extension<StackColors>()!.background,
-                    counterText: "",
+                  const SizedBox(
+                    height: 8,
                   ),
-                  submittedFieldDecoration: _pinPutDecoration.copyWith(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .infoItemIcons,
-                    border: Border.all(
-                      width: 1,
+                  Text(
+                    "This PIN protects access to your wallet.",
+                    style: STextStyles.subtitle(context),
+                  ),
+                  const SizedBox(
+                    height: 36,
+                  ),
+                  CustomPinPut(
+                    fieldsCount: Constants.pinLength,
+                    eachFieldHeight: 12,
+                    eachFieldWidth: 12,
+                    textStyle: STextStyles.label(context).copyWith(
+                      fontSize: 1,
+                    ),
+                    focusNode: _pinPutFocusNode1,
+                    controller: _pinPutController1,
+                    useNativeKeyboard: false,
+                    obscureText: "",
+                    inputDecoration: InputDecoration(
+                      border: InputBorder.none,
+                      enabledBorder: InputBorder.none,
+                      focusedBorder: InputBorder.none,
+                      disabledBorder: InputBorder.none,
+                      errorBorder: InputBorder.none,
+                      focusedErrorBorder: InputBorder.none,
+                      fillColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .background,
+                      counterText: "",
+                    ),
+                    submittedFieldDecoration: _pinPutDecoration.copyWith(
                       color: Theme.of(context)
                           .extension<StackColors>()!
                           .infoItemIcons,
+                      border: Border.all(
+                        width: 1,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .infoItemIcons,
+                      ),
                     ),
-                  ),
-                  selectedFieldDecoration: _pinPutDecoration,
-                  followingFieldDecoration: _pinPutDecoration,
-                  onSubmit: (String pin) {
-                    if (pin.length == Constants.pinLength) {
-                      _pageController.nextPage(
-                        duration: const Duration(milliseconds: 300),
-                        curve: Curves.linear,
-                      );
-                    }
-                  },
-                ),
-              ],
-            ),
-
-            // page 2
-            Column(
-              mainAxisAlignment: MainAxisAlignment.center,
-              children: [
-                Text(
-                  "Confirm PIN",
-                  style: STextStyles.pageTitleH1(context),
-                ),
-                const SizedBox(
-                  height: 8,
-                ),
-                Text(
-                  "This PIN protects access to your wallet.",
-                  style: STextStyles.subtitle(context),
-                ),
-                const SizedBox(
-                  height: 36,
-                ),
-                CustomPinPut(
-                  fieldsCount: Constants.pinLength,
-                  eachFieldHeight: 12,
-                  eachFieldWidth: 12,
-                  textStyle: STextStyles.infoSmall(context).copyWith(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .textSubtitle3,
-                    fontSize: 1,
-                  ),
-                  focusNode: _pinPutFocusNode2,
-                  controller: _pinPutController2,
-                  useNativeKeyboard: false,
-                  obscureText: "",
-                  inputDecoration: InputDecoration(
-                    border: InputBorder.none,
-                    enabledBorder: InputBorder.none,
-                    focusedBorder: InputBorder.none,
-                    disabledBorder: InputBorder.none,
-                    errorBorder: InputBorder.none,
-                    focusedErrorBorder: InputBorder.none,
-                    fillColor:
-                        Theme.of(context).extension<StackColors>()!.background,
-                    counterText: "",
-                  ),
-                  submittedFieldDecoration: _pinPutDecoration.copyWith(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .infoItemIcons,
-                    border: Border.all(
-                      width: 1,
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .infoItemIcons,
-                    ),
-                  ),
-                  selectedFieldDecoration: _pinPutDecoration,
-                  followingFieldDecoration: _pinPutDecoration,
-                  onSubmit: (String pin) async {
-                    // _onSubmitCount++;
-                    // if (_onSubmitCount - _onSubmitFailCount > 1) return;
-
-                    if (_pinPutController1.text == _pinPutController2.text) {
-                      // ask if want to use biometrics
-                      final bool useBiometrics = (Platform.isLinux)
-                          ? false
-                          : await biometrics.authenticate(
-                              cancelButtonText: "SKIP",
-                              localizedReason:
-                                  "You can use your fingerprint to unlock the wallet and confirm transactions.",
-                              title: "Enable fingerprint authentication",
-                            );
-
-                      //TODO investigate why this crashes IOS, maybe ios persists securestorage even after an uninstall?
-                      // This should never fail as we are writing a new pin
-                      // assert(
-                      //     (await _secureStore.read(key: "stack_pin")) == null);
-                      // possible alternative to the above but it does not guarantee we aren't overwriting a pin
-                      // if (!Platform.isLinux)
-                      //   assert((await _secureStore.read(key: "stack_pin")) ==
-                      //       null);
-                      assert(ref.read(prefsChangeNotifierProvider).hasPin ==
-                          false);
-
-                      await _secureStore.write(key: "stack_pin", value: pin);
-
-                      ref.read(prefsChangeNotifierProvider).useBiometrics =
-                          useBiometrics;
-                      ref.read(prefsChangeNotifierProvider).hasPin = true;
-
-                      await Future<void>.delayed(
-                          const Duration(milliseconds: 200));
-
-                      if (mounted) {
-                        if (!widget.popOnSuccess) {
-                          Navigator.of(context).pushNamedAndRemoveUntil(
-                            HomeView.routeName,
-                            (route) => false,
-                          );
-                        } else {
-                          Navigator.of(context).pop();
-                        }
+                    selectedFieldDecoration: _pinPutDecoration,
+                    followingFieldDecoration: _pinPutDecoration,
+                    onSubmit: (String pin) {
+                      if (pin.length == Constants.pinLength) {
+                        _pageController.nextPage(
+                          duration: const Duration(milliseconds: 300),
+                          curve: Curves.linear,
+                        );
                       }
-                    } else {
-                      // _onSubmitFailCount++;
-                      _pageController.animateTo(
-                        0,
-                        duration: const Duration(milliseconds: 300),
-                        curve: Curves.linear,
-                      );
+                    },
+                  ),
+                ],
+              ),
 
-                      showFloatingFlushBar(
-                        type: FlushBarType.warning,
-                        message: "PIN codes do not match. Try again.",
-                        context: context,
-                        iconAsset: Assets.svg.alertCircle,
-                      );
+              // page 2
+              Column(
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: [
+                  Text(
+                    "Confirm PIN",
+                    style: STextStyles.pageTitleH1(context),
+                  ),
+                  const SizedBox(
+                    height: 8,
+                  ),
+                  Text(
+                    "This PIN protects access to your wallet.",
+                    style: STextStyles.subtitle(context),
+                  ),
+                  const SizedBox(
+                    height: 36,
+                  ),
+                  CustomPinPut(
+                    fieldsCount: Constants.pinLength,
+                    eachFieldHeight: 12,
+                    eachFieldWidth: 12,
+                    textStyle: STextStyles.infoSmall(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textSubtitle3,
+                      fontSize: 1,
+                    ),
+                    focusNode: _pinPutFocusNode2,
+                    controller: _pinPutController2,
+                    useNativeKeyboard: false,
+                    obscureText: "",
+                    inputDecoration: InputDecoration(
+                      border: InputBorder.none,
+                      enabledBorder: InputBorder.none,
+                      focusedBorder: InputBorder.none,
+                      disabledBorder: InputBorder.none,
+                      errorBorder: InputBorder.none,
+                      focusedErrorBorder: InputBorder.none,
+                      fillColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .background,
+                      counterText: "",
+                    ),
+                    submittedFieldDecoration: _pinPutDecoration.copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .infoItemIcons,
+                      border: Border.all(
+                        width: 1,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .infoItemIcons,
+                      ),
+                    ),
+                    selectedFieldDecoration: _pinPutDecoration,
+                    followingFieldDecoration: _pinPutDecoration,
+                    onSubmit: (String pin) async {
+                      // _onSubmitCount++;
+                      // if (_onSubmitCount - _onSubmitFailCount > 1) return;
 
-                      _pinPutController1.text = '';
-                      _pinPutController2.text = '';
-                    }
-                  },
-                ),
-              ],
-            ),
-          ],
+                      if (_pinPutController1.text == _pinPutController2.text) {
+                        // ask if want to use biometrics
+                        final bool useBiometrics = (Platform.isLinux)
+                            ? false
+                            : await biometrics.authenticate(
+                                cancelButtonText: "SKIP",
+                                localizedReason:
+                                    "You can use your fingerprint to unlock the wallet and confirm transactions.",
+                                title: "Enable fingerprint authentication",
+                              );
+
+                        //TODO investigate why this crashes IOS, maybe ios persists securestorage even after an uninstall?
+                        // This should never fail as we are writing a new pin
+                        // assert(
+                        //     (await _secureStore.read(key: "stack_pin")) == null);
+                        // possible alternative to the above but it does not guarantee we aren't overwriting a pin
+                        // if (!Platform.isLinux)
+                        //   assert((await _secureStore.read(key: "stack_pin")) ==
+                        //       null);
+                        assert(ref.read(prefsChangeNotifierProvider).hasPin ==
+                            false);
+
+                        await _secureStore.write(key: "stack_pin", value: pin);
+
+                        ref.read(prefsChangeNotifierProvider).useBiometrics =
+                            useBiometrics;
+                        ref.read(prefsChangeNotifierProvider).hasPin = true;
+
+                        await Future<void>.delayed(
+                            const Duration(milliseconds: 200));
+
+                        if (mounted) {
+                          if (!widget.popOnSuccess) {
+                            Navigator.of(context).pushNamedAndRemoveUntil(
+                              HomeView.routeName,
+                              (route) => false,
+                            );
+                          } else {
+                            Navigator.of(context).pop();
+                          }
+                        }
+                      } else {
+                        // _onSubmitFailCount++;
+                        _pageController.animateTo(
+                          0,
+                          duration: const Duration(milliseconds: 300),
+                          curve: Curves.linear,
+                        );
+
+                        showFloatingFlushBar(
+                          type: FlushBarType.warning,
+                          message: "PIN codes do not match. Try again.",
+                          context: context,
+                          iconAsset: Assets.svg.alertCircle,
+                        );
+
+                        _pinPutController1.text = '';
+                        _pinPutController2.text = '';
+                      }
+                    },
+                  ),
+                ],
+              ),
+            ],
+          ),
         ),
       ),
     );
diff --git a/lib/pages/pinpad_views/lock_screen_view.dart b/lib/pages/pinpad_views/lock_screen_view.dart
index 60d317e21..455d5ee3b 100644
--- a/lib/pages/pinpad_views/lock_screen_view.dart
+++ b/lib/pages/pinpad_views/lock_screen_view.dart
@@ -17,6 +17,7 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_pin_put/custom_pin_put.dart';
 import 'package:stackwallet/widgets/shake/shake.dart';
@@ -161,173 +162,177 @@ class _LockscreenViewState extends ConsumerState<LockscreenView> {
   late SecureStorageInterface _secureStore;
   late Biometrics biometrics;
 
-  Scaffold get _body => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          leading: widget.showBackButton
-              ? AppBarBackButton(
-                  onPressed: () async {
-                    if (FocusScope.of(context).hasFocus) {
-                      FocusScope.of(context).unfocus();
-                      await Future<void>.delayed(
-                          const Duration(milliseconds: 70));
-                    }
-                    if (mounted) {
-                      Navigator.of(context).pop();
-                    }
-                  },
-                )
-              : Container(),
-        ),
-        body: SafeArea(
-          child: Column(
-            mainAxisAlignment: MainAxisAlignment.center,
-            children: [
-              Shake(
-                animationDuration: const Duration(milliseconds: 700),
-                animationRange: 12,
-                controller: _shakeController,
-                child: Center(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      Center(
-                        child: Text(
-                          "Enter PIN",
-                          style: STextStyles.pageTitleH1(context),
+  Widget get _body => Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: widget.showBackButton
+                ? AppBarBackButton(
+                    onPressed: () async {
+                      if (FocusScope.of(context).hasFocus) {
+                        FocusScope.of(context).unfocus();
+                        await Future<void>.delayed(
+                            const Duration(milliseconds: 70));
+                      }
+                      if (mounted) {
+                        Navigator.of(context).pop();
+                      }
+                    },
+                  )
+                : Container(),
+          ),
+          body: SafeArea(
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                Shake(
+                  animationDuration: const Duration(milliseconds: 700),
+                  animationRange: 12,
+                  controller: _shakeController,
+                  child: Center(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        Center(
+                          child: Text(
+                            "Enter PIN",
+                            style: STextStyles.pageTitleH1(context),
+                          ),
                         ),
-                      ),
-                      const SizedBox(
-                        height: 52,
-                      ),
-                      CustomPinPut(
-                        fieldsCount: Constants.pinLength,
-                        eachFieldHeight: 12,
-                        eachFieldWidth: 12,
-                        textStyle: STextStyles.label(context).copyWith(
-                          fontSize: 1,
+                        const SizedBox(
+                          height: 52,
                         ),
-                        focusNode: _pinFocusNode,
-                        controller: _pinTextController,
-                        useNativeKeyboard: false,
-                        obscureText: "",
-                        inputDecoration: InputDecoration(
-                          border: InputBorder.none,
-                          enabledBorder: InputBorder.none,
-                          focusedBorder: InputBorder.none,
-                          disabledBorder: InputBorder.none,
-                          errorBorder: InputBorder.none,
-                          focusedErrorBorder: InputBorder.none,
-                          fillColor: Theme.of(context)
-                              .extension<StackColors>()!
-                              .background,
-                          counterText: "",
-                        ),
-                        submittedFieldDecoration: _pinPutDecoration.copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .infoItemIcons,
-                          border: Border.all(
-                            width: 1,
+                        CustomPinPut(
+                          fieldsCount: Constants.pinLength,
+                          eachFieldHeight: 12,
+                          eachFieldWidth: 12,
+                          textStyle: STextStyles.label(context).copyWith(
+                            fontSize: 1,
+                          ),
+                          focusNode: _pinFocusNode,
+                          controller: _pinTextController,
+                          useNativeKeyboard: false,
+                          obscureText: "",
+                          inputDecoration: InputDecoration(
+                            border: InputBorder.none,
+                            enabledBorder: InputBorder.none,
+                            focusedBorder: InputBorder.none,
+                            disabledBorder: InputBorder.none,
+                            errorBorder: InputBorder.none,
+                            focusedErrorBorder: InputBorder.none,
+                            fillColor: Theme.of(context)
+                                .extension<StackColors>()!
+                                .background,
+                            counterText: "",
+                          ),
+                          submittedFieldDecoration: _pinPutDecoration.copyWith(
                             color: Theme.of(context)
                                 .extension<StackColors>()!
                                 .infoItemIcons,
+                            border: Border.all(
+                              width: 1,
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .infoItemIcons,
+                            ),
                           ),
-                        ),
-                        selectedFieldDecoration: _pinPutDecoration,
-                        followingFieldDecoration: _pinPutDecoration,
-                        onSubmit: (String pin) async {
-                          _attempts++;
+                          selectedFieldDecoration: _pinPutDecoration,
+                          followingFieldDecoration: _pinPutDecoration,
+                          onSubmit: (String pin) async {
+                            _attempts++;
 
-                          if (_attempts > maxAttemptsBeforeThrottling) {
-                            _attemptLock = true;
-                            switch (_attempts) {
-                              case 4:
-                                _timeout = const Duration(seconds: 30);
-                                break;
+                            if (_attempts > maxAttemptsBeforeThrottling) {
+                              _attemptLock = true;
+                              switch (_attempts) {
+                                case 4:
+                                  _timeout = const Duration(seconds: 30);
+                                  break;
 
-                              case 5:
-                                _timeout = const Duration(seconds: 60);
-                                break;
+                                case 5:
+                                  _timeout = const Duration(seconds: 60);
+                                  break;
 
-                              case 6:
-                                _timeout = const Duration(minutes: 5);
-                                break;
+                                case 6:
+                                  _timeout = const Duration(minutes: 5);
+                                  break;
 
-                              case 7:
-                                _timeout = const Duration(minutes: 10);
-                                break;
+                                case 7:
+                                  _timeout = const Duration(minutes: 10);
+                                  break;
 
-                              case 8:
-                                _timeout = const Duration(minutes: 20);
-                                break;
+                                case 8:
+                                  _timeout = const Duration(minutes: 20);
+                                  break;
 
-                              case 9:
-                                _timeout = const Duration(minutes: 30);
-                                break;
+                                case 9:
+                                  _timeout = const Duration(minutes: 30);
+                                  break;
 
-                              default:
-                                _timeout = const Duration(minutes: 60);
+                                default:
+                                  _timeout = const Duration(minutes: 60);
+                              }
+
+                              unawaited(
+                                  Future<void>.delayed(_timeout).then((_) {
+                                _attemptLock = false;
+                                _attempts = 0;
+                              }));
                             }
 
-                            unawaited(Future<void>.delayed(_timeout).then((_) {
-                              _attemptLock = false;
-                              _attempts = 0;
-                            }));
-                          }
+                            if (_attemptLock) {
+                              String prettyTime = "";
+                              if (_timeout.inSeconds >= 60) {
+                                prettyTime += "${_timeout.inMinutes} minutes";
+                              } else {
+                                prettyTime += "${_timeout.inSeconds} seconds";
+                              }
 
-                          if (_attemptLock) {
-                            String prettyTime = "";
-                            if (_timeout.inSeconds >= 60) {
-                              prettyTime += "${_timeout.inMinutes} minutes";
+                              unawaited(showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message:
+                                    "Incorrect PIN entered too many times. Please wait $prettyTime",
+                                context: context,
+                                iconAsset: Assets.svg.alertCircle,
+                              ));
+
+                              await Future<void>.delayed(
+                                  const Duration(milliseconds: 100));
+
+                              _pinTextController.text = '';
+
+                              return;
+                            }
+
+                            final storedPin =
+                                await _secureStore.read(key: 'stack_pin');
+
+                            if (storedPin == pin) {
+                              await Future<void>.delayed(
+                                  const Duration(milliseconds: 200));
+                              unawaited(_onUnlock());
                             } else {
-                              prettyTime += "${_timeout.inSeconds} seconds";
+                              unawaited(_shakeController.shake());
+                              unawaited(showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "Incorrect PIN. Please try again",
+                                context: context,
+                                iconAsset: Assets.svg.alertCircle,
+                              ));
+
+                              await Future<void>.delayed(
+                                  const Duration(milliseconds: 100));
+
+                              _pinTextController.text = '';
                             }
-
-                            unawaited(showFloatingFlushBar(
-                              type: FlushBarType.warning,
-                              message:
-                                  "Incorrect PIN entered too many times. Please wait $prettyTime",
-                              context: context,
-                              iconAsset: Assets.svg.alertCircle,
-                            ));
-
-                            await Future<void>.delayed(
-                                const Duration(milliseconds: 100));
-
-                            _pinTextController.text = '';
-
-                            return;
-                          }
-
-                          final storedPin =
-                              await _secureStore.read(key: 'stack_pin');
-
-                          if (storedPin == pin) {
-                            await Future<void>.delayed(
-                                const Duration(milliseconds: 200));
-                            unawaited(_onUnlock());
-                          } else {
-                            unawaited(_shakeController.shake());
-                            unawaited(showFloatingFlushBar(
-                              type: FlushBarType.warning,
-                              message: "Incorrect PIN. Please try again",
-                              context: context,
-                              iconAsset: Assets.svg.alertCircle,
-                            ));
-
-                            await Future<void>.delayed(
-                                const Duration(milliseconds: 100));
-
-                            _pinTextController.text = '';
-                          }
-                        },
-                      ),
-                    ],
+                          },
+                        ),
+                      ],
+                    ),
                   ),
                 ),
-              ),
-            ],
+              ],
+            ),
           ),
         ),
       );
diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
index 05cedb148..46b48bb42 100644
--- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
+++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
@@ -23,6 +23,7 @@ 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/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/primary_button.dart';
@@ -305,48 +306,51 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
 
     return ConditionalParent(
       condition: !isDesktop,
-      builder: (child) => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          leading: AppBarBackButton(
-            onPressed: () async {
-              if (FocusScope.of(context).hasFocus) {
-                FocusScope.of(context).unfocus();
-                await Future<void>.delayed(const Duration(milliseconds: 70));
-              }
-              if (mounted) {
-                Navigator.of(context).pop();
-              }
-            },
+      builder: (child) => Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () async {
+                if (FocusScope.of(context).hasFocus) {
+                  FocusScope.of(context).unfocus();
+                  await Future<void>.delayed(const Duration(milliseconds: 70));
+                }
+                if (mounted) {
+                  Navigator.of(context).pop();
+                }
+              },
+            ),
+            title: Text(
+              "Generate QR code",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
-          title: Text(
-            "Generate QR code",
-            style: STextStyles.navBarTitle(context),
-          ),
-        ),
-        body: LayoutBuilder(
-          builder: (buildContext, constraints) {
-            return Padding(
-              padding: const EdgeInsets.only(
-                left: 12,
-                top: 12,
-                right: 12,
-              ),
-              child: SingleChildScrollView(
-                child: ConstrainedBox(
-                  constraints: BoxConstraints(
-                    minHeight: constraints.maxHeight - 24,
-                  ),
-                  child: IntrinsicHeight(
-                    child: Padding(
-                      padding: const EdgeInsets.all(4),
-                      child: child,
+          body: LayoutBuilder(
+            builder: (buildContext, constraints) {
+              return Padding(
+                padding: const EdgeInsets.only(
+                  left: 12,
+                  top: 12,
+                  right: 12,
+                ),
+                child: SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight - 24,
+                    ),
+                    child: IntrinsicHeight(
+                      child: Padding(
+                        padding: const EdgeInsets.all(4),
+                        child: child,
+                      ),
                     ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
       child: Padding(
@@ -530,7 +534,7 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                       });
                     }
                   : onGeneratePressed,
-              buttonHeight: ButtonHeight.l,
+              buttonHeight: isDesktop ? ButtonHeight.l : null,
             ),
             if (isDesktop && didGenerate)
               Row(
@@ -586,6 +590,8 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                                 if (!isDesktop)
                                   SecondaryButton(
                                     width: 170,
+                                    buttonHeight:
+                                        isDesktop ? ButtonHeight.l : null,
                                     onPressed: () async {
                                       await _capturePng(false);
                                     },
@@ -605,7 +611,8 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
                                   ),
                                 PrimaryButton(
                                   width: 170,
-                                  buttonHeight: ButtonHeight.l,
+                                  buttonHeight:
+                                      isDesktop ? ButtonHeight.l : null,
                                   onPressed: () async {
                                     // TODO: add save functionality instead of share
                                     // save works on linux at the moment
diff --git a/lib/pages/receive_view/receive_view.dart b/lib/pages/receive_view/receive_view.dart
index 50e0ffd5e..1ba00f8ee 100644
--- a/lib/pages/receive_view/receive_view.dart
+++ b/lib/pages/receive_view/receive_view.dart
@@ -12,9 +12,9 @@ import 'package:stackwallet/route_generator.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/enums/flush_bar_type.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/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';
@@ -115,147 +115,149 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
       }
     });
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Receive ${coin.ticker}",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Receive ${coin.ticker}",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(12),
-        child: SingleChildScrollView(
-          child: Padding(
-            padding: const EdgeInsets.all(4),
-            child: Column(
-              crossAxisAlignment: CrossAxisAlignment.stretch,
-              children: [
-                GestureDetector(
-                  onTap: () {
-                    clipboard.setData(
-                      ClipboardData(text: receivingAddress),
-                    );
-                    showFloatingFlushBar(
-                      type: FlushBarType.info,
-                      message: "Copied to clipboard",
-                      iconAsset: Assets.svg.copy,
-                      context: context,
-                    );
-                  },
-                  child: RoundedWhiteContainer(
-                    child: Column(
-                      children: [
-                        Row(
-                          children: [
-                            Text(
-                              "Your ${coin.ticker} address",
-                              style: STextStyles.itemSubtitle(context),
-                            ),
-                            const Spacer(),
-                            Row(
-                              children: [
-                                SvgPicture.asset(
-                                  Assets.svg.copy,
-                                  width: 10,
-                                  height: 10,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .infoItemIcons,
-                                ),
-                                const SizedBox(
-                                  width: 4,
-                                ),
-                                Text(
-                                  "Copy",
-                                  style: STextStyles.link2(context),
-                                ),
-                              ],
-                            ),
-                          ],
-                        ),
-                        const SizedBox(
-                          height: 4,
-                        ),
-                        Row(
-                          children: [
-                            Expanded(
-                              child: Text(
-                                receivingAddress,
-                                style: STextStyles.itemSubtitle12(context),
-                              ),
-                            ),
-                          ],
-                        ),
-                      ],
-                    ),
-                  ),
-                ),
-                if (coin != Coin.epicCash)
-                  const SizedBox(
-                    height: 12,
-                  ),
-                if (coin != Coin.epicCash)
-                  TextButton(
-                    onPressed: generateNewAddress,
-                    style: Theme.of(context)
-                        .extension<StackColors>()!
-                        .getSecondaryEnabledButtonColor(context),
-                    child: Text(
-                      "Generate new address",
-                      style: STextStyles.button(context).copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorDark),
-                    ),
-                  ),
-                const SizedBox(
-                  height: 30,
-                ),
-                RoundedWhiteContainer(
-                  child: Padding(
-                    padding: const EdgeInsets.all(8.0),
-                    child: Center(
+        body: Padding(
+          padding: const EdgeInsets.all(12),
+          child: SingleChildScrollView(
+            child: Padding(
+              padding: const EdgeInsets.all(4),
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: [
+                  GestureDetector(
+                    onTap: () {
+                      clipboard.setData(
+                        ClipboardData(text: receivingAddress),
+                      );
+                      showFloatingFlushBar(
+                        type: FlushBarType.info,
+                        message: "Copied to clipboard",
+                        iconAsset: Assets.svg.copy,
+                        context: context,
+                      );
+                    },
+                    child: RoundedWhiteContainer(
                       child: Column(
                         children: [
-                          QrImage(
-                              data: "${coin.uriScheme}:$receivingAddress",
-                              size: MediaQuery.of(context).size.width / 2,
-                              foregroundColor: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .accentColorDark),
-                          const SizedBox(
-                            height: 20,
+                          Row(
+                            children: [
+                              Text(
+                                "Your ${coin.ticker} address",
+                                style: STextStyles.itemSubtitle(context),
+                              ),
+                              const Spacer(),
+                              Row(
+                                children: [
+                                  SvgPicture.asset(
+                                    Assets.svg.copy,
+                                    width: 10,
+                                    height: 10,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .infoItemIcons,
+                                  ),
+                                  const SizedBox(
+                                    width: 4,
+                                  ),
+                                  Text(
+                                    "Copy",
+                                    style: STextStyles.link2(context),
+                                  ),
+                                ],
+                              ),
+                            ],
                           ),
-                          BlueTextButton(
-                            text: "Create new QR code",
-                            onTap: () async {
-                              unawaited(Navigator.of(context).push(
-                                RouteGenerator.getRoute(
-                                  shouldUseMaterialRoute:
-                                      RouteGenerator.useMaterialPageRoute,
-                                  builder: (_) => GenerateUriQrCodeView(
-                                    coin: coin,
-                                    receivingAddress: receivingAddress,
-                                  ),
-                                  settings: const RouteSettings(
-                                    name: GenerateUriQrCodeView.routeName,
-                                  ),
+                          const SizedBox(
+                            height: 4,
+                          ),
+                          Row(
+                            children: [
+                              Expanded(
+                                child: Text(
+                                  receivingAddress,
+                                  style: STextStyles.itemSubtitle12(context),
                                 ),
-                              ));
-                            },
+                              ),
+                            ],
                           ),
                         ],
                       ),
                     ),
                   ),
-                ),
-              ],
+                  if (coin != Coin.epicCash)
+                    const SizedBox(
+                      height: 12,
+                    ),
+                  if (coin != Coin.epicCash)
+                    TextButton(
+                      onPressed: generateNewAddress,
+                      style: Theme.of(context)
+                          .extension<StackColors>()!
+                          .getSecondaryEnabledButtonColor(context),
+                      child: Text(
+                        "Generate new address",
+                        style: STextStyles.button(context).copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .accentColorDark),
+                      ),
+                    ),
+                  const SizedBox(
+                    height: 30,
+                  ),
+                  RoundedWhiteContainer(
+                    child: Padding(
+                      padding: const EdgeInsets.all(8.0),
+                      child: Center(
+                        child: Column(
+                          children: [
+                            QrImage(
+                                data: "${coin.uriScheme}:$receivingAddress",
+                                size: MediaQuery.of(context).size.width / 2,
+                                foregroundColor: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorDark),
+                            const SizedBox(
+                              height: 20,
+                            ),
+                            BlueTextButton(
+                              text: "Create new QR code",
+                              onTap: () async {
+                                unawaited(Navigator.of(context).push(
+                                  RouteGenerator.getRoute(
+                                    shouldUseMaterialRoute:
+                                        RouteGenerator.useMaterialPageRoute,
+                                    builder: (_) => GenerateUriQrCodeView(
+                                      coin: coin,
+                                      receivingAddress: receivingAddress,
+                                    ),
+                                    settings: const RouteSettings(
+                                      name: GenerateUriQrCodeView.routeName,
+                                    ),
+                                  ),
+                                ));
+                              },
+                            ),
+                          ],
+                        ),
+                      ),
+                    ),
+                  ),
+                ],
+              ),
             ),
           ),
         ),
diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index 16de6cf55..f1075b6e6 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -22,6 +22,7 @@ import 'package:stackwallet/utilities/format.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.dart';
@@ -203,48 +204,51 @@ class _ConfirmTransactionViewState
 
     return ConditionalParent(
       condition: !isDesktop,
-      builder: (child) => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
+      builder: (child) => Background(
+        child: Scaffold(
           backgroundColor:
               Theme.of(context).extension<StackColors>()!.background,
-          leading: AppBarBackButton(
-            onPressed: () async {
-              // if (FocusScope.of(context).hasFocus) {
-              //   FocusScope.of(context).unfocus();
-              //   await Future<void>.delayed(Duration(milliseconds: 50));
-              // }
-              Navigator.of(context).pop();
-            },
+          appBar: 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(Duration(milliseconds: 50));
+                // }
+                Navigator.of(context).pop();
+              },
+            ),
+            title: Text(
+              "Confirm transaction",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
-          title: Text(
-            "Confirm transaction",
-            style: STextStyles.navBarTitle(context),
-          ),
-        ),
-        body: LayoutBuilder(
-          builder: (builderContext, constraints) {
-            return Padding(
-              padding: const EdgeInsets.only(
-                left: 12,
-                top: 12,
-                right: 12,
-              ),
-              child: SingleChildScrollView(
-                child: ConstrainedBox(
-                  constraints: BoxConstraints(
-                    minHeight: constraints.maxHeight - 24,
-                  ),
-                  child: IntrinsicHeight(
-                    child: Padding(
-                      padding: const EdgeInsets.all(4),
-                      child: child,
+          body: LayoutBuilder(
+            builder: (builderContext, constraints) {
+              return Padding(
+                padding: const EdgeInsets.only(
+                  left: 12,
+                  top: 12,
+                  right: 12,
+                ),
+                child: SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight - 24,
+                    ),
+                    child: IntrinsicHeight(
+                      child: Padding(
+                        padding: const EdgeInsets.all(4),
+                        child: child,
+                      ),
                     ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
       child: ConditionalParent(
diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart
index 2539b89ab..a89a20d85 100644
--- a/lib/pages/send_view/send_view.dart
+++ b/lib/pages/send_view/send_view.dart
@@ -33,6 +33,7 @@ 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/animated_text.dart';
+import 'package:stackwallet/widgets/background.dart';
 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/icon_widgets/addressbook_icon.dart';
@@ -379,325 +380,464 @@ class _SendViewState extends ConsumerState<SendView> {
       });
     }
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            if (FocusScope.of(context).hasFocus) {
-              FocusScope.of(context).unfocus();
-              await Future<void>.delayed(const Duration(milliseconds: 50));
-            }
-            if (mounted) {
-              Navigator.of(context).pop();
-            }
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              if (FocusScope.of(context).hasFocus) {
+                FocusScope.of(context).unfocus();
+                await Future<void>.delayed(const Duration(milliseconds: 50));
+              }
+              if (mounted) {
+                Navigator.of(context).pop();
+              }
+            },
+          ),
+          title: Text(
+            "Send ${coin.ticker}",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Send ${coin.ticker}",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (builderContext, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  // subtract top and bottom padding set in parent
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.symmetric(horizontal: 4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        Container(
-                          decoration: BoxDecoration(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .popupBG,
+        body: LayoutBuilder(
+          builder: (builderContext, constraints) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    // subtract top and bottom padding set in parent
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.symmetric(horizontal: 4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          Container(
+                            decoration: BoxDecoration(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .popupBG,
+                              borderRadius: BorderRadius.circular(
+                                Constants.size.circularBorderRadius,
+                              ),
+                            ),
+                            child: Padding(
+                              padding: const EdgeInsets.all(12.0),
+                              child: Row(
+                                children: [
+                                  SvgPicture.asset(
+                                    Assets.svg.iconFor(coin: coin),
+                                    width: 22,
+                                    height: 22,
+                                  ),
+                                  const SizedBox(
+                                    width: 6,
+                                  ),
+                                  if (coin != Coin.firo &&
+                                      coin != Coin.firoTestNet)
+                                    Expanded(
+                                      child: Text(
+                                        ref.watch(provider.select(
+                                            (value) => value.walletName)),
+                                        style: STextStyles.titleBold12(context),
+                                        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,
+                                        // ),
+                                        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(),
+                                  FutureBuilder(
+                                    future: (coin != Coin.firo &&
+                                            coin != Coin.firoTestNet)
+                                        ? ref.watch(provider.select(
+                                            (value) => value.availableBalance))
+                                        : ref
+                                                    .watch(
+                                                        publicPrivateBalanceStateProvider
+                                                            .state)
+                                                    .state ==
+                                                "Private"
+                                            ? (ref.watch(provider).wallet
+                                                    as FiroWallet)
+                                                .availablePrivateBalance()
+                                            : (ref.watch(provider).wallet
+                                                    as FiroWallet)
+                                                .availablePublicBalance(),
+                                    builder:
+                                        (_, AsyncSnapshot<Decimal> snapshot) {
+                                      if (snapshot.connectionState ==
+                                              ConnectionState.done &&
+                                          snapshot.hasData) {
+                                        _cachedBalance = snapshot.data!;
+                                      }
+
+                                      if (_cachedBalance != null) {
+                                        return GestureDetector(
+                                          onTap: () {
+                                            cryptoAmountController.text =
+                                                _cachedBalance!.toStringAsFixed(
+                                                    Constants
+                                                        .decimalPlacesForCoin(
+                                                            coin));
+                                          },
+                                          child: Container(
+                                            color: Colors.transparent,
+                                            child: Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.end,
+                                              children: [
+                                                Text(
+                                                  "${Format.localizedStringAsFixed(
+                                                    value: _cachedBalance!,
+                                                    locale: locale,
+                                                    decimalPlaces: 8,
+                                                  )} ${coin.ticker}",
+                                                  style:
+                                                      STextStyles.titleBold12(
+                                                              context)
+                                                          .copyWith(
+                                                    fontSize: 10,
+                                                  ),
+                                                  textAlign: TextAlign.right,
+                                                ),
+                                                Text(
+                                                  "${Format.localizedStringAsFixed(
+                                                    value: _cachedBalance! *
+                                                        ref.watch(priceAnd24hChangeNotifierProvider
+                                                            .select((value) =>
+                                                                value
+                                                                    .getPrice(
+                                                                        coin)
+                                                                    .item1)),
+                                                    locale: locale,
+                                                    decimalPlaces: 2,
+                                                  )} ${ref.watch(prefsChangeNotifierProvider.select((value) => value.currency))}",
+                                                  style: STextStyles
+                                                          .titleBold12_400(
+                                                              context)
+                                                      .copyWith(
+                                                    fontSize: 8,
+                                                  ),
+                                                  textAlign: TextAlign.right,
+                                                )
+                                              ],
+                                            ),
+                                          ),
+                                        );
+                                      } else {
+                                        return Column(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.end,
+                                          children: [
+                                            AnimatedText(
+                                              stringsToLoopThrough: const [
+                                                "Loading balance   ",
+                                                "Loading balance.  ",
+                                                "Loading balance.. ",
+                                                "Loading balance...",
+                                              ],
+                                              style: STextStyles.itemSubtitle(
+                                                      context)
+                                                  .copyWith(
+                                                fontSize: 10,
+                                              ),
+                                            ),
+                                            const SizedBox(
+                                              height: 2,
+                                            ),
+                                            AnimatedText(
+                                              stringsToLoopThrough: const [
+                                                "Loading balance   ",
+                                                "Loading balance.  ",
+                                                "Loading balance.. ",
+                                                "Loading balance...",
+                                              ],
+                                              style: STextStyles.itemSubtitle(
+                                                      context)
+                                                  .copyWith(
+                                                fontSize: 8,
+                                              ),
+                                            )
+                                          ],
+                                        );
+                                      }
+                                    },
+                                  ),
+                                ],
+                              ),
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 16,
+                          ),
+                          Text(
+                            "Send to",
+                            style: STextStyles.smallMed12(context),
+                            textAlign: TextAlign.left,
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          ClipRRect(
                             borderRadius: BorderRadius.circular(
                               Constants.size.circularBorderRadius,
                             ),
-                          ),
-                          child: Padding(
-                            padding: const EdgeInsets.all(12.0),
-                            child: Row(
-                              children: [
-                                SvgPicture.asset(
-                                  Assets.svg.iconFor(coin: coin),
-                                  width: 22,
-                                  height: 22,
-                                ),
-                                const SizedBox(
-                                  width: 6,
-                                ),
-                                if (coin != Coin.firo &&
-                                    coin != Coin.firoTestNet)
-                                  Expanded(
-                                    child: Text(
-                                      ref.watch(provider
-                                          .select((value) => value.walletName)),
-                                      style: STextStyles.titleBold12(context),
-                                      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,
-                                      // ),
-                                      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(),
-                                FutureBuilder(
-                                  future: (coin != Coin.firo &&
-                                          coin != Coin.firoTestNet)
-                                      ? ref.watch(provider.select(
-                                          (value) => value.availableBalance))
-                                      : ref
-                                                  .watch(
-                                                      publicPrivateBalanceStateProvider
-                                                          .state)
-                                                  .state ==
-                                              "Private"
-                                          ? (ref.watch(provider).wallet
-                                                  as FiroWallet)
-                                              .availablePrivateBalance()
-                                          : (ref.watch(provider).wallet
-                                                  as FiroWallet)
-                                              .availablePublicBalance(),
-                                  builder:
-                                      (_, AsyncSnapshot<Decimal> snapshot) {
-                                    if (snapshot.connectionState ==
-                                            ConnectionState.done &&
-                                        snapshot.hasData) {
-                                      _cachedBalance = snapshot.data!;
-                                    }
-
-                                    if (_cachedBalance != null) {
-                                      return GestureDetector(
-                                        onTap: () {
-                                          cryptoAmountController.text =
-                                              _cachedBalance!.toStringAsFixed(
-                                                  Constants
-                                                      .decimalPlacesForCoin(
-                                                          coin));
-                                        },
-                                        child: Container(
-                                          color: Colors.transparent,
-                                          child: Column(
-                                            crossAxisAlignment:
-                                                CrossAxisAlignment.end,
-                                            children: [
-                                              Text(
-                                                "${Format.localizedStringAsFixed(
-                                                  value: _cachedBalance!,
-                                                  locale: locale,
-                                                  decimalPlaces: 8,
-                                                )} ${coin.ticker}",
-                                                style: STextStyles.titleBold12(
-                                                        context)
-                                                    .copyWith(
-                                                  fontSize: 10,
-                                                ),
-                                                textAlign: TextAlign.right,
-                                              ),
-                                              Text(
-                                                "${Format.localizedStringAsFixed(
-                                                  value: _cachedBalance! *
-                                                      ref.watch(
-                                                          priceAnd24hChangeNotifierProvider
-                                                              .select((value) =>
-                                                                  value
-                                                                      .getPrice(
-                                                                          coin)
-                                                                      .item1)),
-                                                  locale: locale,
-                                                  decimalPlaces: 2,
-                                                )} ${ref.watch(prefsChangeNotifierProvider.select((value) => value.currency))}",
-                                                style:
-                                                    STextStyles.titleBold12_400(
-                                                            context)
-                                                        .copyWith(
-                                                  fontSize: 8,
-                                                ),
-                                                textAlign: TextAlign.right,
-                                              )
-                                            ],
-                                          ),
-                                        ),
-                                      );
-                                    } else {
-                                      return Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.end,
-                                        children: [
-                                          AnimatedText(
-                                            stringsToLoopThrough: const [
-                                              "Loading balance   ",
-                                              "Loading balance.  ",
-                                              "Loading balance.. ",
-                                              "Loading balance...",
-                                            ],
-                                            style: STextStyles.itemSubtitle(
-                                                    context)
-                                                .copyWith(
-                                              fontSize: 10,
-                                            ),
-                                          ),
-                                          const SizedBox(
-                                            height: 2,
-                                          ),
-                                          AnimatedText(
-                                            stringsToLoopThrough: const [
-                                              "Loading balance   ",
-                                              "Loading balance.  ",
-                                              "Loading balance.. ",
-                                              "Loading balance...",
-                                            ],
-                                            style: STextStyles.itemSubtitle(
-                                                    context)
-                                                .copyWith(
-                                              fontSize: 8,
-                                            ),
-                                          )
-                                        ],
-                                      );
-                                    }
-                                  },
-                                ),
-                              ],
-                            ),
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        Text(
-                          "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"),
-                            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,
-                            ),
-                            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, _amountToSend);
@@ -707,211 +847,498 @@ 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(
-                              _address ?? "",
-                              ref
-                                  .read(walletsChangeNotifierProvider)
-                                  .getManager(walletId),
-                            );
+                          Builder(
+                            builder: (_) {
+                              final error = _updateInvalidAddressText(
+                                _address ?? "",
+                                ref
+                                    .read(walletsChangeNotifierProvider)
+                                    .getManager(walletId),
+                              );
 
-                            if (error == null || error.isEmpty) {
-                              return Container();
-                            } else {
-                              return Align(
-                                alignment: Alignment.topLeft,
-                                child: Padding(
-                                  padding: const EdgeInsets.only(
-                                    left: 12.0,
-                                    top: 4.0,
-                                  ),
-                                  child: Text(
-                                    error,
-                                    textAlign: TextAlign.left,
-                                    style: STextStyles.label(context).copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textError,
+                              if (error == null || error.isEmpty) {
+                                return Container();
+                              } else {
+                                return Align(
+                                  alignment: Alignment.topLeft,
+                                  child: Padding(
+                                    padding: const EdgeInsets.only(
+                                      left: 12.0,
+                                      top: 4.0,
+                                    ),
+                                    child: Text(
+                                      error,
+                                      textAlign: TextAlign.left,
+                                      style:
+                                          STextStyles.label(context).copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textError,
+                                      ),
                                     ),
                                   ),
+                                );
+                              }
+                            },
+                          ),
+                          if (coin == Coin.firo)
+                            const SizedBox(
+                              height: 12,
+                            ),
+                          if (coin == Coin.firo)
+                            Text(
+                              "Send from",
+                              style: STextStyles.smallMed12(context),
+                              textAlign: TextAlign.left,
+                            ),
+                          if (coin == Coin.firo)
+                            const SizedBox(
+                              height: 8,
+                            ),
+                          if (coin == Coin.firo)
+                            Stack(
+                              children: [
+                                TextField(
+                                  autocorrect: Util.isDesktop ? false : true,
+                                  enableSuggestions:
+                                      Util.isDesktop ? false : true,
+                                  readOnly: true,
+                                  textInputAction: TextInputAction.none,
                                 ),
-                              );
-                            }
-                          },
-                        ),
-                        if (coin == Coin.firo)
+                                Padding(
+                                  padding: const EdgeInsets.symmetric(
+                                    horizontal: 12,
+                                  ),
+                                  child: RawMaterialButton(
+                                    splashColor: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .highlight,
+                                    shape: RoundedRectangleBorder(
+                                      borderRadius: BorderRadius.circular(
+                                        Constants.size.circularBorderRadius,
+                                      ),
+                                    ),
+                                    onPressed: () {
+                                      showModalBottomSheet<dynamic>(
+                                        backgroundColor: Colors.transparent,
+                                        context: context,
+                                        shape: const RoundedRectangleBorder(
+                                          borderRadius: BorderRadius.vertical(
+                                            top: Radius.circular(20),
+                                          ),
+                                        ),
+                                        builder: (_) =>
+                                            FiroBalanceSelectionSheet(
+                                          walletId: walletId,
+                                        ),
+                                      );
+                                    },
+                                    child: Row(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceBetween,
+                                      children: [
+                                        Row(
+                                          children: [
+                                            Text(
+                                              "${ref.watch(publicPrivateBalanceStateProvider.state).state} balance",
+                                              style: STextStyles.itemSubtitle12(
+                                                  context),
+                                            ),
+                                            const SizedBox(
+                                              width: 10,
+                                            ),
+                                            FutureBuilder(
+                                              future: _firoBalanceFuture(
+                                                  provider, locale),
+                                              builder: (context,
+                                                  AsyncSnapshot<String?>
+                                                      snapshot) {
+                                                if (snapshot.connectionState ==
+                                                        ConnectionState.done &&
+                                                    snapshot.hasData) {
+                                                  if (ref
+                                                          .read(
+                                                              publicPrivateBalanceStateProvider
+                                                                  .state)
+                                                          .state ==
+                                                      "Private") {
+                                                    _privateBalanceString =
+                                                        snapshot.data!;
+                                                  } else {
+                                                    _publicBalanceString =
+                                                        snapshot.data!;
+                                                  }
+                                                }
+                                                if (ref
+                                                            .read(
+                                                                publicPrivateBalanceStateProvider
+                                                                    .state)
+                                                            .state ==
+                                                        "Private" &&
+                                                    _privateBalanceString !=
+                                                        null) {
+                                                  return Text(
+                                                    "$_privateBalanceString ${coin.ticker}",
+                                                    style: STextStyles
+                                                        .itemSubtitle(context),
+                                                  );
+                                                } else if (ref
+                                                            .read(
+                                                                publicPrivateBalanceStateProvider
+                                                                    .state)
+                                                            .state ==
+                                                        "Public" &&
+                                                    _publicBalanceString !=
+                                                        null) {
+                                                  return Text(
+                                                    "$_publicBalanceString ${coin.ticker}",
+                                                    style: STextStyles
+                                                        .itemSubtitle(context),
+                                                  );
+                                                } else {
+                                                  return AnimatedText(
+                                                    stringsToLoopThrough: const [
+                                                      "Loading balance",
+                                                      "Loading balance.",
+                                                      "Loading balance..",
+                                                      "Loading balance...",
+                                                    ],
+                                                    style: STextStyles
+                                                        .itemSubtitle(context),
+                                                  );
+                                                }
+                                              },
+                                            ),
+                                          ],
+                                        ),
+                                        SvgPicture.asset(
+                                          Assets.svg.chevronDown,
+                                          width: 8,
+                                          height: 4,
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .textSubtitle2,
+                                        ),
+                                      ],
+                                    ),
+                                  ),
+                                )
+                              ],
+                            ),
                           const SizedBox(
                             height: 12,
                           ),
-                        if (coin == Coin.firo)
-                          Text(
-                            "Send from",
-                            style: STextStyles.smallMed12(context),
-                            textAlign: TextAlign.left,
+                          Row(
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            children: [
+                              Text(
+                                "Amount",
+                                style: STextStyles.smallMed12(context),
+                                textAlign: TextAlign.left,
+                              ),
+                              BlueTextButton(
+                                text: "Send all ${coin.ticker}",
+                                onTap: () async {
+                                  if (coin == Coin.firo ||
+                                      coin == Coin.firoTestNet) {
+                                    final firoWallet =
+                                        ref.read(provider).wallet as FiroWallet;
+                                    if (ref
+                                            .read(
+                                                publicPrivateBalanceStateProvider
+                                                    .state)
+                                            .state ==
+                                        "Private") {
+                                      cryptoAmountController.text =
+                                          (await firoWallet
+                                                  .availablePrivateBalance())
+                                              .toStringAsFixed(Constants
+                                                  .decimalPlacesForCoin(coin));
+                                    } else {
+                                      cryptoAmountController.text =
+                                          (await firoWallet
+                                                  .availablePublicBalance())
+                                              .toStringAsFixed(Constants
+                                                  .decimalPlacesForCoin(coin));
+                                    }
+                                  } else {
+                                    cryptoAmountController.text = (await ref
+                                            .read(provider)
+                                            .availableBalance)
+                                        .toStringAsFixed(
+                                            Constants.decimalPlacesForCoin(
+                                                coin));
+                                  }
+                                },
+                              ),
+                            ],
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
+                            style: STextStyles.smallMed14(context).copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .textDark,
+                            ),
+                            key:
+                                const Key("amountInputFieldCryptoTextFieldKey"),
+                            controller: cryptoAmountController,
+                            focusNode: _cryptoFocus,
+                            keyboardType: const TextInputType.numberWithOptions(
+                              signed: false,
+                              decimal: true,
+                            ),
+                            textAlign: TextAlign.right,
+                            inputFormatters: [
+                              // regex to validate a crypto amount with 8 decimal places
+                              TextInputFormatter.withFunction((oldValue,
+                                      newValue) =>
+                                  RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
+                                          .hasMatch(newValue.text)
+                                      ? newValue
+                                      : oldValue),
+                            ],
+                            decoration: InputDecoration(
+                              contentPadding: const EdgeInsets.only(
+                                top: 12,
+                                right: 12,
+                              ),
+                              hintText: "0",
+                              hintStyle:
+                                  STextStyles.fieldLabel(context).copyWith(
+                                fontSize: 14,
+                              ),
+                              prefixIcon: FittedBox(
+                                fit: BoxFit.scaleDown,
+                                child: Padding(
+                                  padding: const EdgeInsets.all(12),
+                                  child: Text(
+                                    coin.ticker,
+                                    style: STextStyles.smallMed14(context)
+                                        .copyWith(
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .accentColorDark),
+                                  ),
+                                ),
+                              ),
+                            ),
+                          ),
+                          if (Prefs.instance.externalCalls)
+                            const SizedBox(
+                              height: 8,
+                            ),
+                          if (Prefs.instance.externalCalls)
+                            TextField(
+                              autocorrect: Util.isDesktop ? false : true,
+                              enableSuggestions: Util.isDesktop ? false : true,
+                              style: STextStyles.smallMed14(context).copyWith(
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .textDark,
+                              ),
+                              key:
+                                  const Key("amountInputFieldFiatTextFieldKey"),
+                              controller: baseAmountController,
+                              focusNode: _baseFocus,
+                              keyboardType:
+                                  const TextInputType.numberWithOptions(
+                                signed: false,
+                                decimal: true,
+                              ),
+                              textAlign: TextAlign.right,
+                              inputFormatters: [
+                                // regex to validate a fiat amount with 2 decimal places
+                                TextInputFormatter.withFunction((oldValue,
+                                        newValue) =>
+                                    RegExp(r'^([0-9]*[,.]?[0-9]{0,2}|[,.][0-9]{0,2})$')
+                                            .hasMatch(newValue.text)
+                                        ? newValue
+                                        : oldValue),
+                              ],
+                              onChanged: (baseAmountString) {
+                                if (baseAmountString.isNotEmpty &&
+                                    baseAmountString != "." &&
+                                    baseAmountString != ",") {
+                                  final baseAmount =
+                                      baseAmountString.contains(",")
+                                          ? Decimal.parse(baseAmountString
+                                              .replaceFirst(",", "."))
+                                          : Decimal.parse(baseAmountString);
+
+                                  var _price = ref
+                                      .read(priceAnd24hChangeNotifierProvider)
+                                      .getPrice(coin)
+                                      .item1;
+
+                                  if (_price == Decimal.zero) {
+                                    _amountToSend = Decimal.zero;
+                                  } else {
+                                    _amountToSend = baseAmount <= Decimal.zero
+                                        ? Decimal.zero
+                                        : (baseAmount / _price).toDecimal(
+                                            scaleOnInfinitePrecision:
+                                                Constants.decimalPlacesForCoin(
+                                                    coin));
+                                  }
+                                  if (_cachedAmountToSend != null &&
+                                      _cachedAmountToSend == _amountToSend) {
+                                    return;
+                                  }
+                                  _cachedAmountToSend = _amountToSend;
+                                  Logging.instance.log(
+                                      "it changed $_amountToSend $_cachedAmountToSend",
+                                      level: LogLevel.Info);
+
+                                  final amountString =
+                                      Format.localizedStringAsFixed(
+                                    value: _amountToSend!,
+                                    locale: ref
+                                        .read(
+                                            localeServiceChangeNotifierProvider)
+                                        .locale,
+                                    decimalPlaces:
+                                        Constants.decimalPlacesForCoin(coin),
+                                  );
+
+                                  _cryptoAmountChangeLock = true;
+                                  cryptoAmountController.text = amountString;
+                                  _cryptoAmountChangeLock = false;
+                                } else {
+                                  _amountToSend = Decimal.zero;
+                                  _cryptoAmountChangeLock = true;
+                                  cryptoAmountController.text = "";
+                                  _cryptoAmountChangeLock = false;
+                                }
+                                // setState(() {
+                                //   _calculateFeesFuture = calculateFees(
+                                //       Format.decimalAmountToSatoshis(
+                                //           _amountToSend!));
+                                // });
+                                _updatePreviewButtonState(
+                                    _address, _amountToSend);
+                              },
+                              decoration: InputDecoration(
+                                contentPadding: const EdgeInsets.only(
+                                  top: 12,
+                                  right: 12,
+                                ),
+                                hintText: "0",
+                                hintStyle:
+                                    STextStyles.fieldLabel(context).copyWith(
+                                  fontSize: 14,
+                                ),
+                                prefixIcon: FittedBox(
+                                  fit: BoxFit.scaleDown,
+                                  child: Padding(
+                                    padding: const EdgeInsets.all(12),
+                                    child: Text(
+                                      ref.watch(prefsChangeNotifierProvider
+                                          .select((value) => value.currency)),
+                                      style: STextStyles.smallMed14(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorDark),
+                                    ),
+                                  ),
+                                ),
+                              ),
+                            ),
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          Text(
+                            "Note (optional)",
+                            style: STextStyles.smallMed12(context),
+                            textAlign: TextAlign.left,
+                          ),
+                          const SizedBox(
+                            height: 8,
+                          ),
+                          ClipRRect(
+                            borderRadius: BorderRadius.circular(
+                              Constants.size.circularBorderRadius,
+                            ),
+                            child: TextField(
+                              autocorrect: Util.isDesktop ? false : true,
+                              enableSuggestions: Util.isDesktop ? false : true,
+                              controller: noteController,
+                              focusNode: _noteFocusNode,
+                              style: STextStyles.field(context),
+                              onChanged: (_) => setState(() {}),
+                              decoration: standardInputDecoration(
+                                "Type something...",
+                                _noteFocusNode,
+                                context,
+                              ).copyWith(
+                                suffixIcon: noteController.text.isNotEmpty
+                                    ? Padding(
+                                        padding:
+                                            const EdgeInsets.only(right: 0),
+                                        child: UnconstrainedBox(
+                                          child: Row(
+                                            children: [
+                                              TextFieldIconButton(
+                                                child: const XIcon(),
+                                                onTap: () async {
+                                                  setState(() {
+                                                    noteController.text = "";
+                                                  });
+                                                },
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                      )
+                                    : null,
+                              ),
+                            ),
+                          ),
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          Text(
+                            "Transaction fee (estimated)",
+                            style: STextStyles.smallMed12(context),
+                            textAlign: TextAlign.left,
                           ),
-                        if (coin == Coin.firo)
                           const SizedBox(
                             height: 8,
                           ),
-                        if (coin == Coin.firo)
                           Stack(
                             children: [
                               TextField(
                                 autocorrect: Util.isDesktop ? false : true,
                                 enableSuggestions:
                                     Util.isDesktop ? false : true,
+                                controller: feeController,
                                 readOnly: true,
                                 textInputAction: TextInputAction.none,
                               ),
@@ -928,780 +1355,172 @@ class _SendViewState extends ConsumerState<SendView> {
                                       Constants.size.circularBorderRadius,
                                     ),
                                   ),
-                                  onPressed: () {
-                                    showModalBottomSheet<dynamic>(
-                                      backgroundColor: Colors.transparent,
-                                      context: context,
-                                      shape: const RoundedRectangleBorder(
-                                        borderRadius: BorderRadius.vertical(
-                                          top: Radius.circular(20),
-                                        ),
-                                      ),
-                                      builder: (_) => FiroBalanceSelectionSheet(
-                                        walletId: walletId,
-                                      ),
-                                    );
-                                  },
-                                  child: Row(
-                                    mainAxisAlignment:
-                                        MainAxisAlignment.spaceBetween,
-                                    children: [
-                                      Row(
-                                        children: [
-                                          Text(
-                                            "${ref.watch(publicPrivateBalanceStateProvider.state).state} balance",
-                                            style: STextStyles.itemSubtitle12(
-                                                context),
-                                          ),
-                                          const SizedBox(
-                                            width: 10,
-                                          ),
-                                          FutureBuilder(
-                                            future: _firoBalanceFuture(
-                                                provider, locale),
-                                            builder: (context,
-                                                AsyncSnapshot<String?>
-                                                    snapshot) {
-                                              if (snapshot.connectionState ==
-                                                      ConnectionState.done &&
-                                                  snapshot.hasData) {
-                                                if (ref
-                                                        .read(
-                                                            publicPrivateBalanceStateProvider
-                                                                .state)
-                                                        .state ==
-                                                    "Private") {
-                                                  _privateBalanceString =
-                                                      snapshot.data!;
+                                  onPressed: (coin == Coin.firo ||
+                                              coin == Coin.firoTestNet) &&
+                                          ref
+                                                  .watch(
+                                                      publicPrivateBalanceStateProvider
+                                                          .state)
+                                                  .state ==
+                                              "Private"
+                                      ? null
+                                      : () {
+                                          showModalBottomSheet<dynamic>(
+                                            backgroundColor: Colors.transparent,
+                                            context: context,
+                                            shape: const RoundedRectangleBorder(
+                                              borderRadius:
+                                                  BorderRadius.vertical(
+                                                top: Radius.circular(20),
+                                              ),
+                                            ),
+                                            builder: (_) =>
+                                                TransactionFeeSelectionSheet(
+                                              walletId: walletId,
+                                              amount: Decimal.tryParse(
+                                                      cryptoAmountController
+                                                          .text) ??
+                                                  Decimal.zero,
+                                              updateChosen: (String fee) {
+                                                setState(() {
+                                                  _calculateFeesFuture =
+                                                      Future(() => fee);
+                                                });
+                                              },
+                                            ),
+                                          );
+                                        },
+                                  child: ((coin == Coin.firo ||
+                                              coin == Coin.firoTestNet) &&
+                                          ref
+                                                  .watch(
+                                                      publicPrivateBalanceStateProvider
+                                                          .state)
+                                                  .state ==
+                                              "Private")
+                                      ? Row(
+                                          children: [
+                                            FutureBuilder(
+                                              future: _calculateFeesFuture,
+                                              builder: (context, snapshot) {
+                                                if (snapshot.connectionState ==
+                                                        ConnectionState.done &&
+                                                    snapshot.hasData) {
+                                                  return Text(
+                                                    "~${snapshot.data! as String} ${coin.ticker}",
+                                                    style: STextStyles
+                                                        .itemSubtitle(context),
+                                                  );
                                                 } else {
-                                                  _publicBalanceString =
-                                                      snapshot.data!;
+                                                  return AnimatedText(
+                                                    stringsToLoopThrough: const [
+                                                      "Calculating",
+                                                      "Calculating.",
+                                                      "Calculating..",
+                                                      "Calculating...",
+                                                    ],
+                                                    style: STextStyles
+                                                        .itemSubtitle(context),
+                                                  );
                                                 }
-                                              }
-                                              if (ref
-                                                          .read(
-                                                              publicPrivateBalanceStateProvider
-                                                                  .state)
-                                                          .state ==
-                                                      "Private" &&
-                                                  _privateBalanceString !=
-                                                      null) {
-                                                return Text(
-                                                  "$_privateBalanceString ${coin.ticker}",
-                                                  style:
-                                                      STextStyles.itemSubtitle(
-                                                          context),
-                                                );
-                                              } else if (ref
-                                                          .read(
-                                                              publicPrivateBalanceStateProvider
-                                                                  .state)
-                                                          .state ==
-                                                      "Public" &&
-                                                  _publicBalanceString !=
-                                                      null) {
-                                                return Text(
-                                                  "$_publicBalanceString ${coin.ticker}",
-                                                  style:
-                                                      STextStyles.itemSubtitle(
-                                                          context),
-                                                );
-                                              } else {
-                                                return AnimatedText(
-                                                  stringsToLoopThrough: const [
-                                                    "Loading balance",
-                                                    "Loading balance.",
-                                                    "Loading balance..",
-                                                    "Loading balance...",
-                                                  ],
-                                                  style:
-                                                      STextStyles.itemSubtitle(
-                                                          context),
-                                                );
-                                              }
-                                            },
-                                          ),
-                                        ],
-                                      ),
-                                      SvgPicture.asset(
-                                        Assets.svg.chevronDown,
-                                        width: 8,
-                                        height: 4,
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textSubtitle2,
-                                      ),
-                                    ],
-                                  ),
+                                              },
+                                            ),
+                                          ],
+                                        )
+                                      : Row(
+                                          mainAxisAlignment:
+                                              MainAxisAlignment.spaceBetween,
+                                          children: [
+                                            Row(
+                                              children: [
+                                                Text(
+                                                  ref
+                                                      .watch(
+                                                          feeRateTypeStateProvider
+                                                              .state)
+                                                      .state
+                                                      .prettyName,
+                                                  style: STextStyles
+                                                      .itemSubtitle12(context),
+                                                ),
+                                                const SizedBox(
+                                                  width: 10,
+                                                ),
+                                                FutureBuilder(
+                                                  future: _calculateFeesFuture,
+                                                  builder: (context, snapshot) {
+                                                    if (snapshot.connectionState ==
+                                                            ConnectionState
+                                                                .done &&
+                                                        snapshot.hasData) {
+                                                      return Text(
+                                                        "~${snapshot.data! as String} ${coin.ticker}",
+                                                        style: STextStyles
+                                                            .itemSubtitle(
+                                                                context),
+                                                      );
+                                                    } else {
+                                                      return AnimatedText(
+                                                        stringsToLoopThrough: const [
+                                                          "Calculating",
+                                                          "Calculating.",
+                                                          "Calculating..",
+                                                          "Calculating...",
+                                                        ],
+                                                        style: STextStyles
+                                                            .itemSubtitle(
+                                                                context),
+                                                      );
+                                                    }
+                                                  },
+                                                ),
+                                              ],
+                                            ),
+                                            SvgPicture.asset(
+                                              Assets.svg.chevronDown,
+                                              width: 8,
+                                              height: 4,
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textSubtitle2,
+                                            ),
+                                          ],
+                                        ),
                                 ),
                               )
                             ],
                           ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: [
-                            Text(
-                              "Amount",
-                              style: STextStyles.smallMed12(context),
-                              textAlign: TextAlign.left,
-                            ),
-                            BlueTextButton(
-                              text: "Send all ${coin.ticker}",
-                              onTap: () async {
-                                if (coin == Coin.firo ||
-                                    coin == Coin.firoTestNet) {
-                                  final firoWallet =
-                                      ref.read(provider).wallet as FiroWallet;
-                                  if (ref
-                                          .read(
-                                              publicPrivateBalanceStateProvider
-                                                  .state)
-                                          .state ==
-                                      "Private") {
-                                    cryptoAmountController.text =
-                                        (await firoWallet
-                                                .availablePrivateBalance())
-                                            .toStringAsFixed(
-                                                Constants.decimalPlacesForCoin(
-                                                    coin));
-                                  } else {
-                                    cryptoAmountController.text =
-                                        (await firoWallet
-                                                .availablePublicBalance())
-                                            .toStringAsFixed(
-                                                Constants.decimalPlacesForCoin(
-                                                    coin));
-                                  }
-                                } else {
-                                  cryptoAmountController.text = (await ref
-                                          .read(provider)
-                                          .availableBalance)
-                                      .toStringAsFixed(
-                                          Constants.decimalPlacesForCoin(coin));
-                                }
-                              },
-                            ),
-                          ],
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        TextField(
-                          autocorrect: Util.isDesktop ? false : true,
-                          enableSuggestions: Util.isDesktop ? false : true,
-                          style: STextStyles.smallMed14(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .textDark,
-                          ),
-                          key: const Key("amountInputFieldCryptoTextFieldKey"),
-                          controller: cryptoAmountController,
-                          focusNode: _cryptoFocus,
-                          keyboardType: const TextInputType.numberWithOptions(
-                            signed: false,
-                            decimal: true,
-                          ),
-                          textAlign: TextAlign.right,
-                          inputFormatters: [
-                            // regex to validate a crypto amount with 8 decimal places
-                            TextInputFormatter.withFunction((oldValue,
-                                    newValue) =>
-                                RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
-                                        .hasMatch(newValue.text)
-                                    ? newValue
-                                    : oldValue),
-                          ],
-                          decoration: InputDecoration(
-                            contentPadding: const EdgeInsets.only(
-                              top: 12,
-                              right: 12,
-                            ),
-                            hintText: "0",
-                            hintStyle: STextStyles.fieldLabel(context).copyWith(
-                              fontSize: 14,
-                            ),
-                            prefixIcon: FittedBox(
-                              fit: BoxFit.scaleDown,
-                              child: Padding(
-                                padding: const EdgeInsets.all(12),
-                                child: Text(
-                                  coin.ticker,
-                                  style: STextStyles.smallMed14(context)
-                                      .copyWith(
-                                          color: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .accentColorDark),
-                                ),
-                              ),
-                            ),
-                          ),
-                        ),
-                        if (Prefs.instance.externalCalls)
+                          const Spacer(),
                           const SizedBox(
-                            height: 8,
+                            height: 12,
                           ),
-                        if (Prefs.instance.externalCalls)
-                          TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            style: STextStyles.smallMed14(context).copyWith(
-                              color: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .textDark,
-                            ),
-                            key: const Key("amountInputFieldFiatTextFieldKey"),
-                            controller: baseAmountController,
-                            focusNode: _baseFocus,
-                            keyboardType: const TextInputType.numberWithOptions(
-                              signed: false,
-                              decimal: true,
-                            ),
-                            textAlign: TextAlign.right,
-                            inputFormatters: [
-                              // regex to validate a fiat amount with 2 decimal places
-                              TextInputFormatter.withFunction((oldValue,
-                                      newValue) =>
-                                  RegExp(r'^([0-9]*[,.]?[0-9]{0,2}|[,.][0-9]{0,2})$')
-                                          .hasMatch(newValue.text)
-                                      ? newValue
-                                      : oldValue),
-                            ],
-                            onChanged: (baseAmountString) {
-                              if (baseAmountString.isNotEmpty &&
-                                  baseAmountString != "." &&
-                                  baseAmountString != ",") {
-                                final baseAmount = baseAmountString
-                                        .contains(",")
-                                    ? Decimal.parse(
-                                        baseAmountString.replaceFirst(",", "."))
-                                    : Decimal.parse(baseAmountString);
-
-                                var _price = ref
-                                    .read(priceAnd24hChangeNotifierProvider)
-                                    .getPrice(coin)
-                                    .item1;
-
-                                if (_price == Decimal.zero) {
-                                  _amountToSend = Decimal.zero;
-                                } else {
-                                  _amountToSend = baseAmount <= Decimal.zero
-                                      ? Decimal.zero
-                                      : (baseAmount / _price).toDecimal(
-                                          scaleOnInfinitePrecision:
-                                              Constants.decimalPlacesForCoin(
-                                                  coin));
-                                }
-                                if (_cachedAmountToSend != null &&
-                                    _cachedAmountToSend == _amountToSend) {
-                                  return;
-                                }
-                                _cachedAmountToSend = _amountToSend;
-                                Logging.instance.log(
-                                    "it changed $_amountToSend $_cachedAmountToSend",
-                                    level: LogLevel.Info);
-
-                                final amountString =
-                                    Format.localizedStringAsFixed(
-                                  value: _amountToSend!,
-                                  locale: ref
-                                      .read(localeServiceChangeNotifierProvider)
-                                      .locale,
-                                  decimalPlaces:
-                                      Constants.decimalPlacesForCoin(coin),
-                                );
-
-                                _cryptoAmountChangeLock = true;
-                                cryptoAmountController.text = amountString;
-                                _cryptoAmountChangeLock = false;
-                              } else {
-                                _amountToSend = Decimal.zero;
-                                _cryptoAmountChangeLock = true;
-                                cryptoAmountController.text = "";
-                                _cryptoAmountChangeLock = false;
-                              }
-                              // setState(() {
-                              //   _calculateFeesFuture = calculateFees(
-                              //       Format.decimalAmountToSatoshis(
-                              //           _amountToSend!));
-                              // });
-                              _updatePreviewButtonState(
-                                  _address, _amountToSend);
-                            },
-                            decoration: InputDecoration(
-                              contentPadding: const EdgeInsets.only(
-                                top: 12,
-                                right: 12,
-                              ),
-                              hintText: "0",
-                              hintStyle:
-                                  STextStyles.fieldLabel(context).copyWith(
-                                fontSize: 14,
-                              ),
-                              prefixIcon: FittedBox(
-                                fit: BoxFit.scaleDown,
-                                child: Padding(
-                                  padding: const EdgeInsets.all(12),
-                                  child: Text(
-                                    ref.watch(prefsChangeNotifierProvider
-                                        .select((value) => value.currency)),
-                                    style: STextStyles.smallMed14(context)
-                                        .copyWith(
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .accentColorDark),
-                                  ),
-                                ),
-                              ),
-                            ),
-                          ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        Text(
-                          "Note (optional)",
-                          style: STextStyles.smallMed12(context),
-                          textAlign: TextAlign.left,
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            controller: noteController,
-                            focusNode: _noteFocusNode,
-                            style: STextStyles.field(context),
-                            onChanged: (_) => setState(() {}),
-                            decoration: standardInputDecoration(
-                              "Type something...",
-                              _noteFocusNode,
-                              context,
-                            ).copyWith(
-                              suffixIcon: noteController.text.isNotEmpty
-                                  ? Padding(
-                                      padding: const EdgeInsets.only(right: 0),
-                                      child: UnconstrainedBox(
-                                        child: Row(
-                                          children: [
-                                            TextFieldIconButton(
-                                              child: const XIcon(),
-                                              onTap: () async {
-                                                setState(() {
-                                                  noteController.text = "";
-                                                });
-                                              },
-                                            ),
-                                          ],
-                                        ),
-                                      ),
-                                    )
-                                  : null,
-                            ),
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        Text(
-                          "Transaction fee (estimated)",
-                          style: STextStyles.smallMed12(context),
-                          textAlign: TextAlign.left,
-                        ),
-                        const SizedBox(
-                          height: 8,
-                        ),
-                        Stack(
-                          children: [
-                            TextField(
-                              autocorrect: Util.isDesktop ? false : true,
-                              enableSuggestions: Util.isDesktop ? false : true,
-                              controller: feeController,
-                              readOnly: true,
-                              textInputAction: TextInputAction.none,
-                            ),
-                            Padding(
-                              padding: const EdgeInsets.symmetric(
-                                horizontal: 12,
-                              ),
-                              child: RawMaterialButton(
-                                splashColor: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .highlight,
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
-                                  ),
-                                ),
-                                onPressed: (coin == Coin.firo ||
-                                            coin == Coin.firoTestNet) &&
-                                        ref
-                                                .watch(
-                                                    publicPrivateBalanceStateProvider
-                                                        .state)
-                                                .state ==
-                                            "Private"
-                                    ? null
-                                    : () {
-                                        showModalBottomSheet<dynamic>(
-                                          backgroundColor: Colors.transparent,
-                                          context: context,
-                                          shape: const RoundedRectangleBorder(
-                                            borderRadius: BorderRadius.vertical(
-                                              top: Radius.circular(20),
-                                            ),
-                                          ),
-                                          builder: (_) =>
-                                              TransactionFeeSelectionSheet(
-                                            walletId: walletId,
-                                            amount: Decimal.tryParse(
-                                                    cryptoAmountController
-                                                        .text) ??
-                                                Decimal.zero,
-                                            updateChosen: (String fee) {
-                                              setState(() {
-                                                _calculateFeesFuture =
-                                                    Future(() => fee);
-                                              });
-                                            },
-                                          ),
-                                        );
-                                      },
-                                child: ((coin == Coin.firo ||
-                                            coin == Coin.firoTestNet) &&
-                                        ref
-                                                .watch(
-                                                    publicPrivateBalanceStateProvider
-                                                        .state)
-                                                .state ==
-                                            "Private")
-                                    ? Row(
-                                        children: [
-                                          FutureBuilder(
-                                            future: _calculateFeesFuture,
-                                            builder: (context, snapshot) {
-                                              if (snapshot.connectionState ==
-                                                      ConnectionState.done &&
-                                                  snapshot.hasData) {
-                                                return Text(
-                                                  "~${snapshot.data! as String} ${coin.ticker}",
-                                                  style:
-                                                      STextStyles.itemSubtitle(
-                                                          context),
-                                                );
-                                              } else {
-                                                return AnimatedText(
-                                                  stringsToLoopThrough: const [
-                                                    "Calculating",
-                                                    "Calculating.",
-                                                    "Calculating..",
-                                                    "Calculating...",
-                                                  ],
-                                                  style:
-                                                      STextStyles.itemSubtitle(
-                                                          context),
-                                                );
-                                              }
-                                            },
-                                          ),
-                                        ],
-                                      )
-                                    : Row(
-                                        mainAxisAlignment:
-                                            MainAxisAlignment.spaceBetween,
-                                        children: [
-                                          Row(
-                                            children: [
-                                              Text(
-                                                ref
-                                                    .watch(
-                                                        feeRateTypeStateProvider
-                                                            .state)
-                                                    .state
-                                                    .prettyName,
-                                                style:
-                                                    STextStyles.itemSubtitle12(
-                                                        context),
-                                              ),
-                                              const SizedBox(
-                                                width: 10,
-                                              ),
-                                              FutureBuilder(
-                                                future: _calculateFeesFuture,
-                                                builder: (context, snapshot) {
-                                                  if (snapshot.connectionState ==
-                                                          ConnectionState
-                                                              .done &&
-                                                      snapshot.hasData) {
-                                                    return Text(
-                                                      "~${snapshot.data! as String} ${coin.ticker}",
-                                                      style: STextStyles
-                                                          .itemSubtitle(
-                                                              context),
-                                                    );
-                                                  } else {
-                                                    return AnimatedText(
-                                                      stringsToLoopThrough: const [
-                                                        "Calculating",
-                                                        "Calculating.",
-                                                        "Calculating..",
-                                                        "Calculating...",
-                                                      ],
-                                                      style: STextStyles
-                                                          .itemSubtitle(
-                                                              context),
-                                                    );
-                                                  }
-                                                },
-                                              ),
-                                            ],
-                                          ),
-                                          SvgPicture.asset(
-                                            Assets.svg.chevronDown,
-                                            width: 8,
-                                            height: 4,
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textSubtitle2,
-                                          ),
-                                        ],
-                                      ),
-                              ),
-                            )
-                          ],
-                        ),
-                        const Spacer(),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        TextButton(
-                          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) {
-                                    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();
-                                            },
-                                          ),
-                                        );
-                                      },
+                          TextButton(
+                            onPressed: ref
+                                    .watch(previewTxButtonStateProvider.state)
+                                    .state
+                                ? () async {
+                                    // wait for keyboard to disappear
+                                    FocusScope.of(context).unfocus();
+                                    await Future<void>.delayed(
+                                      const Duration(milliseconds: 100),
                                     );
-                                    return;
-                                  }
+                                    final manager = ref
+                                        .read(walletsChangeNotifierProvider)
+                                        .getManager(walletId);
 
-                                  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(
-                                              await (manager.wallet
-                                                      as FiroWallet)
-                                                  .availablePrivateBalance(),
-                                              coin);
-                                    } else {
-                                      availableBalance =
-                                          Format.decimalAmountToSatoshis(
-                                              await (manager.wallet
-                                                      as FiroWallet)
-                                                  .availablePublicBalance(),
-                                              coin);
-                                    }
-                                  } else {
-                                    availableBalance =
-                                        Format.decimalAmountToSatoshis(
-                                            await manager.availableBalance,
-                                            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>()!
-                                                .getSecondaryEnabledButtonColor(
-                                                    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>()!
-                                                .getPrimaryEnabledButtonColor(
-                                                    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>(
+                                    // TODO: remove the need for this!!
+                                    final bool isOwnAddress =
+                                        await manager.isOwnAddress(_address!);
+                                    if (isOwnAddress) {
+                                      await showDialog<dynamic>(
                                         context: context,
                                         useSafeArea: false,
                                         barrierDismissible: true,
                                         builder: (context) {
                                           return StackDialog(
                                             title: "Transaction failed",
-                                            message: e.toString(),
+                                            message:
+                                                "Sending to self is currently disabled",
                                             rightButton: TextButton(
                                               style: Theme.of(context)
                                                   .extension<StackColors>()!
@@ -1723,36 +1542,238 @@ class _SendViewState extends ConsumerState<SendView> {
                                             ),
                                           );
                                         },
+                                      );
+                                      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(
+                                                await (manager.wallet
+                                                        as FiroWallet)
+                                                    .availablePrivateBalance(),
+                                                coin);
+                                      } else {
+                                        availableBalance =
+                                            Format.decimalAmountToSatoshis(
+                                                await (manager.wallet
+                                                        as FiroWallet)
+                                                    .availablePublicBalance(),
+                                                coin);
+                                      }
+                                    } else {
+                                      availableBalance =
+                                          Format.decimalAmountToSatoshis(
+                                              await manager.availableBalance,
+                                              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>()!
+                                                  .getSecondaryEnabledButtonColor(
+                                                      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>()!
+                                                  .getPrimaryEnabledButtonColor(
+                                                      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>()!
+                                                    .getSecondaryEnabledButtonColor(
+                                                        context),
+                                                child: Text(
+                                                  "Ok",
+                                                  style: STextStyles.button(
+                                                          context)
+                                                      .copyWith(
+                                                          color: Theme.of(
+                                                                  context)
+                                                              .extension<
+                                                                  StackColors>()!
+                                                              .accentColorDark),
+                                                ),
+                                                onPressed: () {
+                                                  Navigator.of(context).pop();
+                                                },
+                                              ),
+                                            );
+                                          },
+                                        ));
+                                      }
                                     }
                                   }
-                                }
-                              : null,
-                          style: ref
-                                  .watch(previewTxButtonStateProvider.state)
-                                  .state
-                              ? Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .getPrimaryEnabledButtonColor(context)
-                              : Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .getPrimaryDisabledButtonColor(context),
-                          child: Text(
-                            "Preview",
-                            style: STextStyles.button(context),
+                                : null,
+                            style: ref
+                                    .watch(previewTxButtonStateProvider.state)
+                                    .state
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .getPrimaryEnabledButtonColor(context)
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .getPrimaryDisabledButtonColor(context),
+                            child: Text(
+                              "Preview",
+                              style: STextStyles.button(context),
+                            ),
                           ),
-                        ),
-                        const SizedBox(
-                          height: 4,
-                        ),
-                      ],
+                          const SizedBox(
+                            height: 4,
+                          ),
+                        ],
+                      ),
                     ),
                   ),
                 ),
               ),
-            ),
-          );
-        },
+            );
+          },
+        ),
       ),
     );
   }
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 dc2da2488..a1e78ba7d 100644
--- a/lib/pages/settings_views/global_settings_view/about_view.dart
+++ b/lib/pages/settings_views/global_settings_view/about_view.dart
@@ -11,6 +11,7 @@ import 'package:package_info_plus/package_info_plus.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/background.dart';
 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/rounded_white_container.dart';
@@ -117,408 +118,431 @@ class AboutView extends ConsumerWidget {
     ];
     Future commitMoneroFuture = Future.wait(futureMoneroList);
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "About",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "About",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      FutureBuilder(
-                        future: PackageInfo.fromPlatform(),
-                        builder:
-                            (context, AsyncSnapshot<PackageInfo> snapshot) {
-                          String version = "";
-                          String signature = "";
-                          String appName = "";
-                          String build = "";
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        FutureBuilder(
+                          future: PackageInfo.fromPlatform(),
+                          builder:
+                              (context, AsyncSnapshot<PackageInfo> snapshot) {
+                            String version = "";
+                            String signature = "";
+                            String appName = "";
+                            String build = "";
 
-                          if (snapshot.connectionState ==
-                                  ConnectionState.done &&
-                              snapshot.hasData) {
-                            version = snapshot.data!.version;
-                            build = snapshot.data!.buildNumber;
-                            signature = snapshot.data!.buildSignature;
-                            appName = snapshot.data!.appName;
-                          }
+                            if (snapshot.connectionState ==
+                                    ConnectionState.done &&
+                                snapshot.hasData) {
+                              version = snapshot.data!.version;
+                              build = snapshot.data!.buildNumber;
+                              signature = snapshot.data!.buildSignature;
+                              appName = snapshot.data!.appName;
+                            }
 
-                          return Column(
-                            crossAxisAlignment: CrossAxisAlignment.stretch,
+                            return Column(
+                              crossAxisAlignment: CrossAxisAlignment.stretch,
+                              children: [
+                                Center(
+                                  child: Text(
+                                    appName,
+                                    style: STextStyles.pageTitleH2(context),
+                                  ),
+                                ),
+                                const SizedBox(
+                                  height: 24,
+                                ),
+                                RoundedWhiteContainer(
+                                  child: Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.stretch,
+                                    children: [
+                                      Text(
+                                        "Version",
+                                        style: STextStyles.titleBold12(context),
+                                      ),
+                                      const SizedBox(
+                                        height: 4,
+                                      ),
+                                      SelectableText(
+                                        version,
+                                        style:
+                                            STextStyles.itemSubtitle(context),
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                                const SizedBox(
+                                  height: 12,
+                                ),
+                                RoundedWhiteContainer(
+                                  child: Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.stretch,
+                                    children: [
+                                      Text(
+                                        "Build number",
+                                        style: STextStyles.titleBold12(context),
+                                      ),
+                                      const SizedBox(
+                                        height: 4,
+                                      ),
+                                      SelectableText(
+                                        build,
+                                        style:
+                                            STextStyles.itemSubtitle(context),
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                                const SizedBox(
+                                  height: 12,
+                                ),
+                                RoundedWhiteContainer(
+                                  child: Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.stretch,
+                                    children: [
+                                      Text(
+                                        "Build signature",
+                                        style: STextStyles.titleBold12(context),
+                                      ),
+                                      const SizedBox(
+                                        height: 4,
+                                      ),
+                                      SelectableText(
+                                        signature,
+                                        style:
+                                            STextStyles.itemSubtitle(context),
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              ],
+                            );
+                          },
+                        ),
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        FutureBuilder(
+                            future: commitFiroFuture,
+                            builder:
+                                (context, AsyncSnapshot<dynamic> snapshot) {
+                              bool commitExists = false;
+                              bool isHead = false;
+                              CommitStatus stateOfCommit =
+                                  CommitStatus.notLoaded;
+
+                              if (snapshot.connectionState ==
+                                      ConnectionState.done &&
+                                  snapshot.hasData) {
+                                commitExists = snapshot.data![0] as bool;
+                                isHead = snapshot.data![1] as bool;
+                                if (commitExists && isHead) {
+                                  stateOfCommit = CommitStatus.isHead;
+                                } else if (commitExists) {
+                                  stateOfCommit = CommitStatus.isOldCommit;
+                                } else {
+                                  stateOfCommit = CommitStatus.notACommit;
+                                }
+                              }
+                              TextStyle indicationStyle =
+                                  STextStyles.itemSubtitle(context);
+                              switch (stateOfCommit) {
+                                case CommitStatus.isHead:
+                                  indicationStyle =
+                                      STextStyles.itemSubtitle(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorGreen);
+                                  break;
+                                case CommitStatus.isOldCommit:
+                                  indicationStyle =
+                                      STextStyles.itemSubtitle(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorYellow);
+                                  break;
+                                case CommitStatus.notACommit:
+                                  indicationStyle =
+                                      STextStyles.itemSubtitle(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorRed);
+                                  break;
+                                default:
+                                  break;
+                              }
+                              return RoundedWhiteContainer(
+                                child: Column(
+                                  crossAxisAlignment:
+                                      CrossAxisAlignment.stretch,
+                                  children: [
+                                    Text(
+                                      "Firo Build Commit",
+                                      style: STextStyles.titleBold12(context),
+                                    ),
+                                    const SizedBox(
+                                      height: 4,
+                                    ),
+                                    SelectableText(
+                                      firoCommit,
+                                      style: indicationStyle,
+                                    ),
+                                  ],
+                                ),
+                              );
+                            }),
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        FutureBuilder(
+                            future: commitEpicFuture,
+                            builder:
+                                (context, AsyncSnapshot<dynamic> snapshot) {
+                              bool commitExists = false;
+                              bool isHead = false;
+                              CommitStatus stateOfCommit =
+                                  CommitStatus.notLoaded;
+
+                              if (snapshot.connectionState ==
+                                      ConnectionState.done &&
+                                  snapshot.hasData) {
+                                commitExists = snapshot.data![0] as bool;
+                                isHead = snapshot.data![1] as bool;
+                                if (commitExists && isHead) {
+                                  stateOfCommit = CommitStatus.isHead;
+                                } else if (commitExists) {
+                                  stateOfCommit = CommitStatus.isOldCommit;
+                                } else {
+                                  stateOfCommit = CommitStatus.notACommit;
+                                }
+                              }
+                              TextStyle indicationStyle =
+                                  STextStyles.itemSubtitle(context);
+                              switch (stateOfCommit) {
+                                case CommitStatus.isHead:
+                                  indicationStyle =
+                                      STextStyles.itemSubtitle(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorGreen);
+                                  break;
+                                case CommitStatus.isOldCommit:
+                                  indicationStyle =
+                                      STextStyles.itemSubtitle(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorYellow);
+                                  break;
+                                case CommitStatus.notACommit:
+                                  indicationStyle =
+                                      STextStyles.itemSubtitle(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorRed);
+                                  break;
+                                default:
+                                  break;
+                              }
+                              return RoundedWhiteContainer(
+                                child: Column(
+                                  crossAxisAlignment:
+                                      CrossAxisAlignment.stretch,
+                                  children: [
+                                    Text(
+                                      "Epic Cash Build Commit",
+                                      style: STextStyles.titleBold12(context),
+                                    ),
+                                    const SizedBox(
+                                      height: 4,
+                                    ),
+                                    SelectableText(
+                                      epicCashCommit,
+                                      style: indicationStyle,
+                                    ),
+                                  ],
+                                ),
+                              );
+                            }),
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        FutureBuilder(
+                            future: commitMoneroFuture,
+                            builder:
+                                (context, AsyncSnapshot<dynamic> snapshot) {
+                              bool commitExists = false;
+                              bool isHead = false;
+                              CommitStatus stateOfCommit =
+                                  CommitStatus.notLoaded;
+
+                              if (snapshot.connectionState ==
+                                      ConnectionState.done &&
+                                  snapshot.hasData) {
+                                commitExists = snapshot.data![0] as bool;
+                                isHead = snapshot.data![1] as bool;
+                                if (commitExists && isHead) {
+                                  stateOfCommit = CommitStatus.isHead;
+                                } else if (commitExists) {
+                                  stateOfCommit = CommitStatus.isOldCommit;
+                                } else {
+                                  stateOfCommit = CommitStatus.notACommit;
+                                }
+                              }
+                              TextStyle indicationStyle =
+                                  STextStyles.itemSubtitle(context);
+                              switch (stateOfCommit) {
+                                case CommitStatus.isHead:
+                                  indicationStyle =
+                                      STextStyles.itemSubtitle(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorGreen);
+                                  break;
+                                case CommitStatus.isOldCommit:
+                                  indicationStyle =
+                                      STextStyles.itemSubtitle(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorYellow);
+                                  break;
+                                case CommitStatus.notACommit:
+                                  indicationStyle =
+                                      STextStyles.itemSubtitle(context)
+                                          .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .accentColorRed);
+                                  break;
+                                default:
+                                  break;
+                              }
+                              return RoundedWhiteContainer(
+                                child: Column(
+                                  crossAxisAlignment:
+                                      CrossAxisAlignment.stretch,
+                                  children: [
+                                    Text(
+                                      "Monero Build Commit",
+                                      style: STextStyles.titleBold12(context),
+                                    ),
+                                    const SizedBox(
+                                      height: 4,
+                                    ),
+                                    SelectableText(
+                                      moneroCommit,
+                                      style: indicationStyle,
+                                    ),
+                                  ],
+                                ),
+                              );
+                            }),
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        RoundedWhiteContainer(
+                          child: Column(
+                            crossAxisAlignment: CrossAxisAlignment.start,
                             children: [
-                              Center(
-                                child: Text(
-                                  appName,
-                                  style: STextStyles.pageTitleH2(context),
-                                ),
+                              Text(
+                                "Website",
+                                style: STextStyles.titleBold12(context),
                               ),
                               const SizedBox(
-                                height: 24,
+                                height: 4,
                               ),
-                              RoundedWhiteContainer(
-                                child: Column(
-                                  crossAxisAlignment:
-                                      CrossAxisAlignment.stretch,
-                                  children: [
-                                    Text(
-                                      "Version",
-                                      style: STextStyles.titleBold12(context),
-                                    ),
-                                    const SizedBox(
-                                      height: 4,
-                                    ),
-                                    SelectableText(
-                                      version,
-                                      style: STextStyles.itemSubtitle(context),
-                                    ),
-                                  ],
-                                ),
-                              ),
-                              const SizedBox(
-                                height: 12,
-                              ),
-                              RoundedWhiteContainer(
-                                child: Column(
-                                  crossAxisAlignment:
-                                      CrossAxisAlignment.stretch,
-                                  children: [
-                                    Text(
-                                      "Build number",
-                                      style: STextStyles.titleBold12(context),
-                                    ),
-                                    const SizedBox(
-                                      height: 4,
-                                    ),
-                                    SelectableText(
-                                      build,
-                                      style: STextStyles.itemSubtitle(context),
-                                    ),
-                                  ],
-                                ),
-                              ),
-                              const SizedBox(
-                                height: 12,
-                              ),
-                              RoundedWhiteContainer(
-                                child: Column(
-                                  crossAxisAlignment:
-                                      CrossAxisAlignment.stretch,
-                                  children: [
-                                    Text(
-                                      "Build signature",
-                                      style: STextStyles.titleBold12(context),
-                                    ),
-                                    const SizedBox(
-                                      height: 4,
-                                    ),
-                                    SelectableText(
-                                      signature,
-                                      style: STextStyles.itemSubtitle(context),
-                                    ),
-                                  ],
-                                ),
+                              BlueTextButton(
+                                text: "https://stackwallet.com",
+                                onTap: () {
+                                  launchUrl(
+                                    Uri.parse("https://stackwallet.com"),
+                                    mode: LaunchMode.externalApplication,
+                                  );
+                                },
                               ),
                             ],
-                          );
-                        },
-                      ),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      FutureBuilder(
-                          future: commitFiroFuture,
-                          builder: (context, AsyncSnapshot<dynamic> snapshot) {
-                            bool commitExists = false;
-                            bool isHead = false;
-                            CommitStatus stateOfCommit = CommitStatus.notLoaded;
-
-                            if (snapshot.connectionState ==
-                                    ConnectionState.done &&
-                                snapshot.hasData) {
-                              commitExists = snapshot.data![0] as bool;
-                              isHead = snapshot.data![1] as bool;
-                              if (commitExists && isHead) {
-                                stateOfCommit = CommitStatus.isHead;
-                              } else if (commitExists) {
-                                stateOfCommit = CommitStatus.isOldCommit;
-                              } else {
-                                stateOfCommit = CommitStatus.notACommit;
-                              }
-                            }
-                            TextStyle indicationStyle =
-                                STextStyles.itemSubtitle(context);
-                            switch (stateOfCommit) {
-                              case CommitStatus.isHead:
-                                indicationStyle =
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorGreen);
-                                break;
-                              case CommitStatus.isOldCommit:
-                                indicationStyle =
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorYellow);
-                                break;
-                              case CommitStatus.notACommit:
-                                indicationStyle =
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorRed);
-                                break;
-                              default:
-                                break;
-                            }
-                            return RoundedWhiteContainer(
-                              child: Column(
-                                crossAxisAlignment: CrossAxisAlignment.stretch,
-                                children: [
-                                  Text(
-                                    "Firo Build Commit",
-                                    style: STextStyles.titleBold12(context),
-                                  ),
-                                  const SizedBox(
-                                    height: 4,
-                                  ),
-                                  SelectableText(
-                                    firoCommit,
-                                    style: indicationStyle,
-                                  ),
-                                ],
-                              ),
-                            );
-                          }),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      FutureBuilder(
-                          future: commitEpicFuture,
-                          builder: (context, AsyncSnapshot<dynamic> snapshot) {
-                            bool commitExists = false;
-                            bool isHead = false;
-                            CommitStatus stateOfCommit = CommitStatus.notLoaded;
-
-                            if (snapshot.connectionState ==
-                                    ConnectionState.done &&
-                                snapshot.hasData) {
-                              commitExists = snapshot.data![0] as bool;
-                              isHead = snapshot.data![1] as bool;
-                              if (commitExists && isHead) {
-                                stateOfCommit = CommitStatus.isHead;
-                              } else if (commitExists) {
-                                stateOfCommit = CommitStatus.isOldCommit;
-                              } else {
-                                stateOfCommit = CommitStatus.notACommit;
-                              }
-                            }
-                            TextStyle indicationStyle =
-                                STextStyles.itemSubtitle(context);
-                            switch (stateOfCommit) {
-                              case CommitStatus.isHead:
-                                indicationStyle =
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorGreen);
-                                break;
-                              case CommitStatus.isOldCommit:
-                                indicationStyle =
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorYellow);
-                                break;
-                              case CommitStatus.notACommit:
-                                indicationStyle =
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorRed);
-                                break;
-                              default:
-                                break;
-                            }
-                            return RoundedWhiteContainer(
-                              child: Column(
-                                crossAxisAlignment: CrossAxisAlignment.stretch,
-                                children: [
-                                  Text(
-                                    "Epic Cash Build Commit",
-                                    style: STextStyles.titleBold12(context),
-                                  ),
-                                  const SizedBox(
-                                    height: 4,
-                                  ),
-                                  SelectableText(
-                                    epicCashCommit,
-                                    style: indicationStyle,
-                                  ),
-                                ],
-                              ),
-                            );
-                          }),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      FutureBuilder(
-                          future: commitMoneroFuture,
-                          builder: (context, AsyncSnapshot<dynamic> snapshot) {
-                            bool commitExists = false;
-                            bool isHead = false;
-                            CommitStatus stateOfCommit = CommitStatus.notLoaded;
-
-                            if (snapshot.connectionState ==
-                                    ConnectionState.done &&
-                                snapshot.hasData) {
-                              commitExists = snapshot.data![0] as bool;
-                              isHead = snapshot.data![1] as bool;
-                              if (commitExists && isHead) {
-                                stateOfCommit = CommitStatus.isHead;
-                              } else if (commitExists) {
-                                stateOfCommit = CommitStatus.isOldCommit;
-                              } else {
-                                stateOfCommit = CommitStatus.notACommit;
-                              }
-                            }
-                            TextStyle indicationStyle =
-                                STextStyles.itemSubtitle(context);
-                            switch (stateOfCommit) {
-                              case CommitStatus.isHead:
-                                indicationStyle =
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorGreen);
-                                break;
-                              case CommitStatus.isOldCommit:
-                                indicationStyle =
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorYellow);
-                                break;
-                              case CommitStatus.notACommit:
-                                indicationStyle =
-                                    STextStyles.itemSubtitle(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorRed);
-                                break;
-                              default:
-                                break;
-                            }
-                            return RoundedWhiteContainer(
-                              child: Column(
-                                crossAxisAlignment: CrossAxisAlignment.stretch,
-                                children: [
-                                  Text(
-                                    "Monero Build Commit",
-                                    style: STextStyles.titleBold12(context),
-                                  ),
-                                  const SizedBox(
-                                    height: 4,
-                                  ),
-                                  SelectableText(
-                                    moneroCommit,
-                                    style: indicationStyle,
-                                  ),
-                                ],
-                              ),
-                            );
-                          }),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      RoundedWhiteContainer(
-                        child: Column(
-                          crossAxisAlignment: CrossAxisAlignment.start,
-                          children: [
-                            Text(
-                              "Website",
-                              style: STextStyles.titleBold12(context),
-                            ),
-                            const SizedBox(
-                              height: 4,
-                            ),
-                            BlueTextButton(
-                              text: "https://stackwallet.com",
-                              onTap: () {
-                                launchUrl(
-                                  Uri.parse("https://stackwallet.com"),
-                                  mode: LaunchMode.externalApplication,
-                                );
-                              },
-                            ),
-                          ],
+                          ),
                         ),
-                      ),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      const Spacer(),
-                      RichText(
-                        textAlign: TextAlign.center,
-                        text: TextSpan(
-                          style: STextStyles.label(context),
-                          children: [
-                            const TextSpan(
-                                text:
-                                    "By using Stack Wallet, you agree to the "),
-                            TextSpan(
-                              text: "Terms of service",
-                              style: STextStyles.richLink(context),
-                              recognizer: TapGestureRecognizer()
-                                ..onTap = () {
-                                  launchUrl(
-                                    Uri.parse(
-                                        "https://stackwallet.com/terms-of-service.html"),
-                                    mode: LaunchMode.externalApplication,
-                                  );
-                                },
-                            ),
-                            const TextSpan(text: " and "),
-                            TextSpan(
-                              text: "Privacy policy",
-                              style: STextStyles.richLink(context),
-                              recognizer: TapGestureRecognizer()
-                                ..onTap = () {
-                                  launchUrl(
-                                    Uri.parse(
-                                        "https://stackwallet.com/privacy-policy.html"),
-                                    mode: LaunchMode.externalApplication,
-                                  );
-                                },
-                            ),
-                          ],
+                        const SizedBox(
+                          height: 12,
                         ),
-                      ),
-                    ],
+                        const Spacer(),
+                        RichText(
+                          textAlign: TextAlign.center,
+                          text: TextSpan(
+                            style: STextStyles.label(context),
+                            children: [
+                              const TextSpan(
+                                  text:
+                                      "By using Stack Wallet, you agree to the "),
+                              TextSpan(
+                                text: "Terms of service",
+                                style: STextStyles.richLink(context),
+                                recognizer: TapGestureRecognizer()
+                                  ..onTap = () {
+                                    launchUrl(
+                                      Uri.parse(
+                                          "https://stackwallet.com/terms-of-service.html"),
+                                      mode: LaunchMode.externalApplication,
+                                    );
+                                  },
+                              ),
+                              const TextSpan(text: " and "),
+                              TextSpan(
+                                text: "Privacy policy",
+                                style: STextStyles.richLink(context),
+                                recognizer: TapGestureRecognizer()
+                                  ..onTap = () {
+                                    launchUrl(
+                                      Uri.parse(
+                                          "https://stackwallet.com/privacy-policy.html"),
+                                      mode: LaunchMode.externalApplication,
+                                    );
+                                  },
+                              ),
+                            ],
+                          ),
+                        ),
+                      ],
+                    ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/advanced_views/advanced_settings_view.dart b/lib/pages/settings_views/global_settings_view/advanced_views/advanced_settings_view.dart
index 86212e0c7..06b798c36 100644
--- a/lib/pages/settings_views/global_settings_view/advanced_views/advanced_settings_view.dart
+++ b/lib/pages/settings_views/global_settings_view/advanced_views/advanced_settings_view.dart
@@ -1,16 +1,15 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_views/debug_view.dart';
+import 'package:stackwallet/pages/stack_privacy_calls.dart';
 import 'package:stackwallet/providers/global/prefs_provider.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/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
-import 'package:tuple/tuple.dart';
-
-import 'package:stackwallet/pages/stack_privacy_calls.dart';
 
 class AdvancedSettingsView extends StatelessWidget {
   const AdvancedSettingsView({
@@ -23,158 +22,160 @@ class AdvancedSettingsView extends StatelessWidget {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Advanced",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Advanced",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              RoundedWhiteContainer(
+                padding: const EdgeInsets.all(0),
+                child: RawMaterialButton(
+                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                  shape: RoundedRectangleBorder(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
                   ),
-                ),
-                onPressed: () {
-                  Navigator.of(context).pushNamed(DebugView.routeName);
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    children: [
-                      Text(
-                        "Debug info",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                    ],
+                  onPressed: () {
+                    Navigator.of(context).pushNamed(DebugView.routeName);
+                  },
+                  child: Padding(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 12,
+                      vertical: 20,
+                    ),
+                    child: Row(
+                      children: [
+                        Text(
+                          "Debug info",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
                   ),
                 ),
               ),
-            ),
-            const SizedBox(
-              height: 8,
-            ),
-            RoundedWhiteContainer(
-              child: Consumer(
-                builder: (_, ref, __) {
-                  return RawMaterialButton(
-                    // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                    shape: RoundedRectangleBorder(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
+              const SizedBox(
+                height: 8,
+              ),
+              RoundedWhiteContainer(
+                child: Consumer(
+                  builder: (_, ref, __) {
+                    return RawMaterialButton(
+                      // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
                       ),
-                    ),
-                    onPressed: null,
-                    child: Padding(
-                      padding: const EdgeInsets.symmetric(vertical: 8),
-                      child: Row(
-                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        children: [
-                          Text(
-                            "Toggle testnet coins",
-                            style: STextStyles.titleBold12(context),
-                            textAlign: TextAlign.left,
-                          ),
-                          SizedBox(
-                            height: 20,
-                            width: 40,
-                            child: DraggableSwitchButton(
-                              isOn: ref.watch(
-                                prefsChangeNotifierProvider
-                                    .select((value) => value.showTestNetCoins),
-                              ),
-                              onValueChanged: (newValue) {
-                                ref
-                                    .read(prefsChangeNotifierProvider)
-                                    .showTestNetCoins = newValue;
-                              },
+                      onPressed: null,
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(vertical: 8),
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          children: [
+                            Text(
+                              "Toggle testnet coins",
+                              style: STextStyles.titleBold12(context),
+                              textAlign: TextAlign.left,
                             ),
-                          ),
-                        ],
-                      ),
-                    ),
-                  );
-                },
-              ),
-            ),
-            const SizedBox(
-              height: 8,
-            ),
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: Consumer(
-                builder: (_, ref, __) {
-                  final externalCalls = ref.watch(
-                    prefsChangeNotifierProvider
-                        .select((value) => value.externalCalls),
-                  );
-                  return RawMaterialButton(
-                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                    shape: RoundedRectangleBorder(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
-                      ),
-                    ),
-                    onPressed: () {
-                      Navigator.of(context).pushNamed(
-                        StackPrivacyCalls.routeName,
-                        arguments: true,
-                      );
-                    },
-                    child: Padding(
-                      padding: const EdgeInsets.symmetric(
-                        horizontal: 12,
-                        vertical: 20,
-                      ),
-                      child: Row(
-                        children: [
-                          RichText(
-                            textAlign: TextAlign.left,
-                            text: TextSpan(
-                              children: [
-                                TextSpan(
-                                  text: "Stack Experience",
-                                  style: STextStyles.titleBold12(context),
+                            SizedBox(
+                              height: 20,
+                              width: 40,
+                              child: DraggableSwitchButton(
+                                isOn: ref.watch(
+                                  prefsChangeNotifierProvider.select(
+                                      (value) => value.showTestNetCoins),
                                 ),
-                                TextSpan(
-                                  text: externalCalls
-                                      ? "\nEasy crypto"
-                                      : "\nIncognito",
-                                  style: STextStyles.label(context)
-                                      .copyWith(fontSize: 15.0),
-                                )
-                              ],
+                                onValueChanged: (newValue) {
+                                  ref
+                                      .read(prefsChangeNotifierProvider)
+                                      .showTestNetCoins = newValue;
+                                },
+                              ),
                             ),
-                          ),
-                        ],
+                          ],
+                        ),
                       ),
-                    ),
-                  );
-                },
+                    );
+                  },
+                ),
               ),
-            ),
-          ],
+              const SizedBox(
+                height: 8,
+              ),
+              RoundedWhiteContainer(
+                padding: const EdgeInsets.all(0),
+                child: Consumer(
+                  builder: (_, ref, __) {
+                    final externalCalls = ref.watch(
+                      prefsChangeNotifierProvider
+                          .select((value) => value.externalCalls),
+                    );
+                    return RawMaterialButton(
+                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                      ),
+                      onPressed: () {
+                        Navigator.of(context).pushNamed(
+                          StackPrivacyCalls.routeName,
+                          arguments: true,
+                        );
+                      },
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 12,
+                          vertical: 20,
+                        ),
+                        child: Row(
+                          children: [
+                            RichText(
+                              textAlign: TextAlign.left,
+                              text: TextSpan(
+                                children: [
+                                  TextSpan(
+                                    text: "Stack Experience",
+                                    style: STextStyles.titleBold12(context),
+                                  ),
+                                  TextSpan(
+                                    text: externalCalls
+                                        ? "\nEasy crypto"
+                                        : "\nIncognito",
+                                    style: STextStyles.label(context)
+                                        .copyWith(fontSize: 15.0),
+                                  )
+                                ],
+                              ),
+                            ),
+                          ],
+                        ),
+                      ),
+                    );
+                  },
+                ),
+              ),
+            ],
+          ),
         ),
       ),
     );
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 055773ef6..33f21759e 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
@@ -26,6 +26,7 @@ import 'package:stackwallet/utilities/stack_file_system.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/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';
@@ -99,474 +100,484 @@ class _DebugViewState extends ConsumerState<DebugView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Debug",
-          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("deleteLogsAppBarButtonKey"),
-                size: 36,
-                shadows: const [],
-                color: Theme.of(context).extension<StackColors>()!.background,
-                icon: SvgPicture.asset(
-                  Assets.svg.trash,
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .accentColorDark,
-                  width: 20,
-                  height: 20,
-                ),
-                onPressed: () async {
-                  await showDialog<void>(
-                    context: context,
-                    builder: (_) => StackDialog(
-                      title: "Delete logs?",
-                      message:
-                          "You are about to delete all logs permanently. Are you sure?",
-                      leftButton: TextButton(
-                        style: Theme.of(context)
-                            .extension<StackColors>()!
-                            .getSecondaryEnabledButtonColor(context),
-                        child: Text(
-                          "Cancel",
-                          style: STextStyles.itemSubtitle12(context),
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Debug",
+            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("deleteLogsAppBarButtonKey"),
+                  size: 36,
+                  shadows: const [],
+                  color: Theme.of(context).extension<StackColors>()!.background,
+                  icon: SvgPicture.asset(
+                    Assets.svg.trash,
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .accentColorDark,
+                    width: 20,
+                    height: 20,
+                  ),
+                  onPressed: () async {
+                    await showDialog<void>(
+                      context: context,
+                      builder: (_) => StackDialog(
+                        title: "Delete logs?",
+                        message:
+                            "You are about to delete all logs permanently. Are you sure?",
+                        leftButton: TextButton(
+                          style: Theme.of(context)
+                              .extension<StackColors>()!
+                              .getSecondaryEnabledButtonColor(context),
+                          child: Text(
+                            "Cancel",
+                            style: STextStyles.itemSubtitle12(context),
+                          ),
+                          onPressed: () {
+                            Navigator.of(context).pop();
+                          },
                         ),
-                        onPressed: () {
-                          Navigator.of(context).pop();
-                        },
-                      ),
-                      rightButton: TextButton(
-                        style: Theme.of(context)
-                            .extension<StackColors>()!
-                            .getPrimaryEnabledButtonColor(context),
-                        child: Text(
-                          "Delete logs",
-                          style: STextStyles.button(context),
-                        ),
-                        onPressed: () async {
-                          Navigator.of(context).pop();
+                        rightButton: TextButton(
+                          style: Theme.of(context)
+                              .extension<StackColors>()!
+                              .getPrimaryEnabledButtonColor(context),
+                          child: Text(
+                            "Delete logs",
+                            style: STextStyles.button(context),
+                          ),
+                          onPressed: () async {
+                            Navigator.of(context).pop();
 
-                          bool shouldPop = false;
-                          unawaited(showDialog<dynamic>(
-                            barrierDismissible: false,
-                            context: context,
-                            builder: (_) => WillPopScope(
-                              onWillPop: () async {
-                                return shouldPop;
-                              },
-                              child: const CustomLoadingOverlay(
-                                message: "Deleting logs...",
-                                eventBus: null,
+                            bool shouldPop = false;
+                            unawaited(showDialog<dynamic>(
+                              barrierDismissible: false,
+                              context: context,
+                              builder: (_) => WillPopScope(
+                                onWillPop: () async {
+                                  return shouldPop;
+                                },
+                                child: const CustomLoadingOverlay(
+                                  message: "Deleting logs...",
+                                  eventBus: null,
+                                ),
                               ),
-                            ),
-                          ));
+                            ));
 
-                          await ref
-                              .read(debugServiceProvider)
-                              .deleteAllMessages();
-                          await ref
-                              .read(debugServiceProvider)
-                              .updateRecentLogs();
+                            await ref
+                                .read(debugServiceProvider)
+                                .deleteAllMessages();
+                            await ref
+                                .read(debugServiceProvider)
+                                .updateRecentLogs();
 
-                          shouldPop = true;
+                            shouldPop = true;
 
-                          if (mounted) {
-                            Navigator.pop(context);
-                            unawaited(showFloatingFlushBar(
-                                type: FlushBarType.info,
-                                context: context,
-                                message: 'Logs cleared!'));
-                          }
-                        },
+                            if (mounted) {
+                              Navigator.pop(context);
+                              unawaited(showFloatingFlushBar(
+                                  type: FlushBarType.info,
+                                  context: context,
+                                  message: 'Logs cleared!'));
+                            }
+                          },
+                        ),
                       ),
-                    ),
-                  );
-                },
+                    );
+                  },
+                ),
               ),
             ),
-          ),
-        ],
-      ),
-      body: Padding(
-        padding: const EdgeInsets.only(
-          top: 12,
-          left: 16,
-          right: 16,
+          ],
         ),
-        child: NestedScrollView(
-          floatHeaderSlivers: true,
-          headerSliverBuilder: (context, innerBoxIsScrolled) {
-            return [
-              SliverOverlapAbsorber(
-                handle:
-                    NestedScrollView.sliverOverlapAbsorberHandleFor(context),
-                sliver: SliverToBoxAdapter(
-                  child: Padding(
-                    padding: const EdgeInsets.only(bottom: 16),
-                    child: Column(
-                      children: [
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            autocorrect: Util.isDesktop ? false : true,
-                            enableSuggestions: Util.isDesktop ? false : true,
-                            controller: _searchController,
-                            focusNode: _searchFocusNode,
-                            onChanged: (newString) {
-                              setState(() => _searchTerm = newString);
-                            },
-                            style: STextStyles.field(context),
-                            decoration: standardInputDecoration(
-                              "Search",
-                              _searchFocusNode,
-                              context,
-                            ).copyWith(
-                              prefixIcon: Padding(
-                                padding: const EdgeInsets.symmetric(
-                                  horizontal: 10,
-                                  vertical: 16,
-                                ),
-                                child: SvgPicture.asset(
-                                  Assets.svg.search,
-                                  width: 16,
-                                  height: 16,
-                                ),
-                              ),
-                              suffixIcon: _searchController.text.isNotEmpty
-                                  ? Padding(
-                                      padding: const EdgeInsets.only(right: 0),
-                                      child: UnconstrainedBox(
-                                        child: Row(
-                                          children: [
-                                            TextFieldIconButton(
-                                              child: const XIcon(),
-                                              onTap: () async {
-                                                setState(() {
-                                                  _searchController.text = "";
-                                                  _searchTerm = "";
-                                                });
-                                              },
-                                            ),
-                                          ],
-                                        ),
-                                      ),
-                                    )
-                                  : null,
+        body: Padding(
+          padding: const EdgeInsets.only(
+            top: 12,
+            left: 16,
+            right: 16,
+          ),
+          child: NestedScrollView(
+            floatHeaderSlivers: true,
+            headerSliverBuilder: (context, innerBoxIsScrolled) {
+              return [
+                SliverOverlapAbsorber(
+                  handle:
+                      NestedScrollView.sliverOverlapAbsorberHandleFor(context),
+                  sliver: SliverToBoxAdapter(
+                    child: Padding(
+                      padding: const EdgeInsets.only(bottom: 16),
+                      child: Column(
+                        children: [
+                          ClipRRect(
+                            borderRadius: BorderRadius.circular(
+                              Constants.size.circularBorderRadius,
                             ),
-                          ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          children: [
-                            BlueTextButton(
-                              text: "Save Debug Info to clipboard",
-                              onTap: () async {
-                                try {
-                                  final packageInfo =
-                                      await PackageInfo.fromPlatform();
-                                  final version = packageInfo.version;
-                                  final build = packageInfo.buildNumber;
-                                  final signature = packageInfo.buildSignature;
-                                  final appName = packageInfo.appName;
-                                  String firoCommit =
-                                      FIRO_VERSIONS.getPluginVersion();
-                                  String epicCashCommit =
-                                      EPIC_VERSIONS.getPluginVersion();
-                                  String moneroCommit =
-                                      MONERO_VERSIONS.getPluginVersion();
-                                  DeviceInfoPlugin deviceInfoPlugin =
-                                      DeviceInfoPlugin();
-                                  final deviceInfo =
-                                      await deviceInfoPlugin.deviceInfo;
-                                  var deviceInfoMap = deviceInfo.toMap();
-                                  deviceInfoMap.remove("systemFeatures");
-
-                                  final logs = filtered(
-                                          ref.watch(debugServiceProvider.select(
-                                              (value) => value.recentLogs)),
-                                          _searchTerm)
-                                      .reversed
-                                      .toList(growable: false);
-                                  List errorLogs = [];
-                                  for (var log in logs) {
-                                    if (log.logLevel == LogLevel.Error ||
-                                        log.logLevel == LogLevel.Fatal) {
-                                      errorLogs.add(
-                                          "${log.logLevel}: ${log.message}");
-                                    }
-                                  }
-
-                                  final finalDebugMap = {
-                                    "version": version,
-                                    "build": build,
-                                    "signature": signature,
-                                    "appName": appName,
-                                    "firoCommit": firoCommit,
-                                    "epicCashCommit": epicCashCommit,
-                                    "moneroCommit": moneroCommit,
-                                    "deviceInfoMap": deviceInfoMap,
-                                    "errorLogs": errorLogs,
-                                  };
-                                  Logging.instance.log(
-                                      json.encode(finalDebugMap),
-                                      level: LogLevel.Info,
-                                      printFullLength: true);
-                                  const ClipboardInterface clipboard =
-                                      ClipboardWrapper();
-                                  await clipboard.setData(
-                                    ClipboardData(
-                                        text: json.encode(finalDebugMap)),
-                                  );
-                                } catch (e, s) {
-                                  Logging.instance
-                                      .log("$e $s", level: LogLevel.Error);
-                                }
+                            child: TextField(
+                              autocorrect: Util.isDesktop ? false : true,
+                              enableSuggestions: Util.isDesktop ? false : true,
+                              controller: _searchController,
+                              focusNode: _searchFocusNode,
+                              onChanged: (newString) {
+                                setState(() => _searchTerm = newString);
                               },
+                              style: STextStyles.field(context),
+                              decoration: standardInputDecoration(
+                                "Search",
+                                _searchFocusNode,
+                                context,
+                              ).copyWith(
+                                prefixIcon: Padding(
+                                  padding: const EdgeInsets.symmetric(
+                                    horizontal: 10,
+                                    vertical: 16,
+                                  ),
+                                  child: SvgPicture.asset(
+                                    Assets.svg.search,
+                                    width: 16,
+                                    height: 16,
+                                  ),
+                                ),
+                                suffixIcon: _searchController.text.isNotEmpty
+                                    ? Padding(
+                                        padding:
+                                            const EdgeInsets.only(right: 0),
+                                        child: UnconstrainedBox(
+                                          child: Row(
+                                            children: [
+                                              TextFieldIconButton(
+                                                child: const XIcon(),
+                                                onTap: () async {
+                                                  setState(() {
+                                                    _searchController.text = "";
+                                                    _searchTerm = "";
+                                                  });
+                                                },
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                      )
+                                    : null,
+                              ),
                             ),
-                            const Spacer(),
-                            BlueTextButton(
-                              text: "Save logs to file",
-                              onTap: () async {
-                                final systemfile = SWBFileSystem();
-                                await systemfile.prepareStorage();
-                                Directory rootPath = await StackFileSystem
-                                    .applicationRootDirectory();
-
-                                if (Platform.isAndroid) {
-                                  rootPath = Directory("/storage/emulated/0/");
-                                }
-
-                                Directory dir =
-                                    Directory('${rootPath.path}/Documents');
-                                if (Platform.isIOS) {
-                                  dir = Directory(rootPath.path);
-                                }
-                                try {
-                                  if (!dir.existsSync()) {
-                                    dir.createSync();
-                                  }
-                                } catch (e, s) {
-                                  Logging.instance
-                                      .log("$e\n$s", level: LogLevel.Error);
-                                }
-                                String? path;
-                                if (Platform.isAndroid) {
-                                  path = dir.path;
-                                } else {
-                                  path = await FilePicker.platform
-                                      .getDirectoryPath(
-                                    dialogTitle: "Choose Log Save Location",
-                                    initialDirectory:
-                                        systemfile.startPath!.path,
-                                    lockParentWindow: true,
-                                  );
-                                }
-
-                                if (path != null) {
-                                  final eventBus = EventBus();
-                                  bool shouldPop = false;
-                                  unawaited(showDialog<dynamic>(
-                                    barrierDismissible: false,
-                                    context: context,
-                                    builder: (_) => WillPopScope(
-                                      onWillPop: () async {
-                                        return shouldPop;
-                                      },
-                                      child: CustomLoadingOverlay(
-                                        message: "Generating Stack logs file",
-                                        eventBus: eventBus,
-                                      ),
-                                    ),
-                                  ));
-
-                                  bool logssaved = true;
-                                  var filename;
+                          ),
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          Row(
+                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            children: [
+                              BlueTextButton(
+                                text: "Save Debug Info to clipboard",
+                                onTap: () async {
                                   try {
-                                    filename = await ref
-                                        .read(debugServiceProvider)
-                                        .exportToFile(path, eventBus);
+                                    final packageInfo =
+                                        await PackageInfo.fromPlatform();
+                                    final version = packageInfo.version;
+                                    final build = packageInfo.buildNumber;
+                                    final signature =
+                                        packageInfo.buildSignature;
+                                    final appName = packageInfo.appName;
+                                    String firoCommit =
+                                        FIRO_VERSIONS.getPluginVersion();
+                                    String epicCashCommit =
+                                        EPIC_VERSIONS.getPluginVersion();
+                                    String moneroCommit =
+                                        MONERO_VERSIONS.getPluginVersion();
+                                    DeviceInfoPlugin deviceInfoPlugin =
+                                        DeviceInfoPlugin();
+                                    final deviceInfo =
+                                        await deviceInfoPlugin.deviceInfo;
+                                    var deviceInfoMap = deviceInfo.toMap();
+                                    deviceInfoMap.remove("systemFeatures");
+
+                                    final logs = filtered(
+                                            ref.watch(debugServiceProvider
+                                                .select((value) =>
+                                                    value.recentLogs)),
+                                            _searchTerm)
+                                        .reversed
+                                        .toList(growable: false);
+                                    List errorLogs = [];
+                                    for (var log in logs) {
+                                      if (log.logLevel == LogLevel.Error ||
+                                          log.logLevel == LogLevel.Fatal) {
+                                        errorLogs.add(
+                                            "${log.logLevel}: ${log.message}");
+                                      }
+                                    }
+
+                                    final finalDebugMap = {
+                                      "version": version,
+                                      "build": build,
+                                      "signature": signature,
+                                      "appName": appName,
+                                      "firoCommit": firoCommit,
+                                      "epicCashCommit": epicCashCommit,
+                                      "moneroCommit": moneroCommit,
+                                      "deviceInfoMap": deviceInfoMap,
+                                      "errorLogs": errorLogs,
+                                    };
+                                    Logging.instance.log(
+                                        json.encode(finalDebugMap),
+                                        level: LogLevel.Info,
+                                        printFullLength: true);
+                                    const ClipboardInterface clipboard =
+                                        ClipboardWrapper();
+                                    await clipboard.setData(
+                                      ClipboardData(
+                                          text: json.encode(finalDebugMap)),
+                                    );
                                   } catch (e, s) {
-                                    logssaved = false;
                                     Logging.instance
                                         .log("$e $s", level: LogLevel.Error);
                                   }
+                                },
+                              ),
+                              const Spacer(),
+                              BlueTextButton(
+                                text: "Save logs to file",
+                                onTap: () async {
+                                  final systemfile = SWBFileSystem();
+                                  await systemfile.prepareStorage();
+                                  Directory rootPath = await StackFileSystem
+                                      .applicationRootDirectory();
 
-                                  shouldPop = true;
+                                  if (Platform.isAndroid) {
+                                    rootPath =
+                                        Directory("/storage/emulated/0/");
+                                  }
 
-                                  if (mounted) {
-                                    Navigator.pop(context);
+                                  Directory dir =
+                                      Directory('${rootPath.path}/Documents');
+                                  if (Platform.isIOS) {
+                                    dir = Directory(rootPath.path);
+                                  }
+                                  try {
+                                    if (!dir.existsSync()) {
+                                      dir.createSync();
+                                    }
+                                  } catch (e, s) {
+                                    Logging.instance
+                                        .log("$e\n$s", level: LogLevel.Error);
+                                  }
+                                  String? path;
+                                  if (Platform.isAndroid) {
+                                    path = dir.path;
+                                  } else {
+                                    path = await FilePicker.platform
+                                        .getDirectoryPath(
+                                      dialogTitle: "Choose Log Save Location",
+                                      initialDirectory:
+                                          systemfile.startPath!.path,
+                                      lockParentWindow: true,
+                                    );
+                                  }
 
-                                    if (Platform.isAndroid) {
-                                      unawaited(
-                                        showDialog(
-                                          context: context,
-                                          builder: (context) => StackOkDialog(
-                                            title: logssaved
-                                                ? "Logs saved to"
-                                                : "Error Saving Logs",
-                                            message: "${path!}/$filename",
+                                  if (path != null) {
+                                    final eventBus = EventBus();
+                                    bool shouldPop = false;
+                                    unawaited(showDialog<dynamic>(
+                                      barrierDismissible: false,
+                                      context: context,
+                                      builder: (_) => WillPopScope(
+                                        onWillPop: () async {
+                                          return shouldPop;
+                                        },
+                                        child: CustomLoadingOverlay(
+                                          message: "Generating Stack logs file",
+                                          eventBus: eventBus,
+                                        ),
+                                      ),
+                                    ));
+
+                                    bool logssaved = true;
+                                    var filename;
+                                    try {
+                                      filename = await ref
+                                          .read(debugServiceProvider)
+                                          .exportToFile(path, eventBus);
+                                    } catch (e, s) {
+                                      logssaved = false;
+                                      Logging.instance
+                                          .log("$e $s", level: LogLevel.Error);
+                                    }
+
+                                    shouldPop = true;
+
+                                    if (mounted) {
+                                      Navigator.pop(context);
+
+                                      if (Platform.isAndroid) {
+                                        unawaited(
+                                          showDialog(
+                                            context: context,
+                                            builder: (context) => StackOkDialog(
+                                              title: logssaved
+                                                  ? "Logs saved to"
+                                                  : "Error Saving Logs",
+                                              message: "${path!}/$filename",
+                                            ),
                                           ),
-                                        ),
-                                      );
-                                    } else {
-                                      unawaited(
-                                        showFloatingFlushBar(
-                                          type: FlushBarType.info,
-                                          context: context,
-                                          message: logssaved
-                                              ? 'Logs file saved'
-                                              : "Error Saving Logs",
-                                        ),
-                                      );
+                                        );
+                                      } else {
+                                        unawaited(
+                                          showFloatingFlushBar(
+                                            type: FlushBarType.info,
+                                            context: context,
+                                            message: logssaved
+                                                ? 'Logs file saved'
+                                                : "Error Saving Logs",
+                                          ),
+                                        );
+                                      }
                                     }
                                   }
-                                }
-                              },
-                            ),
-                          ],
-                        )
-                      ],
+                                },
+                              ),
+                            ],
+                          )
+                        ],
+                      ),
                     ),
                   ),
                 ),
-              ),
-            ];
-          },
-          body: Builder(
-            builder: (context) {
-              final logs = filtered(
-                      ref.watch(debugServiceProvider
-                          .select((value) => value.recentLogs)),
-                      _searchTerm)
-                  .reversed
-                  .toList(growable: false);
+              ];
+            },
+            body: Builder(
+              builder: (context) {
+                final logs = filtered(
+                        ref.watch(debugServiceProvider
+                            .select((value) => value.recentLogs)),
+                        _searchTerm)
+                    .reversed
+                    .toList(growable: false);
 
-              return CustomScrollView(
-                reverse: true,
-                // shrinkWrap: true,
-                controller: scrollController,
-                slivers: [
-                  SliverOverlapInjector(
-                    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
-                      context,
+                return CustomScrollView(
+                  reverse: true,
+                  // shrinkWrap: true,
+                  controller: scrollController,
+                  slivers: [
+                    SliverOverlapInjector(
+                      handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+                        context,
+                      ),
                     ),
-                  ),
-                  SliverList(
-                    delegate: SliverChildBuilderDelegate(
-                      (context, index) {
-                        final log = logs[index];
+                    SliverList(
+                      delegate: SliverChildBuilderDelegate(
+                        (context, index) {
+                          final log = logs[index];
 
-                        return Container(
-                          key: Key("log_${log.id}_${log.timestampInMillisUTC}"),
-                          decoration: BoxDecoration(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .popupBG,
-                            borderRadius: _borderRadius(index, logs.length),
-                          ),
-                          child: Padding(
-                            padding: const EdgeInsets.all(4),
-                            child: RoundedContainer(
-                              padding: const EdgeInsets.all(0),
+                          return Container(
+                            key: Key(
+                                "log_${log.id}_${log.timestampInMillisUTC}"),
+                            decoration: BoxDecoration(
                               color: Theme.of(context)
                                   .extension<StackColors>()!
                                   .popupBG,
-                              child: Column(
-                                crossAxisAlignment: CrossAxisAlignment.start,
-                                children: [
-                                  Row(
-                                    children: [
-                                      Text(
-                                        " [${log.logLevel.name}]",
-                                        style: STextStyles.baseXS(context)
-                                            .copyWith(
-                                          fontSize: 8,
-                                          color: (log.logLevel == LogLevel.Info
-                                              ? Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .topNavIconGreen
-                                              : (log.logLevel ==
-                                                      LogLevel.Warning
-                                                  ? Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .topNavIconYellow
-                                                  : (log.logLevel ==
-                                                          LogLevel.Error
-                                                      ? Colors.orange
-                                                      : Theme.of(context)
-                                                          .extension<
-                                                              StackColors>()!
-                                                          .topNavIconRed))),
+                              borderRadius: _borderRadius(index, logs.length),
+                            ),
+                            child: Padding(
+                              padding: const EdgeInsets.all(4),
+                              child: RoundedContainer(
+                                padding: const EdgeInsets.all(0),
+                                color: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .popupBG,
+                                child: Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Row(
+                                      children: [
+                                        Text(
+                                          " [${log.logLevel.name}]",
+                                          style: STextStyles.baseXS(context)
+                                              .copyWith(
+                                            fontSize: 8,
+                                            color: (log.logLevel ==
+                                                    LogLevel.Info
+                                                ? Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .topNavIconGreen
+                                                : (log.logLevel ==
+                                                        LogLevel.Warning
+                                                    ? Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .topNavIconYellow
+                                                    : (log.logLevel ==
+                                                            LogLevel.Error
+                                                        ? Colors.orange
+                                                        : Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .topNavIconRed))),
+                                          ),
                                         ),
-                                      ),
-                                      Text(
-                                        "[${DateTime.fromMillisecondsSinceEpoch(log.timestampInMillisUTC, isUtc: true)}]: ",
-                                        style: STextStyles.baseXS(context)
-                                            .copyWith(
-                                          fontSize: 8,
-                                          color: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .textDark3,
+                                        Text(
+                                          "[${DateTime.fromMillisecondsSinceEpoch(log.timestampInMillisUTC, isUtc: true)}]: ",
+                                          style: STextStyles.baseXS(context)
+                                              .copyWith(
+                                            fontSize: 8,
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .textDark3,
+                                          ),
                                         ),
-                                      ),
-                                    ],
-                                  ),
-                                  Row(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.start,
-                                    children: [
-                                      const SizedBox(
-                                        width: 20,
-                                      ),
-                                      Flexible(
-                                        child: Column(
-                                          crossAxisAlignment:
-                                              CrossAxisAlignment.start,
-                                          children: [
-                                            SelectableText(
-                                              log.message,
-                                              style: STextStyles.baseXS(context)
-                                                  .copyWith(fontSize: 8),
-                                            ),
-                                          ],
+                                      ],
+                                    ),
+                                    Row(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        const SizedBox(
+                                          width: 20,
                                         ),
-                                      ),
-                                    ],
-                                  ),
-                                ],
+                                        Flexible(
+                                          child: Column(
+                                            crossAxisAlignment:
+                                                CrossAxisAlignment.start,
+                                            children: [
+                                              SelectableText(
+                                                log.message,
+                                                style:
+                                                    STextStyles.baseXS(context)
+                                                        .copyWith(fontSize: 8),
+                                              ),
+                                            ],
+                                          ),
+                                        ),
+                                      ],
+                                    ),
+                                  ],
+                                ),
                               ),
                             ),
-                          ),
-                        );
-                      },
-                      childCount: logs.length,
+                          );
+                        },
+                        childCount: logs.length,
+                      ),
                     ),
-                  ),
-                ],
-              );
-            },
+                  ],
+                );
+              },
+            ),
           ),
         ),
       ),
diff --git a/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart b/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart
index d1e893802..693f39f02 100644
--- a/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart
+++ b/lib/pages/settings_views/global_settings_view/appearance_settings_view.dart
@@ -10,6 +10,7 @@ import 'package:stackwallet/utilities/theme/dark_colors.dart';
 import 'package:stackwallet/utilities/theme/light_colors.dart';
 import 'package:stackwallet/utilities/theme/ocean_breeze_colors.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -32,127 +33,131 @@ class AppearanceSettingsView extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Appearance",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Appearance",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      RoundedWhiteContainer(
-                        child: Consumer(
-                          builder: (_, ref, __) {
-                            return RawMaterialButton(
-                              splashColor: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .highlight,
-                              materialTapTargetSize:
-                                  MaterialTapTargetSize.shrinkWrap,
-                              shape: RoundedRectangleBorder(
-                                borderRadius: BorderRadius.circular(
-                                  Constants.size.circularBorderRadius,
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        RoundedWhiteContainer(
+                          child: Consumer(
+                            builder: (_, ref, __) {
+                              return RawMaterialButton(
+                                splashColor: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .highlight,
+                                materialTapTargetSize:
+                                    MaterialTapTargetSize.shrinkWrap,
+                                shape: RoundedRectangleBorder(
+                                  borderRadius: BorderRadius.circular(
+                                    Constants.size.circularBorderRadius,
+                                  ),
                                 ),
-                              ),
-                              onPressed: null,
-                              child: Padding(
-                                padding:
-                                    const EdgeInsets.symmetric(vertical: 8),
-                                child: Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
-                                  children: [
-                                    Text(
-                                      "Display favorite wallets",
-                                      style: STextStyles.titleBold12(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    SizedBox(
-                                      height: 20,
-                                      width: 40,
-                                      child: DraggableSwitchButton(
-                                        isOn: ref.watch(
-                                          prefsChangeNotifierProvider.select(
-                                              (value) =>
-                                                  value.showFavoriteWallets),
-                                        ),
-                                        onValueChanged: (newValue) {
-                                          ref
-                                              .read(prefsChangeNotifierProvider)
-                                              .showFavoriteWallets = newValue;
-                                        },
+                                onPressed: null,
+                                child: Padding(
+                                  padding:
+                                      const EdgeInsets.symmetric(vertical: 8),
+                                  child: Row(
+                                    mainAxisAlignment:
+                                        MainAxisAlignment.spaceBetween,
+                                    children: [
+                                      Text(
+                                        "Display favorite wallets",
+                                        style: STextStyles.titleBold12(context),
+                                        textAlign: TextAlign.left,
                                       ),
-                                    )
-                                  ],
+                                      SizedBox(
+                                        height: 20,
+                                        width: 40,
+                                        child: DraggableSwitchButton(
+                                          isOn: ref.watch(
+                                            prefsChangeNotifierProvider.select(
+                                                (value) =>
+                                                    value.showFavoriteWallets),
+                                          ),
+                                          onValueChanged: (newValue) {
+                                            ref
+                                                .read(
+                                                    prefsChangeNotifierProvider)
+                                                .showFavoriteWallets = newValue;
+                                          },
+                                        ),
+                                      )
+                                    ],
+                                  ),
                                 ),
-                              ),
-                            );
-                          },
+                              );
+                            },
+                          ),
                         ),
-                      ),
-                      const SizedBox(
-                        height: 10,
-                      ),
-                      RoundedWhiteContainer(
-                        padding: const EdgeInsets.all(0),
-                        child: RawMaterialButton(
-                          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                        const SizedBox(
+                          height: 10,
+                        ),
+                        RoundedWhiteContainer(
                           padding: const EdgeInsets.all(0),
-                          materialTapTargetSize:
-                              MaterialTapTargetSize.shrinkWrap,
-                          shape: RoundedRectangleBorder(
-                            borderRadius: BorderRadius.circular(
-                              Constants.size.circularBorderRadius,
+                          child: RawMaterialButton(
+                            // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                            padding: const EdgeInsets.all(0),
+                            materialTapTargetSize:
+                                MaterialTapTargetSize.shrinkWrap,
+                            shape: RoundedRectangleBorder(
+                              borderRadius: BorderRadius.circular(
+                                Constants.size.circularBorderRadius,
+                              ),
                             ),
-                          ),
-                          onPressed: null,
-                          child: Padding(
-                            padding: const EdgeInsets.all(12),
-                            child: Row(
-                              children: [
-                                Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Choose Theme",
-                                      style: STextStyles.titleBold12(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    const Padding(
-                                      padding: EdgeInsets.all(10),
-                                      child: ThemeOptionsView(),
-                                    ),
-                                  ],
-                                ),
-                              ],
+                            onPressed: null,
+                            child: Padding(
+                              padding: const EdgeInsets.all(12),
+                              child: Row(
+                                children: [
+                                  Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.start,
+                                    children: [
+                                      Text(
+                                        "Choose Theme",
+                                        style: STextStyles.titleBold12(context),
+                                        textAlign: TextAlign.left,
+                                      ),
+                                      const Padding(
+                                        padding: EdgeInsets.all(10),
+                                        child: ThemeOptionsView(),
+                                      ),
+                                    ],
+                                  ),
+                                ],
+                              ),
                             ),
                           ),
                         ),
-                      ),
-                    ],
+                      ],
+                    ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/currency_view.dart b/lib/pages/settings_views/global_settings_view/currency_view.dart
index dccf2d61b..5bcf7fb7f 100644
--- a/lib/pages/settings_views/global_settings_view/currency_view.dart
+++ b/lib/pages/settings_views/global_settings_view/currency_view.dart
@@ -8,6 +8,7 @@ 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/primary_button.dart';
@@ -130,34 +131,37 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            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();
-                }
-              },
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              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(
+                "Currency",
+                style: STextStyles.navBarTitle(context),
+              ),
             ),
-            title: Text(
-              "Currency",
-              style: STextStyles.navBarTitle(context),
+            body: Padding(
+              padding: const EdgeInsets.only(
+                top: 12,
+                left: 16,
+                right: 16,
+              ),
+              child: child,
             ),
           ),
-          body: Padding(
-            padding: const EdgeInsets.only(
-              top: 12,
-              left: 16,
-              right: 16,
-            ),
-            child: child,
-          ),
         );
       },
       child: ConditionalParent(
diff --git a/lib/pages/settings_views/global_settings_view/global_settings_view.dart b/lib/pages/settings_views/global_settings_view/global_settings_view.dart
index fe6529c20..49e7ea36c 100644
--- a/lib/pages/settings_views/global_settings_view/global_settings_view.dart
+++ b/lib/pages/settings_views/global_settings_view/global_settings_view.dart
@@ -20,11 +20,10 @@ import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
-import 'package:stackwallet/utilities/delete_everything.dart';
-
 class GlobalSettingsView extends StatelessWidget {
   const GlobalSettingsView({
     Key? key,
@@ -35,254 +34,257 @@ class GlobalSettingsView extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Settings",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Settings",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (builderContext, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        RoundedWhiteContainer(
-                          padding: const EdgeInsets.all(4),
-                          child: Column(
-                            children: [
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.addressBook,
-                                iconSize: 16,
-                                title: "Address book",
-                                onPressed: () {
-                                  Navigator.of(context)
-                                      .pushNamed(AddressBookView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.downloadFolder,
-                                iconSize: 14,
-                                title: "Stack backup & restore",
-                                onPressed: () {
-                                  Navigator.push(
-                                    context,
-                                    RouteGenerator.getRoute(
-                                      shouldUseMaterialRoute:
-                                          RouteGenerator.useMaterialPageRoute,
-                                      builder: (_) => const LockscreenView(
-                                        showBackButton: true,
-                                        routeOnSuccess:
-                                            StackBackupView.routeName,
-                                        biometricsCancelButtonString: "CANCEL",
-                                        biometricsLocalizedReason:
-                                            "Authenticate to access Stack backup & restore settings",
-                                        biometricsAuthenticationTitle:
-                                            "Stack backup",
-                                      ),
-                                      settings: const RouteSettings(
-                                          name: "/swblockscreen"),
-                                    ),
-                                  );
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.lock,
-                                iconSize: 16,
-                                title: "Security",
-                                onPressed: () {
-                                  Navigator.of(context)
-                                      .pushNamed(SecurityView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.dollarSign,
-                                iconSize: 18,
-                                title: "Currency",
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                      BaseCurrencySettingsView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.language,
-                                iconSize: 18,
-                                title: "Language",
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                      LanguageSettingsView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.node,
-                                iconSize: 16,
-                                title: "Manage nodes",
-                                onPressed: () {
-                                  Navigator.of(context)
-                                      .pushNamed(ManageNodesView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.arrowRotate3,
-                                iconSize: 18,
-                                title: "Syncing preferences",
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                      SyncingPreferencesView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.arrowUpRight,
-                                iconSize: 16,
-                                title: "Startup",
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                      StartupPreferencesView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.sun,
-                                iconSize: 18,
-                                title: "Appearance",
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                      AppearanceSettingsView.routeName);
-                                },
-                              ),
-                              if (Platform.isIOS)
+        body: LayoutBuilder(
+          builder: (builderContext, constraints) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          RoundedWhiteContainer(
+                            padding: const EdgeInsets.all(4),
+                            child: Column(
+                              children: [
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.addressBook,
+                                  iconSize: 16,
+                                  title: "Address book",
+                                  onPressed: () {
+                                    Navigator.of(context)
+                                        .pushNamed(AddressBookView.routeName);
+                                  },
+                                ),
                                 const SizedBox(
                                   height: 8,
                                 ),
-                              if (Platform.isIOS)
                                 SettingsListButton(
-                                  iconAssetName: Assets.svg.circleAlert,
-                                  iconSize: 16,
-                                  title: "Delete account",
-                                  onPressed: () async {
-                                    await Navigator.of(context)
-                                        .pushNamed(DeleteAccountView.routeName);
+                                  iconAssetName: Assets.svg.downloadFolder,
+                                  iconSize: 14,
+                                  title: "Stack backup & restore",
+                                  onPressed: () {
+                                    Navigator.push(
+                                      context,
+                                      RouteGenerator.getRoute(
+                                        shouldUseMaterialRoute:
+                                            RouteGenerator.useMaterialPageRoute,
+                                        builder: (_) => const LockscreenView(
+                                          showBackButton: true,
+                                          routeOnSuccess:
+                                              StackBackupView.routeName,
+                                          biometricsCancelButtonString:
+                                              "CANCEL",
+                                          biometricsLocalizedReason:
+                                              "Authenticate to access Stack backup & restore settings",
+                                          biometricsAuthenticationTitle:
+                                              "Stack backup",
+                                        ),
+                                        settings: const RouteSettings(
+                                            name: "/swblockscreen"),
+                                      ),
+                                    );
                                   },
                                 ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.ellipsis,
-                                iconSize: 18,
-                                title: "About",
-                                onPressed: () {
-                                  Navigator.of(context)
-                                      .pushNamed(AboutView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.solidSliders,
-                                iconSize: 16,
-                                title: "Advanced",
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                      AdvancedSettingsView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.questionMessage,
-                                iconSize: 16,
-                                title: "Support",
-                                onPressed: () {
-                                  Navigator.of(context)
-                                      .pushNamed(SupportView.routeName);
-                                },
-                              ),
-                              // TextButton(
-                              //   style: Theme.of(context)
-                              //       .textButtonTheme
-                              //       .style
-                              //       ?.copyWith(
-                              //         backgroundColor:
-                              //             MaterialStateProperty.all<Color>(
-                              //           Theme.of(context).extension<StackColors>()!.accentColorDark
-                              //         ),
-                              //       ),
-                              //   child: Text(
-                              //     "fire test notification",
-                              //     style: STextStyles.button(context),
-                              //   ),
-                              //   onPressed: () async {
-                              //     NotificationApi.showNotification2(
-                              //       title: "Test notification",
-                              //       body: "My doggy wallet",
-                              //       walletId:
-                              //           "3c5e2d70-fcc3-11ec-86a3-31a106a81c3b",
-                              //       iconAssetName:
-                              //           Assets.svg.iconFor(coin: Coin.dogecoin),
-                              //       date: DateTime.now(),
-                              //     );
-                              //   },
-                              // ),
-                            ],
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.lock,
+                                  iconSize: 16,
+                                  title: "Security",
+                                  onPressed: () {
+                                    Navigator.of(context)
+                                        .pushNamed(SecurityView.routeName);
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.dollarSign,
+                                  iconSize: 18,
+                                  title: "Currency",
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                        BaseCurrencySettingsView.routeName);
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.language,
+                                  iconSize: 18,
+                                  title: "Language",
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                        LanguageSettingsView.routeName);
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.node,
+                                  iconSize: 16,
+                                  title: "Manage nodes",
+                                  onPressed: () {
+                                    Navigator.of(context)
+                                        .pushNamed(ManageNodesView.routeName);
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.arrowRotate3,
+                                  iconSize: 18,
+                                  title: "Syncing preferences",
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                        SyncingPreferencesView.routeName);
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.arrowUpRight,
+                                  iconSize: 16,
+                                  title: "Startup",
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                        StartupPreferencesView.routeName);
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.sun,
+                                  iconSize: 18,
+                                  title: "Appearance",
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                        AppearanceSettingsView.routeName);
+                                  },
+                                ),
+                                if (Platform.isIOS)
+                                  const SizedBox(
+                                    height: 8,
+                                  ),
+                                if (Platform.isIOS)
+                                  SettingsListButton(
+                                    iconAssetName: Assets.svg.circleAlert,
+                                    iconSize: 16,
+                                    title: "Delete account",
+                                    onPressed: () async {
+                                      await Navigator.of(context).pushNamed(
+                                          DeleteAccountView.routeName);
+                                    },
+                                  ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.ellipsis,
+                                  iconSize: 18,
+                                  title: "About",
+                                  onPressed: () {
+                                    Navigator.of(context)
+                                        .pushNamed(AboutView.routeName);
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.solidSliders,
+                                  iconSize: 16,
+                                  title: "Advanced",
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                        AdvancedSettingsView.routeName);
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.questionMessage,
+                                  iconSize: 16,
+                                  title: "Support",
+                                  onPressed: () {
+                                    Navigator.of(context)
+                                        .pushNamed(SupportView.routeName);
+                                  },
+                                ),
+                                // TextButton(
+                                //   style: Theme.of(context)
+                                //       .textButtonTheme
+                                //       .style
+                                //       ?.copyWith(
+                                //         backgroundColor:
+                                //             MaterialStateProperty.all<Color>(
+                                //           Theme.of(context).extension<StackColors>()!.accentColorDark
+                                //         ),
+                                //       ),
+                                //   child: Text(
+                                //     "fire test notification",
+                                //     style: STextStyles.button(context),
+                                //   ),
+                                //   onPressed: () async {
+                                //     NotificationApi.showNotification2(
+                                //       title: "Test notification",
+                                //       body: "My doggy wallet",
+                                //       walletId:
+                                //           "3c5e2d70-fcc3-11ec-86a3-31a106a81c3b",
+                                //       iconAssetName:
+                                //           Assets.svg.iconFor(coin: Coin.dogecoin),
+                                //       date: DateTime.now(),
+                                //     );
+                                //   },
+                                // ),
+                              ],
+                            ),
                           ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                      ],
+                          const SizedBox(
+                            height: 12,
+                          ),
+                        ],
+                      ),
                     ),
                   ),
                 ),
               ),
-            ),
-          );
-        },
+            );
+          },
+        ),
       ),
     );
   }
diff --git a/lib/pages/settings_views/global_settings_view/hidden_settings.dart b/lib/pages/settings_views/global_settings_view/hidden_settings.dart
index 6b6377ab6..7f35fcc86 100644
--- a/lib/pages/settings_views/global_settings_view/hidden_settings.dart
+++ b/lib/pages/settings_views/global_settings_view/hidden_settings.dart
@@ -5,9 +5,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/providers/global/debug_service_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.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/rounded_white_container.dart';
 
 class HiddenSettings extends StatelessWidget {
@@ -17,149 +17,151 @@ class HiddenSettings extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: Container(),
-        title: Text(
-          "Not so secret anymore",
-          style: STextStyles.navBarTitle(context),
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: Container(),
+          title: Text(
+            "Not so secret anymore",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      Consumer(builder: (_, ref, __) {
-                        return GestureDetector(
-                          onTap: () async {
-                            final notifs =
-                                ref.read(notificationsProvider).notifications;
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        Consumer(builder: (_, ref, __) {
+                          return GestureDetector(
+                            onTap: () async {
+                              final notifs =
+                                  ref.read(notificationsProvider).notifications;
 
-                            for (final n in notifs) {
+                              for (final n in notifs) {
+                                await ref
+                                    .read(notificationsProvider)
+                                    .delete(n, false);
+                              }
                               await ref
                                   .read(notificationsProvider)
-                                  .delete(n, false);
-                            }
-                            await ref
-                                .read(notificationsProvider)
-                                .delete(notifs[0], true);
+                                  .delete(notifs[0], true);
 
-                            unawaited(showFloatingFlushBar(
-                              type: FlushBarType.success,
-                              message: "Notification history deleted",
-                              context: context,
-                            ));
-                          },
-                          child: RoundedWhiteContainer(
-                            child: Text(
-                              "Delete notifications",
-                              style: STextStyles.button(context).copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .accentColorDark),
+                              unawaited(showFloatingFlushBar(
+                                type: FlushBarType.success,
+                                message: "Notification history deleted",
+                                context: context,
+                              ));
+                            },
+                            child: RoundedWhiteContainer(
+                              child: Text(
+                                "Delete notifications",
+                                style: STextStyles.button(context).copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark),
+                              ),
                             ),
-                          ),
-                        );
-                      }),
-                      // const SizedBox(
-                      //   height: 12,
-                      // ),
-                      // Consumer(builder: (_, ref, __) {
-                      //   return GestureDetector(
-                      //     onTap: () async {
-                      //       final trades =
-                      //           ref.read(tradesServiceProvider).trades;
-                      //
-                      //       for (final trade in trades) {
-                      //         ref.read(tradesServiceProvider).delete(
-                      //             trade: trade, shouldNotifyListeners: false);
-                      //       }
-                      //       ref.read(tradesServiceProvider).delete(
-                      //           trade: trades[0], shouldNotifyListeners: true);
-                      //
-                      //       // ref.read(notificationsProvider).DELETE_EVERYTHING();
-                      //     },
-                      //     child: RoundedWhiteContainer(
-                      //       child: Text(
-                      //         "Delete trade history",
-                      //         style: STextStyles.button(context).copyWith(
-                      //           color: Theme.of(context).extension<StackColors>()!.accentColorDark
-                      //         ),
-                      //       ),
-                      //     ),
-                      //   );
-                      // }),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      Consumer(builder: (_, ref, __) {
-                        return GestureDetector(
-                          onTap: () async {
-                            await ref
-                                .read(debugServiceProvider)
-                                .deleteAllMessages();
+                          );
+                        }),
+                        // const SizedBox(
+                        //   height: 12,
+                        // ),
+                        // Consumer(builder: (_, ref, __) {
+                        //   return GestureDetector(
+                        //     onTap: () async {
+                        //       final trades =
+                        //           ref.read(tradesServiceProvider).trades;
+                        //
+                        //       for (final trade in trades) {
+                        //         ref.read(tradesServiceProvider).delete(
+                        //             trade: trade, shouldNotifyListeners: false);
+                        //       }
+                        //       ref.read(tradesServiceProvider).delete(
+                        //           trade: trades[0], shouldNotifyListeners: true);
+                        //
+                        //       // ref.read(notificationsProvider).DELETE_EVERYTHING();
+                        //     },
+                        //     child: RoundedWhiteContainer(
+                        //       child: Text(
+                        //         "Delete trade history",
+                        //         style: STextStyles.button(context).copyWith(
+                        //           color: Theme.of(context).extension<StackColors>()!.accentColorDark
+                        //         ),
+                        //       ),
+                        //     ),
+                        //   );
+                        // }),
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        Consumer(builder: (_, ref, __) {
+                          return GestureDetector(
+                            onTap: () async {
+                              await ref
+                                  .read(debugServiceProvider)
+                                  .deleteAllMessages();
 
-                            unawaited(showFloatingFlushBar(
-                              type: FlushBarType.success,
-                              message: "Debug Logs deleted",
-                              context: context,
-                            ));
-                          },
-                          child: RoundedWhiteContainer(
-                            child: Text(
-                              "Delete Debug Logs",
-                              style: STextStyles.button(context).copyWith(
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .accentColorDark),
+                              unawaited(showFloatingFlushBar(
+                                type: FlushBarType.success,
+                                message: "Debug Logs deleted",
+                                context: context,
+                              ));
+                            },
+                            child: RoundedWhiteContainer(
+                              child: Text(
+                                "Delete Debug Logs",
+                                style: STextStyles.button(context).copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark),
+                              ),
                             ),
-                          ),
-                        );
-                      }),
-                      // const SizedBox(
-                      //   height: 12,
-                      // ),
-                      // GestureDetector(
-                      //   onTap: () async {
-                      //     showDialog<void>(
-                      //       context: context,
-                      //       builder: (_) {
-                      //         return StackDialogBase(
-                      //           child: SizedBox(
-                      //             width: 200,
-                      //             child: Lottie.asset(
-                      //               Assets.lottie.test2,
-                      //             ),
-                      //           ),
-                      //         );
-                      //       },
-                      //     );
-                      //   },
-                      //   child: RoundedWhiteContainer(
-                      //     child: Text(
-                      //       "Lottie test",
-                      //       style: STextStyles.button(context).copyWith(
-                      //         color: Theme.of(context).extension<StackColors>()!.accentColorDark
-                      //       ),
-                      //     ),
-                      //   ),
-                      // ),
-                    ],
+                          );
+                        }),
+                        // const SizedBox(
+                        //   height: 12,
+                        // ),
+                        // GestureDetector(
+                        //   onTap: () async {
+                        //     showDialog<void>(
+                        //       context: context,
+                        //       builder: (_) {
+                        //         return StackDialogBase(
+                        //           child: SizedBox(
+                        //             width: 200,
+                        //             child: Lottie.asset(
+                        //               Assets.lottie.test2,
+                        //             ),
+                        //           ),
+                        //         );
+                        //       },
+                        //     );
+                        //   },
+                        //   child: RoundedWhiteContainer(
+                        //     child: Text(
+                        //       "Lottie test",
+                        //       style: STextStyles.button(context).copyWith(
+                        //         color: Theme.of(context).extension<StackColors>()!.accentColorDark
+                        //       ),
+                        //     ),
+                        //   ),
+                        // ),
+                      ],
+                    ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/language_view.dart b/lib/pages/settings_views/global_settings_view/language_view.dart
index b617546e4..9ba2d6dd2 100644
--- a/lib/pages/settings_views/global_settings_view/language_view.dart
+++ b/lib/pages/settings_views/global_settings_view/language_view.dart
@@ -7,14 +7,14 @@ import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/languages_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/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class LanguageSettingsView extends ConsumerStatefulWidget {
   const LanguageSettingsView({Key? key}) : super(key: key);
 
@@ -100,203 +100,205 @@ class _LanguageViewState extends ConsumerState<LanguageSettingsView> {
       listWithoutSelected.insert(0, current);
     }
     listWithoutSelected = _filtered();
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        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();
-            }
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          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(
+            "Language",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Language",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.only(
-          top: 12,
-          left: 16,
-          right: 16,
-        ),
-        child: NestedScrollView(
-          floatHeaderSlivers: true,
-          headerSliverBuilder: (context, innerBoxIsScrolled) {
-            return [
-              SliverOverlapAbsorber(
-                handle:
-                    NestedScrollView.sliverOverlapAbsorberHandleFor(context),
-                sliver: SliverToBoxAdapter(
-                  child: Padding(
-                    padding: const EdgeInsets.only(bottom: 16),
-                    child: ClipRRect(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
-                      ),
-                      child: TextField(
-                        autocorrect: Util.isDesktop ? false : true,
-                        enableSuggestions: Util.isDesktop ? false : true,
-                        controller: _searchController,
-                        focusNode: _searchFocusNode,
-                        onChanged: (newString) {
-                          setState(() => filter = newString);
-                        },
-                        style: STextStyles.field(context),
-                        decoration: standardInputDecoration(
-                          "Search",
-                          _searchFocusNode,
-                          context,
-                        ).copyWith(
-                          prefixIcon: Padding(
-                            padding: const EdgeInsets.symmetric(
-                              horizontal: 10,
-                              vertical: 16,
+        body: Padding(
+          padding: const EdgeInsets.only(
+            top: 12,
+            left: 16,
+            right: 16,
+          ),
+          child: NestedScrollView(
+            floatHeaderSlivers: true,
+            headerSliverBuilder: (context, innerBoxIsScrolled) {
+              return [
+                SliverOverlapAbsorber(
+                  handle:
+                      NestedScrollView.sliverOverlapAbsorberHandleFor(context),
+                  sliver: SliverToBoxAdapter(
+                    child: Padding(
+                      padding: const EdgeInsets.only(bottom: 16),
+                      child: ClipRRect(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                        child: TextField(
+                          autocorrect: Util.isDesktop ? false : true,
+                          enableSuggestions: Util.isDesktop ? false : true,
+                          controller: _searchController,
+                          focusNode: _searchFocusNode,
+                          onChanged: (newString) {
+                            setState(() => filter = newString);
+                          },
+                          style: STextStyles.field(context),
+                          decoration: standardInputDecoration(
+                            "Search",
+                            _searchFocusNode,
+                            context,
+                          ).copyWith(
+                            prefixIcon: Padding(
+                              padding: const EdgeInsets.symmetric(
+                                horizontal: 10,
+                                vertical: 16,
+                              ),
+                              child: SvgPicture.asset(
+                                Assets.svg.search,
+                                width: 16,
+                                height: 16,
+                              ),
                             ),
-                            child: SvgPicture.asset(
-                              Assets.svg.search,
-                              width: 16,
-                              height: 16,
-                            ),
-                          ),
-                          suffixIcon: _searchController.text.isNotEmpty
-                              ? Padding(
-                                  padding: const EdgeInsets.only(right: 0),
-                                  child: UnconstrainedBox(
-                                    child: Row(
-                                      children: [
-                                        TextFieldIconButton(
-                                          child: const XIcon(),
-                                          onTap: () async {
-                                            setState(() {
-                                              _searchController.text = "";
-                                              filter = "";
-                                            });
-                                          },
-                                        ),
-                                      ],
+                            suffixIcon: _searchController.text.isNotEmpty
+                                ? Padding(
+                                    padding: const EdgeInsets.only(right: 0),
+                                    child: UnconstrainedBox(
+                                      child: Row(
+                                        children: [
+                                          TextFieldIconButton(
+                                            child: const XIcon(),
+                                            onTap: () async {
+                                              setState(() {
+                                                _searchController.text = "";
+                                                filter = "";
+                                              });
+                                            },
+                                          ),
+                                        ],
+                                      ),
                                     ),
-                                  ),
-                                )
-                              : null,
+                                  )
+                                : null,
+                          ),
                         ),
                       ),
                     ),
                   ),
                 ),
-              ),
-            ];
-          },
-          body: Builder(
-            builder: (context) {
-              return CustomScrollView(
-                slivers: [
-                  SliverOverlapInjector(
-                    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
-                      context,
+              ];
+            },
+            body: Builder(
+              builder: (context) {
+                return CustomScrollView(
+                  slivers: [
+                    SliverOverlapInjector(
+                      handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+                        context,
+                      ),
                     ),
-                  ),
-                  SliverList(
-                    delegate: SliverChildBuilderDelegate(
-                      (context, index) {
-                        return Container(
-                          decoration: BoxDecoration(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .popupBG,
-                            borderRadius: _borderRadius(index),
-                          ),
-                          child: Padding(
-                            padding: const EdgeInsets.all(4),
-                            key: Key(
-                                "languageSelect_${listWithoutSelected[index]}"),
-                            child: RoundedContainer(
-                              padding: const EdgeInsets.all(0),
-                              color: index == 0
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .currencyListItemBG
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .popupBG,
-                              child: RawMaterialButton(
-                                onPressed: () async {
-                                  onTap(index);
-                                },
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
+                    SliverList(
+                      delegate: SliverChildBuilderDelegate(
+                        (context, index) {
+                          return Container(
+                            decoration: BoxDecoration(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .popupBG,
+                              borderRadius: _borderRadius(index),
+                            ),
+                            child: Padding(
+                              padding: const EdgeInsets.all(4),
+                              key: Key(
+                                  "languageSelect_${listWithoutSelected[index]}"),
+                              child: RoundedContainer(
+                                padding: const EdgeInsets.all(0),
+                                color: index == 0
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .currencyListItemBG
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .popupBG,
+                                child: RawMaterialButton(
+                                  onPressed: () async {
+                                    onTap(index);
+                                  },
+                                  shape: RoundedRectangleBorder(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
                                   ),
-                                ),
-                                child: Padding(
-                                  padding: const EdgeInsets.all(12.0),
-                                  child: Row(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.start,
-                                    children: [
-                                      SizedBox(
-                                        width: 20,
-                                        height: 20,
-                                        child: Radio(
-                                          activeColor: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .radioButtonIconEnabled,
-                                          value: true,
-                                          groupValue: index == 0,
-                                          onChanged: (_) {
-                                            onTap(index);
-                                          },
+                                  child: Padding(
+                                    padding: const EdgeInsets.all(12.0),
+                                    child: Row(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        SizedBox(
+                                          width: 20,
+                                          height: 20,
+                                          child: Radio(
+                                            activeColor: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .radioButtonIconEnabled,
+                                            value: true,
+                                            groupValue: index == 0,
+                                            onChanged: (_) {
+                                              onTap(index);
+                                            },
+                                          ),
                                         ),
-                                      ),
-                                      const SizedBox(
-                                        width: 12,
-                                      ),
-                                      Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
-                                        children: [
-                                          Text(
-                                            listWithoutSelected[index],
-                                            key: (index == 0)
-                                                ? const Key(
-                                                    "selectedLanguageSettingsLanguageText")
-                                                : null,
-                                            style: STextStyles.largeMedium14(
-                                                context),
-                                          ),
-                                          const SizedBox(
-                                            height: 2,
-                                          ),
-                                          Text(
-                                            listWithoutSelected[index],
-                                            key: (index == 0)
-                                                ? const Key(
-                                                    "selectedLanguageSettingsLanguageTextDescription")
-                                                : null,
-                                            style: STextStyles.itemSubtitle(
-                                                context),
-                                          ),
-                                        ],
-                                      ),
-                                    ],
+                                        const SizedBox(
+                                          width: 12,
+                                        ),
+                                        Column(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            Text(
+                                              listWithoutSelected[index],
+                                              key: (index == 0)
+                                                  ? const Key(
+                                                      "selectedLanguageSettingsLanguageText")
+                                                  : null,
+                                              style: STextStyles.largeMedium14(
+                                                  context),
+                                            ),
+                                            const SizedBox(
+                                              height: 2,
+                                            ),
+                                            Text(
+                                              listWithoutSelected[index],
+                                              key: (index == 0)
+                                                  ? const Key(
+                                                      "selectedLanguageSettingsLanguageTextDescription")
+                                                  : null,
+                                              style: STextStyles.itemSubtitle(
+                                                  context),
+                                            ),
+                                          ],
+                                        ),
+                                      ],
+                                    ),
                                   ),
                                 ),
                               ),
                             ),
-                          ),
-                        );
-                      },
-                      childCount: listWithoutSelected.length,
+                          );
+                        },
+                        childCount: listWithoutSelected.length,
+                      ),
                     ),
-                  ),
-                ],
-              );
-            },
+                  ],
+                );
+              },
+            ),
           ),
         ),
       ),
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 9062314f0..bd6e5c6d8 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -12,7 +12,6 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/test_epic_box_connection.dart';
@@ -20,6 +19,7 @@ import 'package:stackwallet/utilities/test_monero_node_connection.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.dart';
@@ -238,7 +238,8 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
                                 Expanded(
                                   child: SecondaryButton(
                                     label: "Cancel",
-                                    buttonHeight: ButtonHeight.l,
+                                    buttonHeight:
+                                        isDesktop ? ButtonHeight.l : null,
                                     onPressed: () => Navigator.of(
                                       context,
                                       rootNavigator: true,
@@ -251,7 +252,8 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
                                 Expanded(
                                   child: PrimaryButton(
                                     label: "Save",
-                                    buttonHeight: ButtonHeight.l,
+                                    buttonHeight:
+                                        isDesktop ? ButtonHeight.l : null,
                                     onPressed: () => Navigator.of(
                                       context,
                                       rootNavigator: true,
@@ -409,84 +411,90 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
 
     return ConditionalParent(
       condition: !isDesktop,
-      builder: (child) => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          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(
-            viewType == AddEditNodeViewType.edit ? "Edit node" : "Add node",
-            style: STextStyles.navBarTitle(context),
-          ),
-          actions: [
-            if (viewType == AddEditNodeViewType.edit)
-              Padding(
-                padding: const EdgeInsets.only(
-                  top: 10,
-                  bottom: 10,
-                  right: 10,
-                ),
-                child: AspectRatio(
-                  aspectRatio: 1,
-                  child: AppBarIconButton(
-                    key: const Key("deleteNodeAppBarButtonKey"),
-                    size: 36,
-                    shadows: const [],
-                    color:
-                        Theme.of(context).extension<StackColors>()!.background,
-                    icon: SvgPicture.asset(
-                      Assets.svg.trash,
+      builder: (child) => Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            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(
+              viewType == AddEditNodeViewType.edit ? "Edit node" : "Add node",
+              style: STextStyles.navBarTitle(context),
+            ),
+            actions: [
+              if (viewType == AddEditNodeViewType.edit)
+                Padding(
+                  padding: const EdgeInsets.only(
+                    top: 10,
+                    bottom: 10,
+                    right: 10,
+                  ),
+                  child: AspectRatio(
+                    aspectRatio: 1,
+                    child: AppBarIconButton(
+                      key: const Key("deleteNodeAppBarButtonKey"),
+                      size: 36,
+                      shadows: const [],
                       color: Theme.of(context)
                           .extension<StackColors>()!
-                          .accentColorDark,
-                      width: 20,
-                      height: 20,
-                    ),
-                    onPressed: () async {
-                      Navigator.popUntil(context,
-                          ModalRoute.withName(widget.routeOnSuccessOrDelete));
+                          .background,
+                      icon: SvgPicture.asset(
+                        Assets.svg.trash,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark,
+                        width: 20,
+                        height: 20,
+                      ),
+                      onPressed: () async {
+                        Navigator.popUntil(context,
+                            ModalRoute.withName(widget.routeOnSuccessOrDelete));
 
-                      await ref.read(nodeServiceChangeNotifierProvider).delete(
-                            nodeId!,
-                            true,
-                          );
-                    },
-                  ),
-                ),
-              ),
-          ],
-        ),
-        body: Padding(
-          padding: const EdgeInsets.only(
-            top: 12,
-            left: 12,
-            right: 12,
-            bottom: 12,
-          ),
-          child: LayoutBuilder(
-            builder: (context, constraints) {
-              return SingleChildScrollView(
-                child: Padding(
-                  padding: const EdgeInsets.all(4),
-                  child: ConstrainedBox(
-                    constraints:
-                        BoxConstraints(minHeight: constraints.maxHeight - 8),
-                    child: IntrinsicHeight(
-                      child: child,
+                        await ref
+                            .read(nodeServiceChangeNotifierProvider)
+                            .delete(
+                              nodeId!,
+                              true,
+                            );
+                      },
                     ),
                   ),
                 ),
-              );
-            },
+            ],
+          ),
+          body: Padding(
+            padding: const EdgeInsets.only(
+              top: 12,
+              left: 12,
+              right: 12,
+              bottom: 12,
+            ),
+            child: LayoutBuilder(
+              builder: (context, constraints) {
+                return SingleChildScrollView(
+                  child: Padding(
+                    padding: const EdgeInsets.all(4),
+                    child: ConstrainedBox(
+                      constraints:
+                          BoxConstraints(minHeight: constraints.maxHeight - 8),
+                      child: IntrinsicHeight(
+                        child: child,
+                      ),
+                    ),
+                  ),
+                );
+              },
+            ),
           ),
         ),
       ),
@@ -562,7 +570,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
                   child: SecondaryButton(
                     label: "Test connection",
                     enabled: testConnectionEnabled,
-                    buttonHeight: ButtonHeight.l,
+                    buttonHeight: isDesktop ? ButtonHeight.l : null,
                     onPressed: testConnectionEnabled
                         ? () async {
                             await _testConnection();
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 a93b64be3..91e6871f3 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
@@ -8,6 +8,7 @@ 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/background.dart';
 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/desktop/desktop_dialog.dart';
@@ -122,66 +123,70 @@ class _CoinNodesViewState extends ConsumerState<CoinNodesView> {
         ),
       );
     } else {
-      return Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          leading: AppBarBackButton(
-            onPressed: () {
-              Navigator.of(context).pop();
-            },
-          ),
-          title: Text(
-            "${widget.coin.prettyName} nodes",
-            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("manageNodesAddNewNodeButtonKey"),
-                  size: 36,
-                  shadows: const [],
-                  color: Theme.of(context).extension<StackColors>()!.background,
-                  icon: SvgPicture.asset(
-                    Assets.svg.plus,
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .accentColorDark,
-                    width: 20,
-                    height: 20,
+      return Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
+            ),
+            title: Text(
+              "${widget.coin.prettyName} nodes",
+              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("manageNodesAddNewNodeButtonKey"),
+                    size: 36,
+                    shadows: const [],
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    icon: SvgPicture.asset(
+                      Assets.svg.plus,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                      width: 20,
+                      height: 20,
+                    ),
+                    onPressed: () {
+                      Navigator.of(context).pushNamed(
+                        AddEditNodeView.routeName,
+                        arguments: Tuple4(
+                          AddEditNodeViewType.add,
+                          widget.coin,
+                          null,
+                          CoinNodesView.routeName,
+                        ),
+                      );
+                    },
                   ),
-                  onPressed: () {
-                    Navigator.of(context).pushNamed(
-                      AddEditNodeView.routeName,
-                      arguments: Tuple4(
-                        AddEditNodeViewType.add,
-                        widget.coin,
-                        null,
-                        CoinNodesView.routeName,
-                      ),
-                    );
-                  },
                 ),
               ),
-            ),
-          ],
-        ),
-        body: Padding(
-          padding: const EdgeInsets.only(
-            top: 12,
-            left: 12,
-            right: 12,
+            ],
           ),
-          child: SingleChildScrollView(
-            child: NodesList(
-              coin: widget.coin,
-              popBackToRoute: CoinNodesView.routeName,
+          body: Padding(
+            padding: const EdgeInsets.only(
+              top: 12,
+              left: 12,
+              right: 12,
+            ),
+            child: SingleChildScrollView(
+              child: NodesList(
+                coin: widget.coin,
+                popBackToRoute: CoinNodesView.routeName,
+              ),
             ),
           ),
         ),
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart
index 22f239232..743fc6957 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart
@@ -8,6 +8,7 @@ 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';
+import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
@@ -47,88 +48,91 @@ class _ManageNodesViewState extends ConsumerState<ManageNodesView> {
         ? _coins
         : _coins.sublist(0, _coins.length - kTestNetCoinCount);
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Manage nodes",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Manage nodes",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.only(
-          top: 12,
-          left: 12,
-          right: 12,
-        ),
-        child: SingleChildScrollView(
-          child: Column(
-            crossAxisAlignment: CrossAxisAlignment.stretch,
-            children: [
-              ...coins.map(
-                (coin) {
-                  final count = ref
-                      .watch(nodeServiceChangeNotifierProvider
-                          .select((value) => value.getNodesFor(coin)))
-                      .length;
+        body: Padding(
+          padding: const EdgeInsets.only(
+            top: 12,
+            left: 12,
+            right: 12,
+          ),
+          child: SingleChildScrollView(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.stretch,
+              children: [
+                ...coins.map(
+                  (coin) {
+                    final count = ref
+                        .watch(nodeServiceChangeNotifierProvider
+                            .select((value) => value.getNodesFor(coin)))
+                        .length;
 
-                  return Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: RoundedWhiteContainer(
-                      padding: const EdgeInsets.all(0),
-                      child: RawMaterialButton(
-                        // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                        shape: RoundedRectangleBorder(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
+                    return Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: RoundedWhiteContainer(
+                        padding: const EdgeInsets.all(0),
+                        child: RawMaterialButton(
+                          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                          shape: RoundedRectangleBorder(
+                            borderRadius: BorderRadius.circular(
+                              Constants.size.circularBorderRadius,
+                            ),
                           ),
-                        ),
-                        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                        onPressed: () {
-                          Navigator.of(context).pushNamed(
-                            CoinNodesView.routeName,
-                            arguments: coin,
-                          );
-                        },
-                        child: Padding(
-                          padding: const EdgeInsets.all(12),
-                          child: Row(
-                            children: [
-                              SvgPicture.asset(
-                                Assets.svg.iconFor(coin: coin),
-                                width: 24,
-                                height: 24,
-                              ),
-                              const SizedBox(
-                                width: 12,
-                              ),
-                              Column(
-                                crossAxisAlignment: CrossAxisAlignment.start,
-                                children: [
-                                  Text(
-                                    "${coin.prettyName} nodes",
-                                    style: STextStyles.titleBold12(context),
-                                  ),
-                                  Text(
-                                    count > 1 ? "$count nodes" : "Default",
-                                    style: STextStyles.label(context),
-                                  ),
-                                ],
-                              )
-                            ],
+                          materialTapTargetSize:
+                              MaterialTapTargetSize.shrinkWrap,
+                          onPressed: () {
+                            Navigator.of(context).pushNamed(
+                              CoinNodesView.routeName,
+                              arguments: coin,
+                            );
+                          },
+                          child: Padding(
+                            padding: const EdgeInsets.all(12),
+                            child: Row(
+                              children: [
+                                SvgPicture.asset(
+                                  Assets.svg.iconFor(coin: coin),
+                                  width: 24,
+                                  height: 24,
+                                ),
+                                const SizedBox(
+                                  width: 12,
+                                ),
+                                Column(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Text(
+                                      "${coin.prettyName} nodes",
+                                      style: STextStyles.titleBold12(context),
+                                    ),
+                                    Text(
+                                      count > 1 ? "$count nodes" : "Default",
+                                      style: STextStyles.label(context),
+                                    ),
+                                  ],
+                                )
+                              ],
+                            ),
                           ),
                         ),
                       ),
-                    ),
-                  );
-                },
-              ),
-            ],
+                    );
+                  },
+                ),
+              ],
+            ),
           ),
         ),
       ),
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index 71d764135..2e43b5595 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -18,6 +18,7 @@ import 'package:stackwallet/utilities/test_monero_node_connection.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/delete_button.dart';
@@ -179,85 +180,89 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
 
     return ConditionalParent(
       condition: !isDesktop,
-      builder: (child) => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          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(
-            "Node details",
-            style: STextStyles.navBarTitle(context),
-          ),
-          actions: [
-            if (!nodeId.startsWith("default"))
-              Padding(
-                padding: const EdgeInsets.only(
-                  top: 10,
-                  bottom: 10,
-                  right: 10,
-                ),
-                child: AspectRatio(
-                  aspectRatio: 1,
-                  child: AppBarIconButton(
-                    key: const Key("nodeDetailsEditNodeAppBarButtonKey"),
-                    size: 36,
-                    shadows: const [],
-                    color:
-                        Theme.of(context).extension<StackColors>()!.background,
-                    icon: SvgPicture.asset(
-                      Assets.svg.pencil,
+      builder: (child) => Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            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(
+              "Node details",
+              style: STextStyles.navBarTitle(context),
+            ),
+            actions: [
+              if (!nodeId.startsWith("default"))
+                Padding(
+                  padding: const EdgeInsets.only(
+                    top: 10,
+                    bottom: 10,
+                    right: 10,
+                  ),
+                  child: AspectRatio(
+                    aspectRatio: 1,
+                    child: AppBarIconButton(
+                      key: const Key("nodeDetailsEditNodeAppBarButtonKey"),
+                      size: 36,
+                      shadows: const [],
                       color: Theme.of(context)
                           .extension<StackColors>()!
-                          .accentColorDark,
-                      width: 20,
-                      height: 20,
+                          .background,
+                      icon: SvgPicture.asset(
+                        Assets.svg.pencil,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark,
+                        width: 20,
+                        height: 20,
+                      ),
+                      onPressed: () {
+                        Navigator.of(context).pushNamed(
+                          AddEditNodeView.routeName,
+                          arguments: Tuple4(
+                            AddEditNodeViewType.edit,
+                            coin,
+                            nodeId,
+                            popRouteName,
+                          ),
+                        );
+                      },
                     ),
-                    onPressed: () {
-                      Navigator.of(context).pushNamed(
-                        AddEditNodeView.routeName,
-                        arguments: Tuple4(
-                          AddEditNodeViewType.edit,
-                          coin,
-                          nodeId,
-                          popRouteName,
-                        ),
-                      );
-                    },
                   ),
                 ),
-              ),
-          ],
-        ),
-        body: Padding(
-          padding: const EdgeInsets.only(
-            top: 12,
-            left: 12,
-            right: 12,
+            ],
           ),
-          child: LayoutBuilder(
-            builder: (context, constraints) {
-              return SingleChildScrollView(
-                child: Padding(
-                  padding: const EdgeInsets.all(4),
-                  child: ConstrainedBox(
-                    constraints:
-                        BoxConstraints(minHeight: constraints.maxHeight - 8),
-                    child: IntrinsicHeight(
-                      child: child,
+          body: Padding(
+            padding: const EdgeInsets.only(
+              top: 12,
+              left: 12,
+              right: 12,
+            ),
+            child: LayoutBuilder(
+              builder: (context, constraints) {
+                return SingleChildScrollView(
+                  child: Padding(
+                    padding: const EdgeInsets.all(4),
+                    child: ConstrainedBox(
+                      constraints:
+                          BoxConstraints(minHeight: constraints.maxHeight - 8),
+                      child: IntrinsicHeight(
+                        child: child,
+                      ),
                     ),
                   ),
-                ),
-              );
-            },
+                );
+              },
+            ),
           ),
         ),
       ),
diff --git a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart
index c88da0521..fb5722594 100644
--- a/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart
+++ b/lib/pages/settings_views/global_settings_view/security_views/change_pin_view/change_pin_view.dart
@@ -9,6 +9,7 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_pin_put/custom_pin_put.dart';
 
@@ -65,182 +66,186 @@ class _ChangePinViewState extends ConsumerState<ChangePinView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            if (FocusScope.of(context).hasFocus) {
-              FocusScope.of(context).unfocus();
-              await Future<void>.delayed(const Duration(milliseconds: 70));
-            }
-            if (mounted) {
-              Navigator.of(context).pop();
-            }
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              if (FocusScope.of(context).hasFocus) {
+                FocusScope.of(context).unfocus();
+                await Future<void>.delayed(const Duration(milliseconds: 70));
+              }
+              if (mounted) {
+                Navigator.of(context).pop();
+              }
+            },
+          ),
         ),
-      ),
-      body: SafeArea(
-        child: PageView(
-          controller: _pageController,
-          physics: const NeverScrollableScrollPhysics(),
-          children: [
-            // page 1
-            Column(
-              mainAxisAlignment: MainAxisAlignment.center,
-              children: [
-                Center(
-                  child: Text(
-                    "Create new PIN",
-                    style: STextStyles.pageTitleH1(context),
+        body: SafeArea(
+          child: PageView(
+            controller: _pageController,
+            physics: const NeverScrollableScrollPhysics(),
+            children: [
+              // page 1
+              Column(
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: [
+                  Center(
+                    child: Text(
+                      "Create new PIN",
+                      style: STextStyles.pageTitleH1(context),
+                    ),
                   ),
-                ),
-                const SizedBox(
-                  height: 52,
-                ),
-                CustomPinPut(
-                  fieldsCount: Constants.pinLength,
-                  eachFieldHeight: 12,
-                  eachFieldWidth: 12,
-                  textStyle: STextStyles.label(context).copyWith(
-                    fontSize: 1,
+                  const SizedBox(
+                    height: 52,
                   ),
-                  focusNode: _pinPutFocusNode1,
-                  controller: _pinPutController1,
-                  useNativeKeyboard: false,
-                  obscureText: "",
-                  inputDecoration: InputDecoration(
-                    border: InputBorder.none,
-                    enabledBorder: InputBorder.none,
-                    focusedBorder: InputBorder.none,
-                    disabledBorder: InputBorder.none,
-                    errorBorder: InputBorder.none,
-                    focusedErrorBorder: InputBorder.none,
-                    fillColor:
-                        Theme.of(context).extension<StackColors>()!.background,
-                    counterText: "",
-                  ),
-                  submittedFieldDecoration: _pinPutDecoration.copyWith(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .infoItemIcons,
-                    border: Border.all(
-                      width: 1,
+                  CustomPinPut(
+                    fieldsCount: Constants.pinLength,
+                    eachFieldHeight: 12,
+                    eachFieldWidth: 12,
+                    textStyle: STextStyles.label(context).copyWith(
+                      fontSize: 1,
+                    ),
+                    focusNode: _pinPutFocusNode1,
+                    controller: _pinPutController1,
+                    useNativeKeyboard: false,
+                    obscureText: "",
+                    inputDecoration: InputDecoration(
+                      border: InputBorder.none,
+                      enabledBorder: InputBorder.none,
+                      focusedBorder: InputBorder.none,
+                      disabledBorder: InputBorder.none,
+                      errorBorder: InputBorder.none,
+                      focusedErrorBorder: InputBorder.none,
+                      fillColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .background,
+                      counterText: "",
+                    ),
+                    submittedFieldDecoration: _pinPutDecoration.copyWith(
                       color: Theme.of(context)
                           .extension<StackColors>()!
                           .infoItemIcons,
+                      border: Border.all(
+                        width: 1,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .infoItemIcons,
+                      ),
                     ),
-                  ),
-                  selectedFieldDecoration: _pinPutDecoration,
-                  followingFieldDecoration: _pinPutDecoration,
-                  onSubmit: (String pin) {
-                    if (pin.length == Constants.pinLength) {
-                      _pageController.nextPage(
-                        duration: const Duration(milliseconds: 300),
-                        curve: Curves.linear,
-                      );
-                    }
-                  },
-                ),
-              ],
-            ),
-
-            // page 2
-
-            Column(
-              mainAxisAlignment: MainAxisAlignment.center,
-              children: [
-                Center(
-                  child: Text(
-                    "Confirm new PIN",
-                    style: STextStyles.pageTitleH1(context),
-                  ),
-                ),
-                const SizedBox(
-                  height: 52,
-                ),
-                CustomPinPut(
-                  fieldsCount: Constants.pinLength,
-                  eachFieldHeight: 12,
-                  eachFieldWidth: 12,
-                  textStyle: STextStyles.infoSmall(context).copyWith(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .textSubtitle3,
-                    fontSize: 1,
-                  ),
-                  focusNode: _pinPutFocusNode2,
-                  controller: _pinPutController2,
-                  useNativeKeyboard: false,
-                  obscureText: "",
-                  inputDecoration: InputDecoration(
-                    border: InputBorder.none,
-                    enabledBorder: InputBorder.none,
-                    focusedBorder: InputBorder.none,
-                    disabledBorder: InputBorder.none,
-                    errorBorder: InputBorder.none,
-                    focusedErrorBorder: InputBorder.none,
-                    fillColor:
-                        Theme.of(context).extension<StackColors>()!.background,
-                    counterText: "",
-                  ),
-                  submittedFieldDecoration: _pinPutDecoration.copyWith(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .infoItemIcons,
-                    border: Border.all(
-                      width: 1,
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .infoItemIcons,
-                    ),
-                  ),
-                  selectedFieldDecoration: _pinPutDecoration,
-                  followingFieldDecoration: _pinPutDecoration,
-                  onSubmit: (String pin) async {
-                    if (_pinPutController1.text == _pinPutController2.text) {
-                      // This should never fail as we are overwriting the existing pin
-                      assert(
-                          (await _secureStore.read(key: "stack_pin")) != null);
-                      await _secureStore.write(key: "stack_pin", value: pin);
-
-                      showFloatingFlushBar(
-                        type: FlushBarType.success,
-                        message: "New PIN is set up",
-                        context: context,
-                        iconAsset: Assets.svg.check,
-                      );
-
-                      await Future<void>.delayed(
-                          const Duration(milliseconds: 1200));
-
-                      if (mounted) {
-                        Navigator.of(context).popUntil(
-                          ModalRoute.withName(SecurityView.routeName),
+                    selectedFieldDecoration: _pinPutDecoration,
+                    followingFieldDecoration: _pinPutDecoration,
+                    onSubmit: (String pin) {
+                      if (pin.length == Constants.pinLength) {
+                        _pageController.nextPage(
+                          duration: const Duration(milliseconds: 300),
+                          curve: Curves.linear,
                         );
                       }
-                    } else {
-                      _pageController.animateTo(
-                        0,
-                        duration: const Duration(milliseconds: 300),
-                        curve: Curves.linear,
-                      );
+                    },
+                  ),
+                ],
+              ),
 
-                      showFloatingFlushBar(
-                        type: FlushBarType.warning,
-                        message: "PIN codes do not match. Try again.",
-                        context: context,
-                        iconAsset: Assets.svg.alertCircle,
-                      );
+              // page 2
 
-                      _pinPutController1.text = '';
-                      _pinPutController2.text = '';
-                    }
-                  },
-                ),
-              ],
-            ),
-          ],
+              Column(
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: [
+                  Center(
+                    child: Text(
+                      "Confirm new PIN",
+                      style: STextStyles.pageTitleH1(context),
+                    ),
+                  ),
+                  const SizedBox(
+                    height: 52,
+                  ),
+                  CustomPinPut(
+                    fieldsCount: Constants.pinLength,
+                    eachFieldHeight: 12,
+                    eachFieldWidth: 12,
+                    textStyle: STextStyles.infoSmall(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .textSubtitle3,
+                      fontSize: 1,
+                    ),
+                    focusNode: _pinPutFocusNode2,
+                    controller: _pinPutController2,
+                    useNativeKeyboard: false,
+                    obscureText: "",
+                    inputDecoration: InputDecoration(
+                      border: InputBorder.none,
+                      enabledBorder: InputBorder.none,
+                      focusedBorder: InputBorder.none,
+                      disabledBorder: InputBorder.none,
+                      errorBorder: InputBorder.none,
+                      focusedErrorBorder: InputBorder.none,
+                      fillColor: Theme.of(context)
+                          .extension<StackColors>()!
+                          .background,
+                      counterText: "",
+                    ),
+                    submittedFieldDecoration: _pinPutDecoration.copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .infoItemIcons,
+                      border: Border.all(
+                        width: 1,
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .infoItemIcons,
+                      ),
+                    ),
+                    selectedFieldDecoration: _pinPutDecoration,
+                    followingFieldDecoration: _pinPutDecoration,
+                    onSubmit: (String pin) async {
+                      if (_pinPutController1.text == _pinPutController2.text) {
+                        // This should never fail as we are overwriting the existing pin
+                        assert((await _secureStore.read(key: "stack_pin")) !=
+                            null);
+                        await _secureStore.write(key: "stack_pin", value: pin);
+
+                        showFloatingFlushBar(
+                          type: FlushBarType.success,
+                          message: "New PIN is set up",
+                          context: context,
+                          iconAsset: Assets.svg.check,
+                        );
+
+                        await Future<void>.delayed(
+                            const Duration(milliseconds: 1200));
+
+                        if (mounted) {
+                          Navigator.of(context).popUntil(
+                            ModalRoute.withName(SecurityView.routeName),
+                          );
+                        }
+                      } else {
+                        _pageController.animateTo(
+                          0,
+                          duration: const Duration(milliseconds: 300),
+                          curve: Curves.linear,
+                        );
+
+                        showFloatingFlushBar(
+                          type: FlushBarType.warning,
+                          message: "PIN codes do not match. Try again.",
+                          context: context,
+                          iconAsset: Assets.svg.alertCircle,
+                        );
+
+                        _pinPutController1.text = '';
+                        _pinPutController2.text = '';
+                      }
+                    },
+                  ),
+                ],
+              ),
+            ],
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/security_views/security_view.dart b/lib/pages/settings_views/global_settings_view/security_views/security_view.dart
index 24fce5cd8..c2a64bb50 100644
--- a/lib/pages/settings_views/global_settings_view/security_views/security_view.dart
+++ b/lib/pages/settings_views/global_settings_view/security_views/security_view.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/route_generator.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/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -22,128 +23,131 @@ class SecurityView extends StatelessWidget {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Security",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Security",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
-                ),
-                onPressed: () {
-                  Navigator.push(
-                    context,
-                    RouteGenerator.getRoute(
-                      shouldUseMaterialRoute:
-                          RouteGenerator.useMaterialPageRoute,
-                      builder: (_) => const LockscreenView(
-                        showBackButton: true,
-                        routeOnSuccess: ChangePinView.routeName,
-                        biometricsCancelButtonString: "CANCEL",
-                        biometricsLocalizedReason: "Authenticate to change PIN",
-                        biometricsAuthenticationTitle: "Change PIN",
-                      ),
-                      settings:
-                          const RouteSettings(name: "/changepinlockscreen"),
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              RoundedWhiteContainer(
+                padding: const EdgeInsets.all(0),
+                child: RawMaterialButton(
+                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                  shape: RoundedRectangleBorder(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
                     ),
-                  );
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
                   ),
-                  child: Row(
-                    children: [
-                      Text(
-                        "Change PIN",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
+                  onPressed: () {
+                    Navigator.push(
+                      context,
+                      RouteGenerator.getRoute(
+                        shouldUseMaterialRoute:
+                            RouteGenerator.useMaterialPageRoute,
+                        builder: (_) => const LockscreenView(
+                          showBackButton: true,
+                          routeOnSuccess: ChangePinView.routeName,
+                          biometricsCancelButtonString: "CANCEL",
+                          biometricsLocalizedReason:
+                              "Authenticate to change PIN",
+                          biometricsAuthenticationTitle: "Change PIN",
+                        ),
+                        settings:
+                            const RouteSettings(name: "/changepinlockscreen"),
                       ),
-                    ],
+                    );
+                  },
+                  child: Padding(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 12,
+                      vertical: 20,
+                    ),
+                    child: Row(
+                      children: [
+                        Text(
+                          "Change PIN",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
                   ),
                 ),
               ),
-            ),
-            const SizedBox(
-              height: 8,
-            ),
-            RoundedWhiteContainer(
-              child: Consumer(
-                builder: (_, ref, __) {
-                  return RawMaterialButton(
-                    // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                    shape: RoundedRectangleBorder(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
+              const SizedBox(
+                height: 8,
+              ),
+              RoundedWhiteContainer(
+                child: Consumer(
+                  builder: (_, ref, __) {
+                    return RawMaterialButton(
+                      // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                      shape: RoundedRectangleBorder(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
                       ),
-                    ),
-                    onPressed: null,
-                    //     () {
-                    //   final useBio =
-                    //       ref.read(prefsChangeNotifierProvider).useBiometrics;
-                    //
-                    //   debugPrint("useBio: $useBio");
-                    //   ref.read(prefsChangeNotifierProvider).useBiometrics =
-                    //       !useBio;
-                    //
-                    //   debugPrint(
-                    //       "useBio set to: ${ref.read(prefsChangeNotifierProvider).useBiometrics}");
-                    // },
-                    child: Padding(
-                      padding: const EdgeInsets.symmetric(vertical: 8),
-                      child: Row(
-                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                        children: [
-                          Text(
-                            "Enable biometric authentication",
-                            style: STextStyles.titleBold12(context),
-                            textAlign: TextAlign.left,
-                          ),
-                          SizedBox(
-                            height: 20,
-                            width: 40,
-                            child: DraggableSwitchButton(
-                              isOn: ref.watch(
-                                prefsChangeNotifierProvider
-                                    .select((value) => value.useBiometrics),
-                              ),
-                              onValueChanged: (newValue) {
-                                ref
-                                    .read(prefsChangeNotifierProvider)
-                                    .useBiometrics = newValue;
-                              },
+                      onPressed: null,
+                      //     () {
+                      //   final useBio =
+                      //       ref.read(prefsChangeNotifierProvider).useBiometrics;
+                      //
+                      //   debugPrint("useBio: $useBio");
+                      //   ref.read(prefsChangeNotifierProvider).useBiometrics =
+                      //       !useBio;
+                      //
+                      //   debugPrint(
+                      //       "useBio set to: ${ref.read(prefsChangeNotifierProvider).useBiometrics}");
+                      // },
+                      child: Padding(
+                        padding: const EdgeInsets.symmetric(vertical: 8),
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                          children: [
+                            Text(
+                              "Enable biometric authentication",
+                              style: STextStyles.titleBold12(context),
+                              textAlign: TextAlign.left,
                             ),
-                          ),
-                        ],
+                            SizedBox(
+                              height: 20,
+                              width: 40,
+                              child: DraggableSwitchButton(
+                                isOn: ref.watch(
+                                  prefsChangeNotifierProvider
+                                      .select((value) => value.useBiometrics),
+                                ),
+                                onValueChanged: (newValue) {
+                                  ref
+                                      .read(prefsChangeNotifierProvider)
+                                      .useBiometrics = newValue;
+                                },
+                              ),
+                            ),
+                          ],
+                        ),
                       ),
-                    ),
-                  );
-                },
+                    );
+                  },
+                ),
               ),
-            ),
-          ],
+            ],
+          ),
         ),
       ),
     );
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 a94375742..15b5a12fa 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
@@ -11,6 +11,8 @@ import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
@@ -19,8 +21,6 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:url_launcher/url_launcher.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class AutoBackupView extends ConsumerStatefulWidget {
   const AutoBackupView({Key? key}) : super(key: key);
 
@@ -225,239 +225,241 @@ class _AutoBackupViewState extends ConsumerState<AutoBackupView> {
       frequencyController.text = Format.prettyFrequencyType(next);
     });
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Auto Backup",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Auto Backup",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
-                  ),
-                ),
-                onPressed: null,
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "Auto Backup",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                      SizedBox(
-                        height: 20,
-                        width: 40,
-                        child: DraggableSwitchButton(
-                          key: const Key("autoBackupToggleButtonKey"),
-                          isOn: _toggle,
-                          controller: toggleController,
-                          onValueChanged: (newValue) async {
-                            _toggle = newValue;
-
-                            if (_toggle) {
-                              attemptEnable();
-                            } else {
-                              attemptDisable();
-                            }
-                          },
-                        ),
-                      ),
-                    ],
-                  ),
-                ),
-              ),
-            ),
-            const SizedBox(
-              height: 8,
-            ),
-            if (!isEnabledAutoBackup)
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
               RoundedWhiteContainer(
-                child: RichText(
-                  textAlign: TextAlign.left,
-                  text: TextSpan(
-                    style: STextStyles.label(context),
-                    children: [
-                      const TextSpan(
-                          text:
-                              "Auto Backup is a custom Stack Wallet feature that offers a convenient backup of your data.\n\nTo ensure maximum security, we recommend using a unique password that you haven't used anywhere else on the internet before. Your password is not stored.\n\nFor more information, please see our website "),
-                      TextSpan(
-                        text: "stackwallet.com.",
-                        style: STextStyles.richLink(context),
-                        recognizer: TapGestureRecognizer()
-                          ..onTap = () {
-                            launchUrl(
-                              Uri.parse("https://stackwallet.com"),
-                              mode: LaunchMode.externalApplication,
-                            );
-                          },
-                      ),
-                    ],
+                padding: const EdgeInsets.all(0),
+                child: RawMaterialButton(
+                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                  shape: RoundedRectangleBorder(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
                   ),
-                ),
-              ),
-            if (isEnabledAutoBackup)
-              Column(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  RoundedWhiteContainer(
+                  onPressed: null,
+                  child: Padding(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 12,
+                      vertical: 20,
+                    ),
                     child: Row(
                       mainAxisAlignment: MainAxisAlignment.spaceBetween,
                       children: [
-                        BlueTextButton(
-                          text: "Back up now",
-                          onTap: () {
-                            ref.read(autoSWBServiceProvider).doBackup();
-                          },
-                        ),
                         Text(
-                          "Backed up ${prettySinceLastBackupString(ref.watch(prefsChangeNotifierProvider.select((value) => value.lastAutoBackup)))}",
-                          style: STextStyles.itemSubtitle(context),
-                        )
+                          "Auto Backup",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                        SizedBox(
+                          height: 20,
+                          width: 40,
+                          child: DraggableSwitchButton(
+                            key: const Key("autoBackupToggleButtonKey"),
+                            isOn: _toggle,
+                            controller: toggleController,
+                            onValueChanged: (newValue) async {
+                              _toggle = newValue;
+
+                              if (_toggle) {
+                                attemptEnable();
+                              } else {
+                                attemptDisable();
+                              }
+                            },
+                          ),
+                        ),
                       ],
                     ),
                   ),
-                  const SizedBox(
-                    height: 32,
-                  ),
-                  Text(
-                    "Auto Backup file",
-                    style: STextStyles.smallMed12(context),
-                  ),
-                  const SizedBox(
-                    height: 10,
-                  ),
-                  ClipRRect(
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
-                    ),
-                    child: TextField(
-                      key: const Key("backupSavedToFileLocationTextFieldKey"),
-                      focusNode: fileLocationFocusNode,
-                      controller: fileLocationController,
-                      enabled: false,
-                      style: STextStyles.field(context).copyWith(
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textDark
-                            .withOpacity(0.5),
-                      ),
-                      readOnly: true,
-                      enableSuggestions: false,
-                      autocorrect: false,
-                      toolbarOptions: const ToolbarOptions(
-                        copy: true,
-                        cut: false,
-                        paste: false,
-                        selectAll: true,
-                      ),
-                      decoration: standardInputDecoration(
-                        "Saved to",
-                        fileLocationFocusNode,
-                        context,
-                      ),
-                    ),
-                  ),
-                  const SizedBox(
-                    height: 10,
-                  ),
-                  ClipRRect(
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
-                    ),
-                    child: TextField(
-                      key: const Key("backupPasswordFieldKey"),
-                      focusNode: passwordFocusNode,
-                      controller: passwordController,
-                      enabled: false,
-                      style: STextStyles.field(context).copyWith(
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textDark
-                            .withOpacity(0.5),
-                      ),
-                      obscureText: true,
-                      enableSuggestions: false,
-                      autocorrect: false,
-                      toolbarOptions: const ToolbarOptions(
-                        copy: true,
-                        cut: false,
-                        paste: false,
-                        selectAll: true,
-                      ),
-                      decoration: standardInputDecoration(
-                        "Passphrase",
-                        passwordFocusNode,
-                        context,
-                      ),
-                    ),
-                  ),
-                  const SizedBox(
-                    height: 12,
-                  ),
-                  Text(
-                    "Auto Backup frequency",
-                    style: STextStyles.smallMed12(context),
-                  ),
-                  const SizedBox(
-                    height: 10,
-                  ),
-                  TextField(
-                    autocorrect: Util.isDesktop ? false : true,
-                    enableSuggestions: Util.isDesktop ? false : true,
-                    key: const Key("backupFrequencyFieldKey"),
-                    controller: frequencyController,
-                    enabled: false,
-                    style: STextStyles.field(context).copyWith(
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .textDark
-                          .withOpacity(0.5),
-                    ),
-                    toolbarOptions: const ToolbarOptions(
-                      copy: true,
-                      cut: false,
-                      paste: false,
-                      selectAll: true,
-                    ),
-                  ),
-                  const SizedBox(
-                    height: 20,
-                  ),
-                  Center(
-                    child: BlueTextButton(
-                      text: "Edit Auto Backup",
-                      onTap: () async {
-                        Navigator.of(context)
-                            .pushNamed(EditAutoBackupView.routeName);
-                      },
-                    ),
-                  )
-                ],
+                ),
               ),
-          ],
+              const SizedBox(
+                height: 8,
+              ),
+              if (!isEnabledAutoBackup)
+                RoundedWhiteContainer(
+                  child: RichText(
+                    textAlign: TextAlign.left,
+                    text: TextSpan(
+                      style: STextStyles.label(context),
+                      children: [
+                        const TextSpan(
+                            text:
+                                "Auto Backup is a custom Stack Wallet feature that offers a convenient backup of your data.\n\nTo ensure maximum security, we recommend using a unique password that you haven't used anywhere else on the internet before. Your password is not stored.\n\nFor more information, please see our website "),
+                        TextSpan(
+                          text: "stackwallet.com.",
+                          style: STextStyles.richLink(context),
+                          recognizer: TapGestureRecognizer()
+                            ..onTap = () {
+                              launchUrl(
+                                Uri.parse("https://stackwallet.com"),
+                                mode: LaunchMode.externalApplication,
+                              );
+                            },
+                        ),
+                      ],
+                    ),
+                  ),
+                ),
+              if (isEnabledAutoBackup)
+                Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    RoundedWhiteContainer(
+                      child: Row(
+                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                        children: [
+                          BlueTextButton(
+                            text: "Back up now",
+                            onTap: () {
+                              ref.read(autoSWBServiceProvider).doBackup();
+                            },
+                          ),
+                          Text(
+                            "Backed up ${prettySinceLastBackupString(ref.watch(prefsChangeNotifierProvider.select((value) => value.lastAutoBackup)))}",
+                            style: STextStyles.itemSubtitle(context),
+                          )
+                        ],
+                      ),
+                    ),
+                    const SizedBox(
+                      height: 32,
+                    ),
+                    Text(
+                      "Auto Backup file",
+                      style: STextStyles.smallMed12(context),
+                    ),
+                    const SizedBox(
+                      height: 10,
+                    ),
+                    ClipRRect(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
+                      ),
+                      child: TextField(
+                        key: const Key("backupSavedToFileLocationTextFieldKey"),
+                        focusNode: fileLocationFocusNode,
+                        controller: fileLocationController,
+                        enabled: false,
+                        style: STextStyles.field(context).copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark
+                              .withOpacity(0.5),
+                        ),
+                        readOnly: true,
+                        enableSuggestions: false,
+                        autocorrect: false,
+                        toolbarOptions: const ToolbarOptions(
+                          copy: true,
+                          cut: false,
+                          paste: false,
+                          selectAll: true,
+                        ),
+                        decoration: standardInputDecoration(
+                          "Saved to",
+                          fileLocationFocusNode,
+                          context,
+                        ),
+                      ),
+                    ),
+                    const SizedBox(
+                      height: 10,
+                    ),
+                    ClipRRect(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
+                      ),
+                      child: TextField(
+                        key: const Key("backupPasswordFieldKey"),
+                        focusNode: passwordFocusNode,
+                        controller: passwordController,
+                        enabled: false,
+                        style: STextStyles.field(context).copyWith(
+                          color: Theme.of(context)
+                              .extension<StackColors>()!
+                              .textDark
+                              .withOpacity(0.5),
+                        ),
+                        obscureText: true,
+                        enableSuggestions: false,
+                        autocorrect: false,
+                        toolbarOptions: const ToolbarOptions(
+                          copy: true,
+                          cut: false,
+                          paste: false,
+                          selectAll: true,
+                        ),
+                        decoration: standardInputDecoration(
+                          "Passphrase",
+                          passwordFocusNode,
+                          context,
+                        ),
+                      ),
+                    ),
+                    const SizedBox(
+                      height: 12,
+                    ),
+                    Text(
+                      "Auto Backup frequency",
+                      style: STextStyles.smallMed12(context),
+                    ),
+                    const SizedBox(
+                      height: 10,
+                    ),
+                    TextField(
+                      autocorrect: Util.isDesktop ? false : true,
+                      enableSuggestions: Util.isDesktop ? false : true,
+                      key: const Key("backupFrequencyFieldKey"),
+                      controller: frequencyController,
+                      enabled: false,
+                      style: STextStyles.field(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .textDark
+                            .withOpacity(0.5),
+                      ),
+                      toolbarOptions: const ToolbarOptions(
+                        copy: true,
+                        cut: false,
+                        paste: false,
+                        selectAll: true,
+                      ),
+                    ),
+                    const SizedBox(
+                      height: 20,
+                    ),
+                    Center(
+                      child: BlueTextButton(
+                        text: "Edit Auto Backup",
+                        onTap: () async {
+                          Navigator.of(context)
+                              .pushNamed(EditAutoBackupView.routeName);
+                        },
+                      ),
+                    )
+                  ],
+                ),
+            ],
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
index bf8bd40e7..8e8731105 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_auto_backup_view.dart
@@ -22,6 +22,7 @@ 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/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/progress_bar.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -108,549 +109,559 @@ class _EnableAutoBackupViewState extends ConsumerState<CreateAutoBackupView> {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Create Auto Backup",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Create Auto Backup",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(builder: (context, constraints) {
-          return SingleChildScrollView(
-            child: ConstrainedBox(
-              constraints: BoxConstraints(
-                minHeight: constraints.maxHeight,
-              ),
-              child: IntrinsicHeight(
-                child: Column(
-                  crossAxisAlignment: CrossAxisAlignment.stretch,
-                  children: [
-                    Text(
-                      "Create your backup file",
-                      style: STextStyles.smallMed12(context),
-                    ),
-                    const SizedBox(
-                      height: 10,
-                    ),
-                    if (!Platform.isAndroid)
-                      TextField(
-                        autocorrect: Util.isDesktop ? false : true,
-                        enableSuggestions: Util.isDesktop ? false : true,
-                        onTap: Platform.isAndroid
-                            ? null
-                            : () async {
-                                try {
-                                  await stackFileSystem.prepareStorage();
-
-                                  if (mounted) {
-                                    await stackFileSystem.pickDir(context);
-                                  }
-
-                                  if (mounted) {
-                                    setState(() {
-                                      fileLocationController.text =
-                                          stackFileSystem.dirPath ?? "";
-                                    });
-                                  }
-                                } catch (e, s) {
-                                  Logging.instance
-                                      .log("$e\n$s", level: LogLevel.Error);
-                                }
-                              },
-                        controller: fileLocationController,
-                        style: STextStyles.field(context),
-                        decoration: InputDecoration(
-                          hintText: "Save to...",
-                          hintStyle: STextStyles.fieldLabel(context),
-                          suffixIcon: UnconstrainedBox(
-                            child: Row(
-                              children: [
-                                const SizedBox(
-                                  width: 16,
-                                ),
-                                SvgPicture.asset(
-                                  Assets.svg.folder,
-                                  color: Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .textDark3,
-                                  width: 16,
-                                  height: 16,
-                                ),
-                                const SizedBox(
-                                  width: 12,
-                                ),
-                              ],
-                            ),
-                          ),
-                        ),
-                        key: const Key(
-                            "createBackupSaveToFileLocationTextFieldKey"),
-                        readOnly: true,
-                        toolbarOptions: const ToolbarOptions(
-                          copy: true,
-                          cut: false,
-                          paste: false,
-                          selectAll: false,
-                        ),
-                        onChanged: (newValue) {},
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: LayoutBuilder(builder: (context, constraints) {
+            return SingleChildScrollView(
+              child: ConstrainedBox(
+                constraints: BoxConstraints(
+                  minHeight: constraints.maxHeight,
+                ),
+                child: IntrinsicHeight(
+                  child: Column(
+                    crossAxisAlignment: CrossAxisAlignment.stretch,
+                    children: [
+                      Text(
+                        "Create your backup file",
+                        style: STextStyles.smallMed12(context),
                       ),
-                    if (!Platform.isAndroid)
                       const SizedBox(
                         height: 10,
                       ),
-                    ClipRRect(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
-                      ),
-                      child: TextField(
-                        key: const Key("createBackupPasswordFieldKey1"),
-                        focusNode: passwordFocusNode,
-                        controller: passwordController,
-                        style: STextStyles.field(context),
-                        obscureText: hidePassword,
-                        enableSuggestions: false,
-                        autocorrect: false,
-                        decoration: standardInputDecoration(
-                          "Create passphrase",
-                          passwordFocusNode,
-                          context,
-                        ).copyWith(
-                          suffixIcon: UnconstrainedBox(
-                            child: Row(
-                              children: [
-                                const SizedBox(
-                                  width: 16,
-                                ),
-                                GestureDetector(
-                                  key: const Key(
-                                      "createBackupPasswordFieldShowPasswordButtonKey"),
-                                  onTap: () async {
-                                    setState(() {
-                                      hidePassword = !hidePassword;
-                                    });
-                                  },
-                                  child: SvgPicture.asset(
-                                    hidePassword
-                                        ? Assets.svg.eye
-                                        : Assets.svg.eyeSlash,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textDark3,
-                                    width: 16,
-                                    height: 16,
-                                  ),
-                                ),
-                                const SizedBox(
-                                  width: 12,
-                                ),
-                              ],
-                            ),
-                          ),
-                        ),
-                        onChanged: (newValue) {
-                          if (newValue.isEmpty) {
-                            setState(() {
-                              passwordFeedback = "";
-                            });
-                            return;
-                          }
-                          final result = zxcvbn.evaluate(newValue);
-                          String suggestionsAndTips = "";
-                          for (var sug
-                              in result.feedback.suggestions!.toSet()) {
-                            suggestionsAndTips += "$sug\n";
-                          }
-                          suggestionsAndTips += result.feedback.warning!;
-                          String feedback =
-                              // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
-                              suggestionsAndTips;
-
-                          passwordStrength = result.score! / 4;
-
-                          // hack fix to format back string returned from zxcvbn
-                          if (feedback.contains("phrasesNo need")) {
-                            feedback = feedback.replaceFirst(
-                                "phrasesNo need", "phrases\nNo need");
-                          }
-
-                          if (feedback.endsWith("\n")) {
-                            feedback =
-                                feedback.substring(0, feedback.length - 2);
-                          }
-
-                          setState(() {
-                            passwordFeedback = feedback;
-                          });
-                        },
-                      ),
-                    ),
-                    if (passwordFocusNode.hasFocus ||
-                        passwordRepeatFocusNode.hasFocus ||
-                        passwordController.text.isNotEmpty)
-                      Padding(
-                        padding: EdgeInsets.only(
-                          left: 12,
-                          right: 12,
-                          top: passwordFeedback.isNotEmpty ? 4 : 0,
-                        ),
-                        child: passwordFeedback.isNotEmpty
-                            ? Text(
-                                passwordFeedback,
-                                style: STextStyles.infoSmall(context),
-                              )
-                            : null,
-                      ),
-                    if (passwordFocusNode.hasFocus ||
-                        passwordRepeatFocusNode.hasFocus ||
-                        passwordController.text.isNotEmpty)
-                      Padding(
-                        padding: const EdgeInsets.only(
-                          left: 12,
-                          right: 12,
-                          top: 10,
-                        ),
-                        child: ProgressBar(
-                          key: const Key("createStackBackUpProgressBar"),
-                          width: MediaQuery.of(context).size.width - 32 - 24,
-                          height: 5,
-                          fillColor: passwordStrength < 0.51
-                              ? Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .accentColorRed
-                              : passwordStrength < 1
-                                  ? Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .accentColorYellow
-                                  : Theme.of(context)
-                                      .extension<StackColors>()!
-                                      .accentColorGreen,
-                          backgroundColor: Theme.of(context)
-                              .extension<StackColors>()!
-                              .buttonBackSecondary,
-                          percent:
-                              passwordStrength < 0.25 ? 0.03 : passwordStrength,
-                        ),
-                      ),
-                    const SizedBox(
-                      height: 10,
-                    ),
-                    ClipRRect(
-                      borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius,
-                      ),
-                      child: TextField(
-                        key: const Key("createBackupPasswordFieldKey2"),
-                        focusNode: passwordRepeatFocusNode,
-                        controller: passwordRepeatController,
-                        style: STextStyles.field(context),
-                        obscureText: hidePassword,
-                        enableSuggestions: false,
-                        autocorrect: false,
-                        decoration: standardInputDecoration(
-                          "Confirm passphrase",
-                          passwordRepeatFocusNode,
-                          context,
-                        ).copyWith(
-                          suffixIcon: UnconstrainedBox(
-                            child: Row(
-                              children: [
-                                const SizedBox(
-                                  width: 16,
-                                ),
-                                GestureDetector(
-                                  key: const Key(
-                                      "createBackupPasswordFieldShowPasswordButtonKey"),
-                                  onTap: () async {
-                                    setState(() {
-                                      hidePassword = !hidePassword;
-                                    });
-                                  },
-                                  child: SvgPicture.asset(
-                                    hidePassword
-                                        ? Assets.svg.eye
-                                        : Assets.svg.eyeSlash,
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .textDark3,
-                                    width: 16,
-                                    height: 16,
-                                  ),
-                                ),
-                                const SizedBox(
-                                  width: 12,
-                                ),
-                              ],
-                            ),
-                          ),
-                        ),
-                        onChanged: (newValue) {
-                          setState(() {});
-                          // TODO: ? check if passwords match?
-                        },
-                      ),
-                    ),
-                    const SizedBox(
-                      height: 32,
-                    ),
-                    Text(
-                      "Auto Backup frequency",
-                      style: STextStyles.smallMed12(context),
-                    ),
-                    const SizedBox(
-                      height: 10,
-                    ),
-                    Stack(
-                      children: [
+                      if (!Platform.isAndroid)
                         TextField(
                           autocorrect: Util.isDesktop ? false : true,
                           enableSuggestions: Util.isDesktop ? false : true,
-                          readOnly: true,
-                          textInputAction: TextInputAction.none,
-                        ),
-                        Positioned.fill(
-                          child: RawMaterialButton(
-                            splashColor: Theme.of(context)
-                                .extension<StackColors>()!
-                                .highlight,
-                            shape: RoundedRectangleBorder(
-                              borderRadius: BorderRadius.circular(
-                                Constants.size.circularBorderRadius,
-                              ),
-                            ),
-                            onPressed: () {
-                              showModalBottomSheet<dynamic>(
-                                backgroundColor: Colors.transparent,
-                                context: context,
-                                shape: const RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.vertical(
-                                    top: Radius.circular(20),
-                                  ),
-                                ),
-                                builder: (_) =>
-                                    const BackupFrequencyTypeSelectSheet(),
-                              );
-                            },
-                            child: Padding(
-                              padding:
-                                  const EdgeInsets.symmetric(horizontal: 12.0),
+                          onTap: Platform.isAndroid
+                              ? null
+                              : () async {
+                                  try {
+                                    await stackFileSystem.prepareStorage();
+
+                                    if (mounted) {
+                                      await stackFileSystem.pickDir(context);
+                                    }
+
+                                    if (mounted) {
+                                      setState(() {
+                                        fileLocationController.text =
+                                            stackFileSystem.dirPath ?? "";
+                                      });
+                                    }
+                                  } catch (e, s) {
+                                    Logging.instance
+                                        .log("$e\n$s", level: LogLevel.Error);
+                                  }
+                                },
+                          controller: fileLocationController,
+                          style: STextStyles.field(context),
+                          decoration: InputDecoration(
+                            hintText: "Save to...",
+                            hintStyle: STextStyles.fieldLabel(context),
+                            suffixIcon: UnconstrainedBox(
                               child: Row(
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
                                 children: [
-                                  Text(
-                                    Format.prettyFrequencyType(ref.watch(
-                                        prefsChangeNotifierProvider.select(
-                                            (value) =>
-                                                value.backupFrequencyType))),
-                                    style: STextStyles.itemSubtitle12(context),
+                                  const SizedBox(
+                                    width: 16,
                                   ),
-                                  Padding(
-                                    padding: const EdgeInsets.only(right: 4.0),
-                                    child: SvgPicture.asset(
-                                      Assets.svg.chevronDown,
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .textSubtitle2,
-                                      width: 12,
-                                      height: 6,
-                                    ),
+                                  SvgPicture.asset(
+                                    Assets.svg.folder,
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .textDark3,
+                                    width: 16,
+                                    height: 16,
+                                  ),
+                                  const SizedBox(
+                                    width: 12,
                                   ),
                                 ],
                               ),
                             ),
                           ),
-                        )
-                      ],
-                    ),
-                    const Spacer(),
-                    const SizedBox(
-                      height: 10,
-                    ),
-                    TextButton(
-                      style: shouldEnableCreate
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context)
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryDisabledButtonColor(context),
-                      onPressed: !shouldEnableCreate
-                          ? null
-                          : () async {
-                              final String pathToSave =
-                                  fileLocationController.text;
-                              final String passphrase = passwordController.text;
-                              final String repeatPassphrase =
-                                  passwordRepeatController.text;
+                          key: const Key(
+                              "createBackupSaveToFileLocationTextFieldKey"),
+                          readOnly: true,
+                          toolbarOptions: const ToolbarOptions(
+                            copy: true,
+                            cut: false,
+                            paste: false,
+                            selectAll: false,
+                          ),
+                          onChanged: (newValue) {},
+                        ),
+                      if (!Platform.isAndroid)
+                        const SizedBox(
+                          height: 10,
+                        ),
+                      ClipRRect(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                        child: TextField(
+                          key: const Key("createBackupPasswordFieldKey1"),
+                          focusNode: passwordFocusNode,
+                          controller: passwordController,
+                          style: STextStyles.field(context),
+                          obscureText: hidePassword,
+                          enableSuggestions: false,
+                          autocorrect: false,
+                          decoration: standardInputDecoration(
+                            "Create passphrase",
+                            passwordFocusNode,
+                            context,
+                          ).copyWith(
+                            suffixIcon: UnconstrainedBox(
+                              child: Row(
+                                children: [
+                                  const SizedBox(
+                                    width: 16,
+                                  ),
+                                  GestureDetector(
+                                    key: const Key(
+                                        "createBackupPasswordFieldShowPasswordButtonKey"),
+                                    onTap: () async {
+                                      setState(() {
+                                        hidePassword = !hidePassword;
+                                      });
+                                    },
+                                    child: SvgPicture.asset(
+                                      hidePassword
+                                          ? Assets.svg.eye
+                                          : Assets.svg.eyeSlash,
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textDark3,
+                                      width: 16,
+                                      height: 16,
+                                    ),
+                                  ),
+                                  const SizedBox(
+                                    width: 12,
+                                  ),
+                                ],
+                              ),
+                            ),
+                          ),
+                          onChanged: (newValue) {
+                            if (newValue.isEmpty) {
+                              setState(() {
+                                passwordFeedback = "";
+                              });
+                              return;
+                            }
+                            final result = zxcvbn.evaluate(newValue);
+                            String suggestionsAndTips = "";
+                            for (var sug
+                                in result.feedback.suggestions!.toSet()) {
+                              suggestionsAndTips += "$sug\n";
+                            }
+                            suggestionsAndTips += result.feedback.warning!;
+                            String feedback =
+                                // "Password Strength: ${((result.score! / 4.0) * 100).toInt()}%\n"
+                                suggestionsAndTips;
 
-                              if (pathToSave.isEmpty) {
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "Directory not chosen",
-                                  context: context,
-                                );
-                                return;
-                              }
-                              if (!(await Directory(pathToSave).exists())) {
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "Directory does not exist",
-                                  context: context,
-                                );
-                                return;
-                              }
-                              if (passphrase.isEmpty) {
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "A passphrase is required",
-                                  context: context,
-                                );
-                                return;
-                              }
-                              if (passphrase != repeatPassphrase) {
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "Passphrase does not match",
-                                  context: context,
-                                );
-                                return;
-                              }
+                            passwordStrength = result.score! / 4;
 
-                              showDialog<dynamic>(
-                                context: context,
-                                barrierDismissible: false,
-                                builder: (_) => const StackDialog(
-                                  title: "Encrypting initial backup",
-                                  message: "This shouldn't take long",
-                                ),
-                              );
+                            // hack fix to format back string returned from zxcvbn
+                            if (feedback.contains("phrasesNo need")) {
+                              feedback = feedback.replaceFirst(
+                                  "phrasesNo need", "phrases\nNo need");
+                            }
 
-                              // make sure the dialog is able to be displayed for at least some time
-                              final fut = Future<void>.delayed(
-                                  const Duration(milliseconds: 300));
+                            if (feedback.endsWith("\n")) {
+                              feedback =
+                                  feedback.substring(0, feedback.length - 2);
+                            }
 
-                              String adkString;
-                              int adkVersion;
-                              try {
-                                final adk =
-                                    await compute(generateAdk, passphrase);
-                                adkString = Format.uint8listToString(adk.item2);
-                                adkVersion = adk.item1;
-                              } on Exception catch (e, s) {
-                                String err = getErrorMessageFromSWBException(e);
-                                Logging.instance
-                                    .log("$err\n$s", level: LogLevel.Error);
-                                // pop encryption progress dialog
-                                Navigator.of(context).pop();
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: err,
-                                  context: context,
-                                );
-                                return;
-                              } catch (e, s) {
-                                Logging.instance
-                                    .log("$e\n$s", level: LogLevel.Error);
-                                // pop encryption progress dialog
-                                Navigator.of(context).pop();
-                                showFloatingFlushBar(
-                                  type: FlushBarType.warning,
-                                  message: "$e",
-                                  context: context,
-                                );
-                                return;
-                              }
-
-                              await secureStore.write(
-                                  key: "auto_adk_string", value: adkString);
-                              await secureStore.write(
-                                  key: "auto_adk_version_string",
-                                  value: adkVersion.toString());
-
-                              final DateTime now = DateTime.now();
-                              final String fileToSave =
-                                  createAutoBackupFilename(pathToSave, now);
-
-                              final backup = await SWB.createStackWalletJSON(
-                                secureStorage: secureStore,
-                              );
-
-                              bool result = await SWB.encryptStackWalletWithADK(
-                                fileToSave,
-                                adkString,
-                                jsonEncode(backup),
-                                adkVersion: adkVersion,
-                              );
-
-                              // this future should already be complete unless there was an error encrypting
-                              await Future.wait([fut]);
-
-                              if (mounted) {
-                                // pop encryption progress dialog
-                                Navigator.of(context).pop();
-
-                                if (result) {
-                                  ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .autoBackupLocation = pathToSave;
-                                  ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .lastAutoBackup = now;
-
-                                  ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .isAutoBackupEnabled = true;
-
-                                  await showDialog<dynamic>(
-                                    context: context,
-                                    barrierDismissible: false,
-                                    builder: (_) => Platform.isAndroid
-                                        ? StackOkDialog(
-                                            title:
-                                                "Stack Auto Backup enabled and saved to:",
-                                            message: fileToSave,
-                                          )
-                                        : const StackOkDialog(
-                                            title:
-                                                "Stack Auto Backup enabled!"),
-                                  );
-                                  if (mounted) {
-                                    passwordController.text = "";
-                                    passwordRepeatController.text = "";
-
-                                    Navigator.of(context).popUntil(
-                                        ModalRoute.withName(
-                                            AutoBackupView.routeName));
-                                  }
-                                } else {
-                                  await showDialog<dynamic>(
-                                    context: context,
-                                    barrierDismissible: false,
-                                    builder: (_) => const StackOkDialog(
-                                        title: "Failed to enable Auto Backup"),
-                                  );
-                                }
-                              }
-                            },
-                      child: Text(
-                        "Enable Auto Backup",
-                        style: STextStyles.button(context),
+                            setState(() {
+                              passwordFeedback = feedback;
+                            });
+                          },
+                        ),
                       ),
-                    ),
-                  ],
+                      if (passwordFocusNode.hasFocus ||
+                          passwordRepeatFocusNode.hasFocus ||
+                          passwordController.text.isNotEmpty)
+                        Padding(
+                          padding: EdgeInsets.only(
+                            left: 12,
+                            right: 12,
+                            top: passwordFeedback.isNotEmpty ? 4 : 0,
+                          ),
+                          child: passwordFeedback.isNotEmpty
+                              ? Text(
+                                  passwordFeedback,
+                                  style: STextStyles.infoSmall(context),
+                                )
+                              : null,
+                        ),
+                      if (passwordFocusNode.hasFocus ||
+                          passwordRepeatFocusNode.hasFocus ||
+                          passwordController.text.isNotEmpty)
+                        Padding(
+                          padding: const EdgeInsets.only(
+                            left: 12,
+                            right: 12,
+                            top: 10,
+                          ),
+                          child: ProgressBar(
+                            key: const Key("createStackBackUpProgressBar"),
+                            width: MediaQuery.of(context).size.width - 32 - 24,
+                            height: 5,
+                            fillColor: passwordStrength < 0.51
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .accentColorRed
+                                : passwordStrength < 1
+                                    ? Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorYellow
+                                    : Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorGreen,
+                            backgroundColor: Theme.of(context)
+                                .extension<StackColors>()!
+                                .buttonBackSecondary,
+                            percent: passwordStrength < 0.25
+                                ? 0.03
+                                : passwordStrength,
+                          ),
+                        ),
+                      const SizedBox(
+                        height: 10,
+                      ),
+                      ClipRRect(
+                        borderRadius: BorderRadius.circular(
+                          Constants.size.circularBorderRadius,
+                        ),
+                        child: TextField(
+                          key: const Key("createBackupPasswordFieldKey2"),
+                          focusNode: passwordRepeatFocusNode,
+                          controller: passwordRepeatController,
+                          style: STextStyles.field(context),
+                          obscureText: hidePassword,
+                          enableSuggestions: false,
+                          autocorrect: false,
+                          decoration: standardInputDecoration(
+                            "Confirm passphrase",
+                            passwordRepeatFocusNode,
+                            context,
+                          ).copyWith(
+                            suffixIcon: UnconstrainedBox(
+                              child: Row(
+                                children: [
+                                  const SizedBox(
+                                    width: 16,
+                                  ),
+                                  GestureDetector(
+                                    key: const Key(
+                                        "createBackupPasswordFieldShowPasswordButtonKey"),
+                                    onTap: () async {
+                                      setState(() {
+                                        hidePassword = !hidePassword;
+                                      });
+                                    },
+                                    child: SvgPicture.asset(
+                                      hidePassword
+                                          ? Assets.svg.eye
+                                          : Assets.svg.eyeSlash,
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .textDark3,
+                                      width: 16,
+                                      height: 16,
+                                    ),
+                                  ),
+                                  const SizedBox(
+                                    width: 12,
+                                  ),
+                                ],
+                              ),
+                            ),
+                          ),
+                          onChanged: (newValue) {
+                            setState(() {});
+                            // TODO: ? check if passwords match?
+                          },
+                        ),
+                      ),
+                      const SizedBox(
+                        height: 32,
+                      ),
+                      Text(
+                        "Auto Backup frequency",
+                        style: STextStyles.smallMed12(context),
+                      ),
+                      const SizedBox(
+                        height: 10,
+                      ),
+                      Stack(
+                        children: [
+                          TextField(
+                            autocorrect: Util.isDesktop ? false : true,
+                            enableSuggestions: Util.isDesktop ? false : true,
+                            readOnly: true,
+                            textInputAction: TextInputAction.none,
+                          ),
+                          Positioned.fill(
+                            child: RawMaterialButton(
+                              splashColor: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .highlight,
+                              shape: RoundedRectangleBorder(
+                                borderRadius: BorderRadius.circular(
+                                  Constants.size.circularBorderRadius,
+                                ),
+                              ),
+                              onPressed: () {
+                                showModalBottomSheet<dynamic>(
+                                  backgroundColor: Colors.transparent,
+                                  context: context,
+                                  shape: const RoundedRectangleBorder(
+                                    borderRadius: BorderRadius.vertical(
+                                      top: Radius.circular(20),
+                                    ),
+                                  ),
+                                  builder: (_) =>
+                                      const BackupFrequencyTypeSelectSheet(),
+                                );
+                              },
+                              child: Padding(
+                                padding: const EdgeInsets.symmetric(
+                                    horizontal: 12.0),
+                                child: Row(
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  children: [
+                                    Text(
+                                      Format.prettyFrequencyType(ref.watch(
+                                          prefsChangeNotifierProvider.select(
+                                              (value) =>
+                                                  value.backupFrequencyType))),
+                                      style:
+                                          STextStyles.itemSubtitle12(context),
+                                    ),
+                                    Padding(
+                                      padding:
+                                          const EdgeInsets.only(right: 4.0),
+                                      child: SvgPicture.asset(
+                                        Assets.svg.chevronDown,
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .textSubtitle2,
+                                        width: 12,
+                                        height: 6,
+                                      ),
+                                    ),
+                                  ],
+                                ),
+                              ),
+                            ),
+                          )
+                        ],
+                      ),
+                      const Spacer(),
+                      const SizedBox(
+                        height: 10,
+                      ),
+                      TextButton(
+                        style: shouldEnableCreate
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .getPrimaryEnabledButtonColor(context)
+                            : Theme.of(context)
+                                .extension<StackColors>()!
+                                .getPrimaryDisabledButtonColor(context),
+                        onPressed: !shouldEnableCreate
+                            ? null
+                            : () async {
+                                final String pathToSave =
+                                    fileLocationController.text;
+                                final String passphrase =
+                                    passwordController.text;
+                                final String repeatPassphrase =
+                                    passwordRepeatController.text;
+
+                                if (pathToSave.isEmpty) {
+                                  showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "Directory not chosen",
+                                    context: context,
+                                  );
+                                  return;
+                                }
+                                if (!(await Directory(pathToSave).exists())) {
+                                  showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "Directory does not exist",
+                                    context: context,
+                                  );
+                                  return;
+                                }
+                                if (passphrase.isEmpty) {
+                                  showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "A passphrase is required",
+                                    context: context,
+                                  );
+                                  return;
+                                }
+                                if (passphrase != repeatPassphrase) {
+                                  showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "Passphrase does not match",
+                                    context: context,
+                                  );
+                                  return;
+                                }
+
+                                showDialog<dynamic>(
+                                  context: context,
+                                  barrierDismissible: false,
+                                  builder: (_) => const StackDialog(
+                                    title: "Encrypting initial backup",
+                                    message: "This shouldn't take long",
+                                  ),
+                                );
+
+                                // make sure the dialog is able to be displayed for at least some time
+                                final fut = Future<void>.delayed(
+                                    const Duration(milliseconds: 300));
+
+                                String adkString;
+                                int adkVersion;
+                                try {
+                                  final adk =
+                                      await compute(generateAdk, passphrase);
+                                  adkString =
+                                      Format.uint8listToString(adk.item2);
+                                  adkVersion = adk.item1;
+                                } on Exception catch (e, s) {
+                                  String err =
+                                      getErrorMessageFromSWBException(e);
+                                  Logging.instance
+                                      .log("$err\n$s", level: LogLevel.Error);
+                                  // pop encryption progress dialog
+                                  Navigator.of(context).pop();
+                                  showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: err,
+                                    context: context,
+                                  );
+                                  return;
+                                } catch (e, s) {
+                                  Logging.instance
+                                      .log("$e\n$s", level: LogLevel.Error);
+                                  // pop encryption progress dialog
+                                  Navigator.of(context).pop();
+                                  showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "$e",
+                                    context: context,
+                                  );
+                                  return;
+                                }
+
+                                await secureStore.write(
+                                    key: "auto_adk_string", value: adkString);
+                                await secureStore.write(
+                                    key: "auto_adk_version_string",
+                                    value: adkVersion.toString());
+
+                                final DateTime now = DateTime.now();
+                                final String fileToSave =
+                                    createAutoBackupFilename(pathToSave, now);
+
+                                final backup = await SWB.createStackWalletJSON(
+                                  secureStorage: secureStore,
+                                );
+
+                                bool result =
+                                    await SWB.encryptStackWalletWithADK(
+                                  fileToSave,
+                                  adkString,
+                                  jsonEncode(backup),
+                                  adkVersion: adkVersion,
+                                );
+
+                                // this future should already be complete unless there was an error encrypting
+                                await Future.wait([fut]);
+
+                                if (mounted) {
+                                  // pop encryption progress dialog
+                                  Navigator.of(context).pop();
+
+                                  if (result) {
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .autoBackupLocation = pathToSave;
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .lastAutoBackup = now;
+
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .isAutoBackupEnabled = true;
+
+                                    await showDialog<dynamic>(
+                                      context: context,
+                                      barrierDismissible: false,
+                                      builder: (_) => Platform.isAndroid
+                                          ? StackOkDialog(
+                                              title:
+                                                  "Stack Auto Backup enabled and saved to:",
+                                              message: fileToSave,
+                                            )
+                                          : const StackOkDialog(
+                                              title:
+                                                  "Stack Auto Backup enabled!"),
+                                    );
+                                    if (mounted) {
+                                      passwordController.text = "";
+                                      passwordRepeatController.text = "";
+
+                                      Navigator.of(context).popUntil(
+                                          ModalRoute.withName(
+                                              AutoBackupView.routeName));
+                                    }
+                                  } else {
+                                    await showDialog<dynamic>(
+                                      context: context,
+                                      barrierDismissible: false,
+                                      builder: (_) => const StackOkDialog(
+                                          title:
+                                              "Failed to enable Auto Backup"),
+                                    );
+                                  }
+                                }
+                              },
+                        child: Text(
+                          "Enable Auto Backup",
+                          style: STextStyles.button(context),
+                        ),
+                      ),
+                    ],
+                  ),
                 ),
               ),
-            ),
-          );
-        }),
+            );
+          }),
+        ),
       ),
     );
   }
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_information_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_information_view.dart
index 772c446f2..012477a5b 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_information_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_information_view.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
@@ -12,75 +13,77 @@ class CreateBackupInfoView extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            if (FocusScope.of(context).hasFocus) {
-              FocusScope.of(context).unfocus();
-              await Future<void>.delayed(const Duration(milliseconds: 75));
-            }
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              if (FocusScope.of(context).hasFocus) {
+                FocusScope.of(context).unfocus();
+                await Future<void>.delayed(const Duration(milliseconds: 75));
+              }
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Create backup",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Create backup",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      Center(
-                        child: Text(
-                          "Info",
-                          style: STextStyles.pageTitleH2(context),
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        Center(
+                          child: Text(
+                            "Info",
+                            style: STextStyles.pageTitleH2(context),
+                          ),
                         ),
-                      ),
-                      const SizedBox(
-                        height: 16,
-                      ),
-                      RoundedWhiteContainer(
-                        child: Text(
-                          // TODO: need info
-                          "{lorem ipsum}",
-                          style: STextStyles.baseXS(context),
+                        const SizedBox(
+                          height: 16,
                         ),
-                      ),
-                      const SizedBox(
-                        height: 16,
-                      ),
-                      const Spacer(),
-                      TextButton(
-                        style: Theme.of(context)
-                            .extension<StackColors>()!
-                            .getPrimaryEnabledButtonColor(context),
-                        onPressed: () {
-                          Navigator.of(context)
-                              .pushNamed(CreateBackupView.routeName);
-                        },
-                        child: Text(
-                          "Next",
-                          style: STextStyles.button(context),
+                        RoundedWhiteContainer(
+                          child: Text(
+                            // TODO: need info
+                            "{lorem ipsum}",
+                            style: STextStyles.baseXS(context),
+                          ),
                         ),
-                      ),
-                    ],
+                        const SizedBox(
+                          height: 16,
+                        ),
+                        const Spacer(),
+                        TextButton(
+                          style: Theme.of(context)
+                              .extension<StackColors>()!
+                              .getPrimaryEnabledButtonColor(context),
+                          onPressed: () {
+                            Navigator.of(context)
+                                .pushNamed(CreateBackupView.routeName);
+                          },
+                          child: Text(
+                            "Next",
+                            style: STextStyles.button(context),
+                          ),
+                        ),
+                      ],
+                    ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
index a6241d25a..4d69ce4e9 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/create_backup_view.dart
@@ -16,6 +16,7 @@ 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/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -103,41 +104,44 @@ class _RestoreFromFileViewState extends State<CreateBackupView> {
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            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();
-                }
-              },
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              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(
+                "Create backup",
+                style: STextStyles.navBarTitle(context),
+              ),
             ),
-            title: Text(
-              "Create backup",
-              style: STextStyles.navBarTitle(context),
-            ),
-          ),
-          body: Padding(
-            padding: const EdgeInsets.all(16),
-            child: LayoutBuilder(
-              builder: (context, constraints) {
-                return SingleChildScrollView(
-                  child: ConstrainedBox(
-                    constraints: BoxConstraints(
-                      minHeight: constraints.maxHeight,
+            body: Padding(
+              padding: const EdgeInsets.all(16),
+              child: LayoutBuilder(
+                builder: (context, constraints) {
+                  return SingleChildScrollView(
+                    child: ConstrainedBox(
+                      constraints: BoxConstraints(
+                        minHeight: constraints.maxHeight,
+                      ),
+                      child: IntrinsicHeight(
+                        child: child,
+                      ),
                     ),
-                    child: IntrinsicHeight(
-                      child: child,
-                    ),
-                  ),
-                );
-              },
+                  );
+                },
+              ),
             ),
           ),
         );
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
index 310be9f2b..7187c5311 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/edit_auto_backup_view.dart
@@ -25,6 +25,7 @@ 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/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/primary_button.dart';
@@ -282,34 +283,37 @@ class _EditAutoBackupViewState extends ConsumerState<EditAutoBackupView> {
 
     return ConditionalParent(
       condition: !isDesktop,
-      builder: (child) => Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          leading: AppBarBackButton(
-            onPressed: () {
-              Navigator.of(context).pop();
-            },
+      builder: (child) => Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                Navigator.of(context).pop();
+              },
+            ),
+            title: Text(
+              "Edit Auto Backup",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
-          title: Text(
-            "Edit Auto Backup",
-            style: STextStyles.navBarTitle(context),
+          body: Padding(
+            padding: const EdgeInsets.all(16),
+            child: LayoutBuilder(builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight,
+                  ),
+                  child: IntrinsicHeight(
+                    child: child,
+                  ),
+                ),
+              );
+            }),
           ),
         ),
-        body: Padding(
-          padding: const EdgeInsets.all(16),
-          child: LayoutBuilder(builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: child,
-                ),
-              ),
-            );
-          }),
-        ),
       ),
       child: Column(
         crossAxisAlignment:
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart
index 3173bc402..14a262d99 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart
@@ -9,9 +9,9 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
@@ -62,204 +62,209 @@ class _RestoreFromEncryptedStringViewState
   Widget build(BuildContext context) {
     return WillPopScope(
       onWillPop: _onWillPop,
-      child: Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
-          leading: AppBarBackButton(
-            onPressed: () async {
-              if (FocusScope.of(context).hasFocus) {
-                FocusScope.of(context).unfocus();
-                await Future<void>.delayed(const Duration(milliseconds: 75));
-              }
-              if (mounted) {
-                _onWillPop();
-              }
-            },
+      child: Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () async {
+                if (FocusScope.of(context).hasFocus) {
+                  FocusScope.of(context).unfocus();
+                  await Future<void>.delayed(const Duration(milliseconds: 75));
+                }
+                if (mounted) {
+                  _onWillPop();
+                }
+              },
+            ),
+            title: Text(
+              "Restore from file",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
-          title: Text(
-            "Restore from file",
-            style: STextStyles.navBarTitle(context),
-          ),
-        ),
-        body: Padding(
-          padding: const EdgeInsets.all(16),
-          child: LayoutBuilder(
-            builder: (context, constraints) {
-              return SingleChildScrollView(
-                child: ConstrainedBox(
-                  constraints: BoxConstraints(
-                    minHeight: constraints.maxHeight,
-                  ),
-                  child: IntrinsicHeight(
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        ClipRRect(
-                          borderRadius: BorderRadius.circular(
-                            Constants.size.circularBorderRadius,
-                          ),
-                          child: TextField(
-                            key: const Key("restoreFromFilePasswordFieldKey"),
-                            focusNode: passwordFocusNode,
-                            controller: passwordController,
-                            style: STextStyles.field(context),
-                            obscureText: hidePassword,
-                            enableSuggestions: false,
-                            autocorrect: false,
-                            decoration: standardInputDecoration(
-                              "Enter password",
-                              passwordFocusNode,
-                              context,
-                            ).copyWith(
-                              suffixIcon: UnconstrainedBox(
-                                child: Row(
-                                  children: [
-                                    const SizedBox(
-                                      width: 16,
-                                    ),
-                                    GestureDetector(
-                                      key: const Key(
-                                          "restoreFromFilePasswordFieldShowPasswordButtonKey"),
-                                      onTap: () async {
-                                        setState(() {
-                                          hidePassword = !hidePassword;
-                                        });
-                                      },
-                                      child: SvgPicture.asset(
-                                        hidePassword
-                                            ? Assets.svg.eye
-                                            : Assets.svg.eyeSlash,
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .textDark3,
+          body: Padding(
+            padding: const EdgeInsets.all(16),
+            child: LayoutBuilder(
+              builder: (context, constraints) {
+                return SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints: BoxConstraints(
+                      minHeight: constraints.maxHeight,
+                    ),
+                    child: IntrinsicHeight(
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          ClipRRect(
+                            borderRadius: BorderRadius.circular(
+                              Constants.size.circularBorderRadius,
+                            ),
+                            child: TextField(
+                              key: const Key("restoreFromFilePasswordFieldKey"),
+                              focusNode: passwordFocusNode,
+                              controller: passwordController,
+                              style: STextStyles.field(context),
+                              obscureText: hidePassword,
+                              enableSuggestions: false,
+                              autocorrect: false,
+                              decoration: standardInputDecoration(
+                                "Enter password",
+                                passwordFocusNode,
+                                context,
+                              ).copyWith(
+                                suffixIcon: UnconstrainedBox(
+                                  child: Row(
+                                    children: [
+                                      const SizedBox(
                                         width: 16,
-                                        height: 16,
                                       ),
-                                    ),
-                                    const SizedBox(
-                                      width: 12,
-                                    ),
-                                  ],
+                                      GestureDetector(
+                                        key: const Key(
+                                            "restoreFromFilePasswordFieldShowPasswordButtonKey"),
+                                        onTap: () async {
+                                          setState(() {
+                                            hidePassword = !hidePassword;
+                                          });
+                                        },
+                                        child: SvgPicture.asset(
+                                          hidePassword
+                                              ? Assets.svg.eye
+                                              : Assets.svg.eyeSlash,
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .textDark3,
+                                          width: 16,
+                                          height: 16,
+                                        ),
+                                      ),
+                                      const SizedBox(
+                                        width: 12,
+                                      ),
+                                    ],
+                                  ),
                                 ),
                               ),
+                              onChanged: (newValue) {
+                                setState(() {});
+                              },
                             ),
-                            onChanged: (newValue) {
-                              setState(() {});
-                            },
                           ),
-                        ),
-                        const SizedBox(
-                          height: 16,
-                        ),
-                        const Spacer(),
-                        TextButton(
-                          style: passwordController.text.isEmpty
-                              ? Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .getPrimaryEnabledButtonColor(context)
-                              : Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .getPrimaryDisabledButtonColor(context),
-                          onPressed: passwordController.text.isEmpty
-                              ? null
-                              : () async {
-                                  final String passphrase =
-                                      passwordController.text;
+                          const SizedBox(
+                            height: 16,
+                          ),
+                          const Spacer(),
+                          TextButton(
+                            style: passwordController.text.isEmpty
+                                ? Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .getPrimaryEnabledButtonColor(context)
+                                : Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .getPrimaryDisabledButtonColor(context),
+                            onPressed: passwordController.text.isEmpty
+                                ? null
+                                : () async {
+                                    final String passphrase =
+                                        passwordController.text;
 
-                                  if (FocusScope.of(context).hasFocus) {
-                                    FocusScope.of(context).unfocus();
-                                    await Future<void>.delayed(
-                                        const Duration(milliseconds: 75));
-                                  }
+                                    if (FocusScope.of(context).hasFocus) {
+                                      FocusScope.of(context).unfocus();
+                                      await Future<void>.delayed(
+                                          const Duration(milliseconds: 75));
+                                    }
 
-                                  bool shouldPop = false;
-                                  showDialog<dynamic>(
-                                    barrierDismissible: false,
-                                    context: context,
-                                    builder: (_) => WillPopScope(
-                                      onWillPop: () async {
-                                        return shouldPop;
-                                      },
-                                      child: Column(
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.stretch,
-                                        mainAxisAlignment:
-                                            MainAxisAlignment.center,
-                                        children: [
-                                          Material(
-                                            color: Colors.transparent,
-                                            child: Center(
-                                              child: Text(
-                                                "Decrypting Stack backup file",
-                                                style: STextStyles.pageTitleH2(
-                                                        context)
-                                                    .copyWith(
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .textWhite,
+                                    bool shouldPop = false;
+                                    showDialog<dynamic>(
+                                      barrierDismissible: false,
+                                      context: context,
+                                      builder: (_) => WillPopScope(
+                                        onWillPop: () async {
+                                          return shouldPop;
+                                        },
+                                        child: Column(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.stretch,
+                                          mainAxisAlignment:
+                                              MainAxisAlignment.center,
+                                          children: [
+                                            Material(
+                                              color: Colors.transparent,
+                                              child: Center(
+                                                child: Text(
+                                                  "Decrypting Stack backup file",
+                                                  style:
+                                                      STextStyles.pageTitleH2(
+                                                              context)
+                                                          .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textWhite,
+                                                  ),
                                                 ),
                                               ),
                                             ),
-                                          ),
-                                          const SizedBox(
-                                            height: 64,
-                                          ),
-                                          const Center(
-                                            child: LoadingIndicator(
-                                              width: 100,
+                                            const SizedBox(
+                                              height: 64,
                                             ),
-                                          ),
-                                        ],
-                                      ),
-                                    ),
-                                  );
-
-                                  final String? jsonString = await compute(
-                                    SWB.decryptStackWalletStringWithPassphrase,
-                                    Tuple2(widget.encrypted, passphrase),
-                                    debugLabel:
-                                        "stack wallet decryption compute",
-                                  );
-
-                                  if (mounted) {
-                                    // pop LoadingIndicator
-                                    shouldPop = true;
-                                    Navigator.of(context).pop();
-
-                                    passwordController.text = "";
-
-                                    if (jsonString == null) {
-                                      showFloatingFlushBar(
-                                        type: FlushBarType.warning,
-                                        message:
-                                            "Failed to decrypt backup file",
-                                        context: context,
-                                      );
-                                      return;
-                                    }
-
-                                    Navigator.of(context).push(
-                                      RouteGenerator.getRoute(
-                                        builder: (_) =>
-                                            StackRestoreProgressView(
-                                          jsonString: jsonString,
-                                          fromFile: true,
+                                            const Center(
+                                              child: LoadingIndicator(
+                                                width: 100,
+                                              ),
+                                            ),
+                                          ],
                                         ),
                                       ),
                                     );
-                                  }
-                                },
-                          child: Text(
-                            "Restore",
-                            style: STextStyles.button(context),
+
+                                    final String? jsonString = await compute(
+                                      SWB.decryptStackWalletStringWithPassphrase,
+                                      Tuple2(widget.encrypted, passphrase),
+                                      debugLabel:
+                                          "stack wallet decryption compute",
+                                    );
+
+                                    if (mounted) {
+                                      // pop LoadingIndicator
+                                      shouldPop = true;
+                                      Navigator.of(context).pop();
+
+                                      passwordController.text = "";
+
+                                      if (jsonString == null) {
+                                        showFloatingFlushBar(
+                                          type: FlushBarType.warning,
+                                          message:
+                                              "Failed to decrypt backup file",
+                                          context: context,
+                                        );
+                                        return;
+                                      }
+
+                                      Navigator.of(context).push(
+                                        RouteGenerator.getRoute(
+                                          builder: (_) =>
+                                              StackRestoreProgressView(
+                                            jsonString: jsonString,
+                                            fromFile: true,
+                                          ),
+                                        ),
+                                      );
+                                    }
+                                  },
+                            child: Text(
+                              "Restore",
+                              style: STextStyles.button(context),
+                            ),
                           ),
-                        ),
-                      ],
+                        ],
+                      ),
                     ),
                   ),
-                ),
-              );
-            },
+                );
+              },
+            ),
           ),
         ),
       ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
index d6571967d..6350feb52 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/restore_from_file_view.dart
@@ -17,6 +17,7 @@ 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/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -75,42 +76,44 @@ class _RestoreFromFileViewState extends ConsumerState<RestoreFromFileView> {
     return ConditionalParent(
         condition: !isDesktop,
         builder: (child) {
-          return Scaffold(
-            backgroundColor:
-                Theme.of(context).extension<StackColors>()!.background,
-            appBar: AppBar(
-              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();
-                  }
-                },
+          return Background(
+            child: Scaffold(
+              backgroundColor:
+                  Theme.of(context).extension<StackColors>()!.background,
+              appBar: AppBar(
+                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(
+                  "Restore from file",
+                  style: STextStyles.navBarTitle(context),
+                ),
               ),
-              title: Text(
-                "Restore from file",
-                style: STextStyles.navBarTitle(context),
-              ),
-            ),
-            body: Padding(
-              padding: const EdgeInsets.all(16),
-              child: LayoutBuilder(
-                builder: (context, constraints) {
-                  return SingleChildScrollView(
-                    child: ConstrainedBox(
-                      constraints: BoxConstraints(
-                        minHeight: constraints.maxHeight,
+              body: Padding(
+                padding: const EdgeInsets.all(16),
+                child: LayoutBuilder(
+                  builder: (context, constraints) {
+                    return SingleChildScrollView(
+                      child: ConstrainedBox(
+                        constraints: BoxConstraints(
+                          minHeight: constraints.maxHeight,
+                        ),
+                        child: IntrinsicHeight(
+                          child: child,
+                        ),
                       ),
-                      child: IntrinsicHeight(
-                        child: child,
-                      ),
-                    ),
-                  );
-                },
+                    );
+                  },
+                ),
               ),
             ),
           );
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/stack_backup_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/stack_backup_view.dart
index 679043fe7..fe163cb66 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/stack_backup_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/stack_backup_view.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/utilities/assets.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/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
@@ -21,147 +22,149 @@ class StackBackupView extends StatelessWidget {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Stack backup",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Stack backup",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              RoundedWhiteContainer(
+                padding: const EdgeInsets.all(0),
+                child: RawMaterialButton(
+                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                  shape: RoundedRectangleBorder(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
                   ),
-                ),
-                onPressed: () {
-                  Navigator.of(context).pushNamed(AutoBackupView.routeName);
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    children: [
-                      SvgPicture.asset(
-                        Assets.svg.backupAuto,
-                        height: 28,
-                        width: 28,
-                      ),
-                      const SizedBox(
-                        width: 12,
-                      ),
-                      Text(
-                        "Auto Backup",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                    ],
+                  onPressed: () {
+                    Navigator.of(context).pushNamed(AutoBackupView.routeName);
+                  },
+                  child: Padding(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 12,
+                      vertical: 20,
+                    ),
+                    child: Row(
+                      children: [
+                        SvgPicture.asset(
+                          Assets.svg.backupAuto,
+                          height: 28,
+                          width: 28,
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                        Text(
+                          "Auto Backup",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
                   ),
                 ),
               ),
-            ),
-            const SizedBox(
-              height: 8,
-            ),
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
+              const SizedBox(
+                height: 8,
+              ),
+              RoundedWhiteContainer(
+                padding: const EdgeInsets.all(0),
+                child: RawMaterialButton(
+                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                  shape: RoundedRectangleBorder(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
                   ),
-                ),
-                onPressed: () {
-                  Navigator.of(context).pushNamed(CreateBackupView.routeName);
-                  // .pushNamed(CreateBackupInfoView.routeName);
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    children: [
-                      SvgPicture.asset(
-                        Assets.svg.backupAdd,
-                        height: 28,
-                        width: 28,
-                      ),
-                      const SizedBox(
-                        width: 12,
-                      ),
-                      Text(
-                        "Create manual backup",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                    ],
+                  onPressed: () {
+                    Navigator.of(context).pushNamed(CreateBackupView.routeName);
+                    // .pushNamed(CreateBackupInfoView.routeName);
+                  },
+                  child: Padding(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 12,
+                      vertical: 20,
+                    ),
+                    child: Row(
+                      children: [
+                        SvgPicture.asset(
+                          Assets.svg.backupAdd,
+                          height: 28,
+                          width: 28,
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                        Text(
+                          "Create manual backup",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
                   ),
                 ),
               ),
-            ),
-            const SizedBox(
-              height: 8,
-            ),
-            RoundedWhiteContainer(
-              padding: const EdgeInsets.all(0),
-              child: RawMaterialButton(
-                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                shape: RoundedRectangleBorder(
-                  borderRadius: BorderRadius.circular(
-                    Constants.size.circularBorderRadius,
+              const SizedBox(
+                height: 8,
+              ),
+              RoundedWhiteContainer(
+                padding: const EdgeInsets.all(0),
+                child: RawMaterialButton(
+                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                  shape: RoundedRectangleBorder(
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
                   ),
-                ),
-                onPressed: () {
-                  Navigator.of(context)
-                      .pushNamed(RestoreFromFileView.routeName);
-                },
-                child: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 12,
-                    vertical: 20,
-                  ),
-                  child: Row(
-                    children: [
-                      SvgPicture.asset(
-                        Assets.svg.backupRestore,
-                        height: 28,
-                        width: 28,
-                      ),
-                      const SizedBox(
-                        width: 12,
-                      ),
-                      Text(
-                        "Restore backup",
-                        style: STextStyles.titleBold12(context),
-                        textAlign: TextAlign.left,
-                      ),
-                    ],
+                  onPressed: () {
+                    Navigator.of(context)
+                        .pushNamed(RestoreFromFileView.routeName);
+                  },
+                  child: Padding(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 12,
+                      vertical: 20,
+                    ),
+                    child: Row(
+                      children: [
+                        SvgPicture.asset(
+                          Assets.svg.backupRestore,
+                          height: 28,
+                          width: 28,
+                        ),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                        Text(
+                          "Restore backup",
+                          style: STextStyles.titleBold12(context),
+                          textAlign: TextAlign.left,
+                        ),
+                      ],
+                    ),
                   ),
                 ),
               ),
-            ),
-          ],
+            ],
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/startup_preferences/startup_preferences_view.dart b/lib/pages/settings_views/global_settings_view/startup_preferences/startup_preferences_view.dart
index baf649ba2..186b9b293 100644
--- a/lib/pages/settings_views/global_settings_view/startup_preferences/startup_preferences_view.dart
+++ b/lib/pages/settings_views/global_settings_view/startup_preferences/startup_preferences_view.dart
@@ -5,6 +5,7 @@ import 'package:stackwallet/providers/global/prefs_provider.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/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
@@ -22,255 +23,263 @@ class _StartupPreferencesViewState
     extends ConsumerState<StartupPreferencesView> {
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Startup preferences",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Startup preferences",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      RoundedWhiteContainer(
-                        padding: const EdgeInsets.all(0),
-                        child: Column(
-                          crossAxisAlignment: CrossAxisAlignment.stretch,
-                          children: [
-                            Padding(
-                              padding: const EdgeInsets.all(4.0),
-                              child: RawMaterialButton(
-                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                materialTapTargetSize:
-                                    MaterialTapTargetSize.shrinkWrap,
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        RoundedWhiteContainer(
+                          padding: const EdgeInsets.all(0),
+                          child: Column(
+                            crossAxisAlignment: CrossAxisAlignment.stretch,
+                            children: [
+                              Padding(
+                                padding: const EdgeInsets.all(4.0),
+                                child: RawMaterialButton(
+                                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                                  materialTapTargetSize:
+                                      MaterialTapTargetSize.shrinkWrap,
+                                  shape: RoundedRectangleBorder(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                  ),
+                                  onPressed: () {
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .gotoWalletOnStartup = false;
+                                  },
+                                  child: Container(
+                                    color: Colors.transparent,
+                                    child: Padding(
+                                      padding: const EdgeInsets.all(8.0),
+                                      child: Row(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          SizedBox(
+                                            width: 20,
+                                            height: 20,
+                                            child: Radio(
+                                              activeColor: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .radioButtonIconEnabled,
+                                              value: false,
+                                              groupValue: ref.watch(
+                                                prefsChangeNotifierProvider
+                                                    .select((value) => value
+                                                        .gotoWalletOnStartup),
+                                              ),
+                                              onChanged: (value) {
+                                                if (value is bool) {
+                                                  ref
+                                                      .read(
+                                                          prefsChangeNotifierProvider)
+                                                      .gotoWalletOnStartup = value;
+                                                }
+                                              },
+                                            ),
+                                          ),
+                                          const SizedBox(
+                                            width: 12,
+                                          ),
+                                          Flexible(
+                                            child: Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.start,
+                                              children: [
+                                                Text(
+                                                  "Home screen",
+                                                  style:
+                                                      STextStyles.titleBold12(
+                                                          context),
+                                                  textAlign: TextAlign.left,
+                                                ),
+                                                Text(
+                                                  "Stack Wallet home screen",
+                                                  style:
+                                                      STextStyles.itemSubtitle(
+                                                          context),
+                                                  textAlign: TextAlign.left,
+                                                ),
+                                              ],
+                                            ),
+                                          ),
+                                        ],
+                                      ),
+                                    ),
                                   ),
                                 ),
-                                onPressed: () {
-                                  ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .gotoWalletOnStartup = false;
-                                },
-                                child: Container(
+                              ),
+                              Padding(
+                                padding: const EdgeInsets.all(4),
+                                child: RawMaterialButton(
+                                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                                  materialTapTargetSize:
+                                      MaterialTapTargetSize.shrinkWrap,
+                                  shape: RoundedRectangleBorder(
+                                    borderRadius: BorderRadius.circular(
+                                      Constants.size.circularBorderRadius,
+                                    ),
+                                  ),
+                                  onPressed: () {
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .gotoWalletOnStartup = true;
+                                  },
+                                  child: Container(
+                                    color: Colors.transparent,
+                                    child: Padding(
+                                      padding: const EdgeInsets.all(8),
+                                      child: Row(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          SizedBox(
+                                            width: 20,
+                                            height: 20,
+                                            child: Radio(
+                                              activeColor: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .radioButtonIconEnabled,
+                                              value: true,
+                                              groupValue: ref.watch(
+                                                prefsChangeNotifierProvider
+                                                    .select((value) => value
+                                                        .gotoWalletOnStartup),
+                                              ),
+                                              onChanged: (value) {
+                                                if (value is bool) {
+                                                  ref
+                                                      .read(
+                                                          prefsChangeNotifierProvider)
+                                                      .gotoWalletOnStartup = value;
+                                                }
+                                              },
+                                            ),
+                                          ),
+                                          const SizedBox(
+                                            width: 12,
+                                          ),
+                                          Flexible(
+                                            child: Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.start,
+                                              children: [
+                                                Text(
+                                                  "Specific wallet",
+                                                  style:
+                                                      STextStyles.titleBold12(
+                                                          context),
+                                                  textAlign: TextAlign.left,
+                                                ),
+                                                Text(
+                                                  "Select a specific wallet to load into on startup",
+                                                  style:
+                                                      STextStyles.itemSubtitle(
+                                                          context),
+                                                  textAlign: TextAlign.left,
+                                                ),
+                                              ],
+                                            ),
+                                          ),
+                                        ],
+                                      ),
+                                    ),
+                                  ),
+                                ),
+                              ),
+                              if (!ref.watch(prefsChangeNotifierProvider.select(
+                                  (value) => value.gotoWalletOnStartup)))
+                                const SizedBox(
+                                  height: 12,
+                                ),
+                              if (ref.watch(prefsChangeNotifierProvider.select(
+                                  (value) => value.gotoWalletOnStartup)))
+                                Container(
                                   color: Colors.transparent,
                                   child: Padding(
-                                    padding: const EdgeInsets.all(8.0),
+                                    padding: const EdgeInsets.only(
+                                      left: 12.0,
+                                      right: 12,
+                                      bottom: 12,
+                                    ),
                                     child: Row(
                                       crossAxisAlignment:
                                           CrossAxisAlignment.start,
                                       children: [
-                                        SizedBox(
-                                          width: 20,
-                                          height: 20,
-                                          child: Radio(
-                                            activeColor: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .radioButtonIconEnabled,
-                                            value: false,
-                                            groupValue: ref.watch(
-                                              prefsChangeNotifierProvider
-                                                  .select((value) => value
-                                                      .gotoWalletOnStartup),
-                                            ),
-                                            onChanged: (value) {
-                                              if (value is bool) {
-                                                ref
-                                                    .read(
-                                                        prefsChangeNotifierProvider)
-                                                    .gotoWalletOnStartup = value;
-                                              }
-                                            },
-                                          ),
-                                        ),
                                         const SizedBox(
-                                          width: 12,
+                                          width: 12 + 20,
+                                          height: 12,
                                         ),
                                         Flexible(
-                                          child: Column(
-                                            crossAxisAlignment:
-                                                CrossAxisAlignment.start,
-                                            children: [
-                                              Text(
-                                                "Home screen",
-                                                style: STextStyles.titleBold12(
-                                                    context),
-                                                textAlign: TextAlign.left,
+                                          child: RawMaterialButton(
+                                            // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                                            materialTapTargetSize:
+                                                MaterialTapTargetSize
+                                                    .shrinkWrap,
+                                            shape: RoundedRectangleBorder(
+                                              borderRadius:
+                                                  BorderRadius.circular(
+                                                Constants
+                                                    .size.circularBorderRadius,
                                               ),
-                                              Text(
-                                                "Stack Wallet home screen",
-                                                style: STextStyles.itemSubtitle(
-                                                    context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                            ],
+                                            ),
+                                            onPressed: () {
+                                              Navigator.of(context).pushNamed(
+                                                  StartupWalletSelectionView
+                                                      .routeName);
+                                            },
+                                            child: Column(
+                                              crossAxisAlignment:
+                                                  CrossAxisAlignment.start,
+                                              children: [
+                                                Text(
+                                                  "Select wallet...",
+                                                  style: STextStyles.link2(
+                                                      context),
+                                                  textAlign: TextAlign.left,
+                                                ),
+                                              ],
+                                            ),
                                           ),
                                         ),
                                       ],
                                     ),
                                   ),
                                 ),
-                              ),
-                            ),
-                            Padding(
-                              padding: const EdgeInsets.all(4),
-                              child: RawMaterialButton(
-                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                materialTapTargetSize:
-                                    MaterialTapTargetSize.shrinkWrap,
-                                shape: RoundedRectangleBorder(
-                                  borderRadius: BorderRadius.circular(
-                                    Constants.size.circularBorderRadius,
-                                  ),
-                                ),
-                                onPressed: () {
-                                  ref
-                                      .read(prefsChangeNotifierProvider)
-                                      .gotoWalletOnStartup = true;
-                                },
-                                child: Container(
-                                  color: Colors.transparent,
-                                  child: Padding(
-                                    padding: const EdgeInsets.all(8),
-                                    child: Row(
-                                      crossAxisAlignment:
-                                          CrossAxisAlignment.start,
-                                      children: [
-                                        SizedBox(
-                                          width: 20,
-                                          height: 20,
-                                          child: Radio(
-                                            activeColor: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .radioButtonIconEnabled,
-                                            value: true,
-                                            groupValue: ref.watch(
-                                              prefsChangeNotifierProvider
-                                                  .select((value) => value
-                                                      .gotoWalletOnStartup),
-                                            ),
-                                            onChanged: (value) {
-                                              if (value is bool) {
-                                                ref
-                                                    .read(
-                                                        prefsChangeNotifierProvider)
-                                                    .gotoWalletOnStartup = value;
-                                              }
-                                            },
-                                          ),
-                                        ),
-                                        const SizedBox(
-                                          width: 12,
-                                        ),
-                                        Flexible(
-                                          child: Column(
-                                            crossAxisAlignment:
-                                                CrossAxisAlignment.start,
-                                            children: [
-                                              Text(
-                                                "Specific wallet",
-                                                style: STextStyles.titleBold12(
-                                                    context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                              Text(
-                                                "Select a specific wallet to load into on startup",
-                                                style: STextStyles.itemSubtitle(
-                                                    context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                            ],
-                                          ),
-                                        ),
-                                      ],
-                                    ),
-                                  ),
-                                ),
-                              ),
-                            ),
-                            if (!ref.watch(prefsChangeNotifierProvider
-                                .select((value) => value.gotoWalletOnStartup)))
-                              const SizedBox(
-                                height: 12,
-                              ),
-                            if (ref.watch(prefsChangeNotifierProvider
-                                .select((value) => value.gotoWalletOnStartup)))
-                              Container(
-                                color: Colors.transparent,
-                                child: Padding(
-                                  padding: const EdgeInsets.only(
-                                    left: 12.0,
-                                    right: 12,
-                                    bottom: 12,
-                                  ),
-                                  child: Row(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.start,
-                                    children: [
-                                      const SizedBox(
-                                        width: 12 + 20,
-                                        height: 12,
-                                      ),
-                                      Flexible(
-                                        child: RawMaterialButton(
-                                          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                                          materialTapTargetSize:
-                                              MaterialTapTargetSize.shrinkWrap,
-                                          shape: RoundedRectangleBorder(
-                                            borderRadius: BorderRadius.circular(
-                                              Constants
-                                                  .size.circularBorderRadius,
-                                            ),
-                                          ),
-                                          onPressed: () {
-                                            Navigator.of(context).pushNamed(
-                                                StartupWalletSelectionView
-                                                    .routeName);
-                                          },
-                                          child: Column(
-                                            crossAxisAlignment:
-                                                CrossAxisAlignment.start,
-                                            children: [
-                                              Text(
-                                                "Select wallet...",
-                                                style:
-                                                    STextStyles.link2(context),
-                                                textAlign: TextAlign.left,
-                                              ),
-                                            ],
-                                          ),
-                                        ),
-                                      ),
-                                    ],
-                                  ),
-                                ),
-                              ),
-                          ],
+                            ],
+                          ),
                         ),
-                      ),
-                    ],
+                      ],
+                    ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart b/lib/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart
index 5d9f2edb1..975e8394d 100644
--- a/lib/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart
+++ b/lib/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart
@@ -6,6 +6,7 @@ import 'package:stackwallet/utilities/assets.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/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -33,170 +34,173 @@ class _StartupWalletSelectionViewState
       _controllers[manager.walletId] = DSBController();
     }
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: FittedBox(
-          fit: BoxFit.scaleDown,
-          child: Text(
-            "Select startup wallet",
-            style: STextStyles.navBarTitle(context),
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: FittedBox(
+            fit: BoxFit.scaleDown,
+            child: Text(
+              "Select startup wallet",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
         ),
-      ),
-      body: LayoutBuilder(builder: (context, constraints) {
-        return Padding(
-          padding: const EdgeInsets.only(
-            left: 12,
-            top: 12,
-            right: 12,
-          ),
-          child: SingleChildScrollView(
-            child: ConstrainedBox(
-              constraints: BoxConstraints(
-                minHeight: constraints.maxHeight - 24,
-              ),
-              child: IntrinsicHeight(
-                child: Padding(
-                  padding: const EdgeInsets.all(4),
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.start,
-                    children: [
-                      const SizedBox(
-                        height: 4,
-                      ),
-                      Text(
-                        "Select a wallet to load into immediately on startup",
-                        style: STextStyles.smallMed12(context),
-                      ),
-                      const SizedBox(
-                        height: 12,
-                      ),
-                      RoundedWhiteContainer(
-                        padding: const EdgeInsets.all(0),
-                        child: Column(
-                          children: [
-                            ...managers.map(
-                              (manager) => Padding(
-                                padding: const EdgeInsets.all(12),
-                                child: Row(
-                                  key: Key(
-                                      "startupWalletSelectionGroupKey_${manager.walletId}"),
-                                  children: [
-                                    Container(
-                                      decoration: BoxDecoration(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .colorForCoin(manager.coin)
-                                            .withOpacity(0.5),
-                                        borderRadius: BorderRadius.circular(
-                                          Constants.size.circularBorderRadius,
-                                        ),
-                                      ),
-                                      child: Padding(
-                                        padding: const EdgeInsets.all(4),
-                                        child: SvgPicture.asset(
-                                          Assets.svg
-                                              .iconFor(coin: manager.coin),
-                                          width: 20,
-                                          height: 20,
-                                        ),
-                                      ),
-                                    ),
-                                    const SizedBox(
-                                      width: 12,
-                                    ),
-                                    Expanded(
-                                      child: Column(
-                                        mainAxisAlignment:
-                                            MainAxisAlignment.spaceBetween,
-                                        crossAxisAlignment:
-                                            CrossAxisAlignment.start,
-                                        children: [
-                                          Text(
-                                            manager.walletName,
-                                            style: STextStyles.titleBold12(
-                                                context),
+        body: LayoutBuilder(builder: (context, constraints) {
+          return Padding(
+            padding: const EdgeInsets.only(
+              left: 12,
+              top: 12,
+              right: 12,
+            ),
+            child: SingleChildScrollView(
+              child: ConstrainedBox(
+                constraints: BoxConstraints(
+                  minHeight: constraints.maxHeight - 24,
+                ),
+                child: IntrinsicHeight(
+                  child: Padding(
+                    padding: const EdgeInsets.all(4),
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      children: [
+                        const SizedBox(
+                          height: 4,
+                        ),
+                        Text(
+                          "Select a wallet to load into immediately on startup",
+                          style: STextStyles.smallMed12(context),
+                        ),
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        RoundedWhiteContainer(
+                          padding: const EdgeInsets.all(0),
+                          child: Column(
+                            children: [
+                              ...managers.map(
+                                (manager) => Padding(
+                                  padding: const EdgeInsets.all(12),
+                                  child: Row(
+                                    key: Key(
+                                        "startupWalletSelectionGroupKey_${manager.walletId}"),
+                                    children: [
+                                      Container(
+                                        decoration: BoxDecoration(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .colorForCoin(manager.coin)
+                                              .withOpacity(0.5),
+                                          borderRadius: BorderRadius.circular(
+                                            Constants.size.circularBorderRadius,
+                                          ),
+                                        ),
+                                        child: Padding(
+                                          padding: const EdgeInsets.all(4),
+                                          child: SvgPicture.asset(
+                                            Assets.svg
+                                                .iconFor(coin: manager.coin),
+                                            width: 20,
+                                            height: 20,
                                           ),
-                                          // const SizedBox(
-                                          //   height: 2,
-                                          // ),
-                                          // FutureBuilder(
-                                          //   future: manager.totalBalance,
-                                          //   builder: (builderContext,
-                                          //       AsyncSnapshot<Decimal> snapshot) {
-                                          //     if (snapshot.connectionState ==
-                                          //             ConnectionState.done &&
-                                          //         snapshot.hasData) {
-                                          //       return Text(
-                                          //         "${Format.localizedStringAsFixed(
-                                          //           value: snapshot.data!,
-                                          //           locale: ref.watch(
-                                          //               localeServiceChangeNotifierProvider
-                                          //                   .select((value) =>
-                                          //                       value.locale)),
-                                          //           decimalPlaces: 8,
-                                          //         )} ${manager.coin.ticker}",
-                                          //         style: STextStyles.itemSubtitle(context),
-                                          //       );
-                                          //     } else {
-                                          //       return AnimatedText(
-                                          //         stringsToLoopThrough: const [
-                                          //           "Loading balance",
-                                          //           "Loading balance.",
-                                          //           "Loading balance..",
-                                          //           "Loading balance..."
-                                          //         ],
-                                          //         style: STextStyles.itemSubtitle(context),
-                                          //       );
-                                          //     }
-                                          //   },
-                                          // ),
-                                        ],
-                                      ),
-                                    ),
-                                    SizedBox(
-                                      height: 20,
-                                      width: 20,
-                                      child: Radio(
-                                        activeColor: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .radioButtonIconEnabled,
-                                        value: manager.walletId,
-                                        groupValue: ref.watch(
-                                          prefsChangeNotifierProvider.select(
-                                              (value) => value.startupWalletId),
                                         ),
-                                        onChanged: (value) {
-                                          if (value is String) {
-                                            ref
-                                                .read(
-                                                    prefsChangeNotifierProvider)
-                                                .startupWalletId = value;
-                                          }
-                                        },
                                       ),
-                                    ),
-                                  ],
+                                      const SizedBox(
+                                        width: 12,
+                                      ),
+                                      Expanded(
+                                        child: Column(
+                                          mainAxisAlignment:
+                                              MainAxisAlignment.spaceBetween,
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            Text(
+                                              manager.walletName,
+                                              style: STextStyles.titleBold12(
+                                                  context),
+                                            ),
+                                            // const SizedBox(
+                                            //   height: 2,
+                                            // ),
+                                            // FutureBuilder(
+                                            //   future: manager.totalBalance,
+                                            //   builder: (builderContext,
+                                            //       AsyncSnapshot<Decimal> snapshot) {
+                                            //     if (snapshot.connectionState ==
+                                            //             ConnectionState.done &&
+                                            //         snapshot.hasData) {
+                                            //       return Text(
+                                            //         "${Format.localizedStringAsFixed(
+                                            //           value: snapshot.data!,
+                                            //           locale: ref.watch(
+                                            //               localeServiceChangeNotifierProvider
+                                            //                   .select((value) =>
+                                            //                       value.locale)),
+                                            //           decimalPlaces: 8,
+                                            //         )} ${manager.coin.ticker}",
+                                            //         style: STextStyles.itemSubtitle(context),
+                                            //       );
+                                            //     } else {
+                                            //       return AnimatedText(
+                                            //         stringsToLoopThrough: const [
+                                            //           "Loading balance",
+                                            //           "Loading balance.",
+                                            //           "Loading balance..",
+                                            //           "Loading balance..."
+                                            //         ],
+                                            //         style: STextStyles.itemSubtitle(context),
+                                            //       );
+                                            //     }
+                                            //   },
+                                            // ),
+                                          ],
+                                        ),
+                                      ),
+                                      SizedBox(
+                                        height: 20,
+                                        width: 20,
+                                        child: Radio(
+                                          activeColor: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .radioButtonIconEnabled,
+                                          value: manager.walletId,
+                                          groupValue: ref.watch(
+                                            prefsChangeNotifierProvider.select(
+                                                (value) =>
+                                                    value.startupWalletId),
+                                          ),
+                                          onChanged: (value) {
+                                            if (value is String) {
+                                              ref
+                                                  .read(
+                                                      prefsChangeNotifierProvider)
+                                                  .startupWalletId = value;
+                                            }
+                                          },
+                                        ),
+                                      ),
+                                    ],
+                                  ),
                                 ),
                               ),
-                            ),
-                          ],
+                            ],
+                          ),
                         ),
-                      ),
-                    ],
+                      ],
+                    ),
                   ),
                 ),
               ),
             ),
-          ),
-        );
-      }),
+          );
+        }),
+      ),
     );
   }
 }
diff --git a/lib/pages/settings_views/global_settings_view/support_view.dart b/lib/pages/settings_views/global_settings_view/support_view.dart
index ee00bdb00..1cc3d35a1 100644
--- a/lib/pages/settings_views/global_settings_view/support_view.dart
+++ b/lib/pages/settings_views/global_settings_view/support_view.dart
@@ -5,6 +5,7 @@ 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/rounded_white_container.dart';
@@ -26,24 +27,26 @@ class SupportView extends StatelessWidget {
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            leading: AppBarBackButton(
-              onPressed: () {
-                Navigator.of(context).pop();
-              },
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              leading: AppBarBackButton(
+                onPressed: () {
+                  Navigator.of(context).pop();
+                },
+              ),
+              title: Text(
+                "Support",
+                style: STextStyles.navBarTitle(context),
+              ),
             ),
-            title: Text(
-              "Support",
-              style: STextStyles.navBarTitle(context),
+            body: Padding(
+              padding: const EdgeInsets.all(16),
+              child: child,
             ),
           ),
-          body: Padding(
-            padding: const EdgeInsets.all(16),
-            child: child,
-          ),
         );
       },
       child: Column(
diff --git a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart
index 3681009a9..10a93d7e8 100644
--- a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart
+++ b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart
@@ -7,6 +7,7 @@ import 'package:stackwallet/utilities/enums/sync_type_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/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -24,35 +25,37 @@ class SyncingOptionsView extends ConsumerWidget {
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            leading: AppBarBackButton(
-              onPressed: () async {
-                Navigator.of(context).pop();
-              },
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              leading: AppBarBackButton(
+                onPressed: () async {
+                  Navigator.of(context).pop();
+                },
+              ),
+              title: Text(
+                "Syncing",
+                style: STextStyles.navBarTitle(context),
+              ),
             ),
-            title: Text(
-              "Syncing",
-              style: STextStyles.navBarTitle(context),
-            ),
-          ),
-          body: Padding(
-            padding: const EdgeInsets.all(16),
-            child: LayoutBuilder(
-              builder: (context, constraints) {
-                return SingleChildScrollView(
-                  child: ConstrainedBox(
-                    constraints: BoxConstraints(
-                      minHeight: constraints.maxHeight,
+            body: Padding(
+              padding: const EdgeInsets.all(16),
+              child: LayoutBuilder(
+                builder: (context, constraints) {
+                  return SingleChildScrollView(
+                    child: ConstrainedBox(
+                      constraints: BoxConstraints(
+                        minHeight: constraints.maxHeight,
+                      ),
+                      child: IntrinsicHeight(
+                        child: child,
+                      ),
                     ),
-                    child: IntrinsicHeight(
-                      child: child,
-                    ),
-                  ),
-                );
-              },
+                  );
+                },
+              ),
             ),
           ),
         );
diff --git a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_preferences_view.dart b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_preferences_view.dart
index e48ebb342..6ce84627e 100644
--- a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_preferences_view.dart
+++ b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/syncing_preferences_view.dart
@@ -6,6 +6,7 @@ import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/sync_type_enum.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -28,131 +29,136 @@ class SyncingPreferencesView extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () async {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () async {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Syncing preferences",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Syncing preferences",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: LayoutBuilder(
-          builder: (context, constraints) {
-            return SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight,
-                ),
-                child: IntrinsicHeight(
-                  child: Column(
-                    crossAxisAlignment: CrossAxisAlignment.stretch,
-                    children: [
-                      RoundedWhiteContainer(
-                        padding: const EdgeInsets.all(0),
-                        child: RawMaterialButton(
-                          // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: LayoutBuilder(
+            builder: (context, constraints) {
+              return SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: [
+                        RoundedWhiteContainer(
                           padding: const EdgeInsets.all(0),
-                          materialTapTargetSize:
-                              MaterialTapTargetSize.shrinkWrap,
-                          shape: RoundedRectangleBorder(
-                            borderRadius: BorderRadius.circular(
-                              Constants.size.circularBorderRadius,
-                            ),
-                          ),
-                          onPressed: () {
-                            Navigator.of(context)
-                                .pushNamed(SyncingOptionsView.routeName);
-                          },
-                          child: Padding(
-                            padding: const EdgeInsets.all(12),
-                            child: Row(
-                              children: [
-                                Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Syncing",
-                                      style: STextStyles.titleBold12(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    Text(
-                                      _currentTypeDescription(ref.watch(
-                                          prefsChangeNotifierProvider.select(
-                                              (value) => value.syncType))),
-                                      style: STextStyles.itemSubtitle(context),
-                                      textAlign: TextAlign.left,
-                                    )
-                                  ],
-                                ),
-                                const Spacer(),
-                              ],
-                            ),
-                          ),
-                        ),
-                      ),
-                      const SizedBox(
-                        height: 8,
-                      ),
-                      RoundedWhiteContainer(
-                        child: Consumer(
-                          builder: (_, ref, __) {
-                            return RawMaterialButton(
-                              // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                              materialTapTargetSize:
-                                  MaterialTapTargetSize.shrinkWrap,
-                              shape: RoundedRectangleBorder(
-                                borderRadius: BorderRadius.circular(
-                                  Constants.size.circularBorderRadius,
-                                ),
+                          child: RawMaterialButton(
+                            // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                            padding: const EdgeInsets.all(0),
+                            materialTapTargetSize:
+                                MaterialTapTargetSize.shrinkWrap,
+                            shape: RoundedRectangleBorder(
+                              borderRadius: BorderRadius.circular(
+                                Constants.size.circularBorderRadius,
                               ),
-                              onPressed: null,
-                              child: Padding(
-                                padding:
-                                    const EdgeInsets.symmetric(vertical: 8),
-                                child: Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
-                                  children: [
-                                    Text(
-                                      "AutoSync only on Wi-Fi",
-                                      style: STextStyles.titleBold12(context),
-                                      textAlign: TextAlign.left,
-                                    ),
-                                    SizedBox(
-                                      height: 20,
-                                      width: 40,
-                                      child: DraggableSwitchButton(
-                                        isOn: ref.watch(
-                                          prefsChangeNotifierProvider.select(
-                                              (value) => value.wifiOnly),
-                                        ),
-                                        onValueChanged: (newValue) {
-                                          ref
-                                              .read(prefsChangeNotifierProvider)
-                                              .wifiOnly = newValue;
-                                        },
+                            ),
+                            onPressed: () {
+                              Navigator.of(context)
+                                  .pushNamed(SyncingOptionsView.routeName);
+                            },
+                            child: Padding(
+                              padding: const EdgeInsets.all(12),
+                              child: Row(
+                                children: [
+                                  Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.start,
+                                    children: [
+                                      Text(
+                                        "Syncing",
+                                        style: STextStyles.titleBold12(context),
+                                        textAlign: TextAlign.left,
                                       ),
-                                    ),
-                                  ],
-                                ),
+                                      Text(
+                                        _currentTypeDescription(ref.watch(
+                                            prefsChangeNotifierProvider.select(
+                                                (value) => value.syncType))),
+                                        style:
+                                            STextStyles.itemSubtitle(context),
+                                        textAlign: TextAlign.left,
+                                      )
+                                    ],
+                                  ),
+                                  const Spacer(),
+                                ],
                               ),
-                            );
-                          },
+                            ),
+                          ),
                         ),
-                      ),
-                    ],
+                        const SizedBox(
+                          height: 8,
+                        ),
+                        RoundedWhiteContainer(
+                          child: Consumer(
+                            builder: (_, ref, __) {
+                              return RawMaterialButton(
+                                // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                                materialTapTargetSize:
+                                    MaterialTapTargetSize.shrinkWrap,
+                                shape: RoundedRectangleBorder(
+                                  borderRadius: BorderRadius.circular(
+                                    Constants.size.circularBorderRadius,
+                                  ),
+                                ),
+                                onPressed: null,
+                                child: Padding(
+                                  padding:
+                                      const EdgeInsets.symmetric(vertical: 8),
+                                  child: Row(
+                                    mainAxisAlignment:
+                                        MainAxisAlignment.spaceBetween,
+                                    children: [
+                                      Text(
+                                        "AutoSync only on Wi-Fi",
+                                        style: STextStyles.titleBold12(context),
+                                        textAlign: TextAlign.left,
+                                      ),
+                                      SizedBox(
+                                        height: 20,
+                                        width: 40,
+                                        child: DraggableSwitchButton(
+                                          isOn: ref.watch(
+                                            prefsChangeNotifierProvider.select(
+                                                (value) => value.wifiOnly),
+                                          ),
+                                          onValueChanged: (newValue) {
+                                            ref
+                                                .read(
+                                                    prefsChangeNotifierProvider)
+                                                .wifiOnly = newValue;
+                                          },
+                                        ),
+                                      ),
+                                    ],
+                                  ),
+                                ),
+                              );
+                            },
+                          ),
+                        ),
+                      ],
+                    ),
                   ),
                 ),
-              ),
-            );
-          },
+              );
+            },
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
index 9724356a1..7cbc86b7a 100644
--- a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
+++ b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
@@ -12,6 +12,7 @@ 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/animated_text.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/custom_buttons/draggable_switch_button.dart';
@@ -31,30 +32,32 @@ class WalletSyncingOptionsView extends ConsumerWidget {
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            leading: AppBarBackButton(
-              onPressed: () async {
-                Navigator.of(context).pop();
-              },
-            ),
-            title: FittedBox(
-              fit: BoxFit.scaleDown,
-              child: Text(
-                "Sync only selected wallets at startup",
-                style: STextStyles.navBarTitle(context),
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              leading: AppBarBackButton(
+                onPressed: () async {
+                  Navigator.of(context).pop();
+                },
+              ),
+              title: FittedBox(
+                fit: BoxFit.scaleDown,
+                child: Text(
+                  "Sync only selected wallets at startup",
+                  style: STextStyles.navBarTitle(context),
+                ),
               ),
             ),
-          ),
-          body: Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
+            body: Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: child,
             ),
-            child: child,
           ),
         );
       },
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart
index 3d557d245..a9235172f 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart
@@ -15,6 +15,7 @@ import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
@@ -35,186 +36,188 @@ class WalletBackupView extends ConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     debugPrint("BUILD: $runtimeType");
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
-        ),
-        title: Text(
-          "Wallet backup",
-          style: STextStyles.navBarTitle(context),
-        ),
-        actions: [
-          Padding(
-            padding: const EdgeInsets.all(10),
-            child: AspectRatio(
-              aspectRatio: 1,
-              child: AppBarIconButton(
-                color: Theme.of(context).extension<StackColors>()!.background,
-                shadows: const [],
-                icon: SvgPicture.asset(
-                  Assets.svg.copy,
-                  width: 20,
-                  height: 20,
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .topNavIconPrimary,
-                ),
-                onPressed: () async {
-                  await clipboardInterface
-                      .setData(ClipboardData(text: mnemonic.join(" ")));
-                  unawaited(showFloatingFlushBar(
-                    type: FlushBarType.info,
-                    message: "Copied to clipboard",
-                    iconAsset: Assets.svg.copy,
-                    context: context,
-                  ));
-                },
-              ),
-            ),
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
           ),
-        ],
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            const SizedBox(
-              height: 4,
-            ),
-            Text(
-              ref
-                  .watch(walletsChangeNotifierProvider
-                      .select((value) => value.getManager(walletId)))
-                  .walletName,
-              textAlign: TextAlign.center,
-              style: STextStyles.label(context).copyWith(
-                fontSize: 12,
-              ),
-            ),
-            const SizedBox(
-              height: 4,
-            ),
-            Text(
-              "Recovery Phrase",
-              textAlign: TextAlign.center,
-              style: STextStyles.pageTitleH1(context),
-            ),
-            const SizedBox(
-              height: 16,
-            ),
-            Container(
-              decoration: BoxDecoration(
-                color: Theme.of(context).extension<StackColors>()!.popupBG,
-                borderRadius:
-                    BorderRadius.circular(Constants.size.circularBorderRadius),
-              ),
-              child: Padding(
-                padding: const EdgeInsets.all(12),
-                child: Text(
-                  "Please write down your backup key. Keep it safe and never share it with anyone. Your backup key is the only way you can access your funds if you forget your PIN, lose your phone, etc.\n\nStack Wallet does not keep nor is able to restore your backup key. Only you have access to your wallet.",
-                  style: STextStyles.label(context),
+          title: Text(
+            "Wallet backup",
+            style: STextStyles.navBarTitle(context),
+          ),
+          actions: [
+            Padding(
+              padding: const EdgeInsets.all(10),
+              child: AspectRatio(
+                aspectRatio: 1,
+                child: AppBarIconButton(
+                  color: Theme.of(context).extension<StackColors>()!.background,
+                  shadows: const [],
+                  icon: SvgPicture.asset(
+                    Assets.svg.copy,
+                    width: 20,
+                    height: 20,
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .topNavIconPrimary,
+                  ),
+                  onPressed: () async {
+                    await clipboardInterface
+                        .setData(ClipboardData(text: mnemonic.join(" ")));
+                    unawaited(showFloatingFlushBar(
+                      type: FlushBarType.info,
+                      message: "Copied to clipboard",
+                      iconAsset: Assets.svg.copy,
+                      context: context,
+                    ));
+                  },
                 ),
               ),
             ),
-            const SizedBox(
-              height: 8,
-            ),
-            Expanded(
-              child: SingleChildScrollView(
-                child: MnemonicTable(
-                  words: mnemonic,
-                  isDesktop: false,
+          ],
+        ),
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              const SizedBox(
+                height: 4,
+              ),
+              Text(
+                ref
+                    .watch(walletsChangeNotifierProvider
+                        .select((value) => value.getManager(walletId)))
+                    .walletName,
+                textAlign: TextAlign.center,
+                style: STextStyles.label(context).copyWith(
+                  fontSize: 12,
                 ),
               ),
-            ),
-            const SizedBox(
-              height: 12,
-            ),
-            TextButton(
-              style: Theme.of(context)
-                  .extension<StackColors>()!
-                  .getPrimaryEnabledButtonColor(context),
-              onPressed: () {
-                String data = AddressUtils.encodeQRSeedData(mnemonic);
+              const SizedBox(
+                height: 4,
+              ),
+              Text(
+                "Recovery Phrase",
+                textAlign: TextAlign.center,
+                style: STextStyles.pageTitleH1(context),
+              ),
+              const SizedBox(
+                height: 16,
+              ),
+              Container(
+                decoration: BoxDecoration(
+                  color: Theme.of(context).extension<StackColors>()!.popupBG,
+                  borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius),
+                ),
+                child: Padding(
+                  padding: const EdgeInsets.all(12),
+                  child: Text(
+                    "Please write down your backup key. Keep it safe and never share it with anyone. Your backup key is the only way you can access your funds if you forget your PIN, lose your phone, etc.\n\nStack Wallet does not keep nor is able to restore your backup key. Only you have access to your wallet.",
+                    style: STextStyles.label(context),
+                  ),
+                ),
+              ),
+              const SizedBox(
+                height: 8,
+              ),
+              Expanded(
+                child: SingleChildScrollView(
+                  child: MnemonicTable(
+                    words: mnemonic,
+                    isDesktop: false,
+                  ),
+                ),
+              ),
+              const SizedBox(
+                height: 12,
+              ),
+              TextButton(
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getPrimaryEnabledButtonColor(context),
+                onPressed: () {
+                  String data = AddressUtils.encodeQRSeedData(mnemonic);
 
-                showDialog<dynamic>(
-                  context: context,
-                  useSafeArea: false,
-                  barrierDismissible: true,
-                  builder: (_) {
-                    final width = MediaQuery.of(context).size.width / 2;
-                    return StackDialogBase(
-                      child: Column(
-                        crossAxisAlignment: CrossAxisAlignment.stretch,
-                        children: [
-                          Center(
-                            child: Text(
-                              "Recovery phrase QR code",
-                              style: STextStyles.pageTitleH2(context),
-                            ),
-                          ),
-                          const SizedBox(
-                            height: 12,
-                          ),
-                          Center(
-                            child: RepaintBoundary(
-                              // key: _qrKey,
-                              child: SizedBox(
-                                width: width + 20,
-                                height: width + 20,
-                                child: QrImage(
-                                    data: data,
-                                    size: width,
-                                    backgroundColor: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .popupBG,
-                                    foregroundColor: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .accentColorDark),
+                  showDialog<dynamic>(
+                    context: context,
+                    useSafeArea: false,
+                    barrierDismissible: true,
+                    builder: (_) {
+                      final width = MediaQuery.of(context).size.width / 2;
+                      return StackDialogBase(
+                        child: Column(
+                          crossAxisAlignment: CrossAxisAlignment.stretch,
+                          children: [
+                            Center(
+                              child: Text(
+                                "Recovery phrase QR code",
+                                style: STextStyles.pageTitleH2(context),
                               ),
                             ),
-                          ),
-                          const SizedBox(
-                            height: 12,
-                          ),
-                          Center(
-                            child: SizedBox(
-                              width: width,
-                              child: TextButton(
-                                onPressed: () async {
-                                  // await _capturePng(true);
-                                  Navigator.of(context).pop();
-                                },
-                                style: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .getSecondaryEnabledButtonColor(context),
-                                child: Text(
-                                  "Cancel",
-                                  style: STextStyles.button(context).copyWith(
-                                      color: Theme.of(context)
+                            const SizedBox(
+                              height: 12,
+                            ),
+                            Center(
+                              child: RepaintBoundary(
+                                // key: _qrKey,
+                                child: SizedBox(
+                                  width: width + 20,
+                                  height: width + 20,
+                                  child: QrImage(
+                                      data: data,
+                                      size: width,
+                                      backgroundColor: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .popupBG,
+                                      foregroundColor: Theme.of(context)
                                           .extension<StackColors>()!
                                           .accentColorDark),
                                 ),
                               ),
                             ),
-                          ),
-                        ],
-                      ),
-                    );
-                  },
-                );
-              },
-              child: Text(
-                "Show QR Code",
-                style: STextStyles.button(context),
+                            const SizedBox(
+                              height: 12,
+                            ),
+                            Center(
+                              child: SizedBox(
+                                width: width,
+                                child: TextButton(
+                                  onPressed: () async {
+                                    // await _capturePng(true);
+                                    Navigator.of(context).pop();
+                                  },
+                                  style: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .getSecondaryEnabledButtonColor(context),
+                                  child: Text(
+                                    "Cancel",
+                                    style: STextStyles.button(context).copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .accentColorDark),
+                                  ),
+                                ),
+                              ),
+                            ),
+                          ],
+                        ),
+                      );
+                    },
+                  );
+                },
+                child: Text(
+                  "Show QR Code",
+                  style: STextStyles.button(context),
+                ),
               ),
-            ),
-          ],
+            ],
+          ),
         ),
       ),
     );
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 3044467aa..7e29010b1 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
@@ -26,6 +26,7 @@ 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/animated_text.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/custom_buttons/blue_text_button.dart';
@@ -312,118 +313,122 @@ class _WalletNetworkSettingsViewState
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) {
-        return Scaffold(
-          backgroundColor:
-              Theme.of(context).extension<StackColors>()!.background,
-          appBar: AppBar(
-            leading: AppBarBackButton(
-              onPressed: () {
-                Navigator.of(context).pop();
-              },
-            ),
-            title: Text(
-              "Network",
-              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,
+        return Background(
+          child: Scaffold(
+            backgroundColor:
+                Theme.of(context).extension<StackColors>()!.background,
+            appBar: AppBar(
+              leading: AppBarBackButton(
+                onPressed: () {
+                  Navigator.of(context).pop();
+                },
+              ),
+              title: Text(
+                "Network",
+                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>()!
-                          .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();
-                                          showDialog<void>(
-                                            context: context,
-                                            useSafeArea: false,
-                                            barrierDismissible: true,
-                                            builder: (context) {
-                                              return ConfirmFullRescanDialog(
-                                                onConfirm: _attemptRescan,
-                                              );
-                                            },
-                                          );
-                                        },
-                                        child: RoundedWhiteContainer(
-                                          child: Material(
-                                            color: Colors.transparent,
-                                            child: Text(
-                                              "Rescan blockchain",
-                                              style:
-                                                  STextStyles.baseXS(context),
+                          .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();
+                                            showDialog<void>(
+                                              context: context,
+                                              useSafeArea: false,
+                                              barrierDismissible: true,
+                                              builder: (context) {
+                                                return ConfirmFullRescanDialog(
+                                                  onConfirm: _attemptRescan,
+                                                );
+                                              },
+                                            );
+                                          },
+                                          child: RoundedWhiteContainer(
+                                            child: Material(
+                                              color: Colors.transparent,
+                                              child: Text(
+                                                "Rescan blockchain",
+                                                style:
+                                                    STextStyles.baseXS(context),
+                                              ),
                                             ),
                                           ),
                                         ),
-                                      ),
-                                    ],
+                                      ],
+                                    ),
                                   ),
                                 ),
-                              ),
-                            ],
-                          );
-                        },
-                      );
-                    },
+                              ],
+                            );
+                          },
+                        );
+                      },
+                    ),
                   ),
                 ),
-              ),
-            ],
-          ),
-          body: Padding(
-            padding: EdgeInsets.only(
-              top: 12,
-              left: _padding,
-              right: _padding,
+              ],
             ),
-            child: SingleChildScrollView(
-              child: Column(
-                crossAxisAlignment: CrossAxisAlignment.stretch,
-                children: [
-                  child,
-                ],
+            body: Padding(
+              padding: EdgeInsets.only(
+                top: 12,
+                left: _padding,
+                right: _padding,
+              ),
+              child: SingleChildScrollView(
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.stretch,
+                  children: [
+                    child,
+                  ],
+                ),
               ),
             ),
           ),
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
index 2d8909245..92b712111 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
@@ -23,15 +23,14 @@ import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_
 import 'package:stackwallet/services/event_bus/global_event_bus.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:tuple/tuple.dart';
 
-import 'package:stackwallet/utilities/util.dart';
-
 /// [eventBus] should only be set during testing
 class WalletSettingsView extends StatefulWidget {
   const WalletSettingsView({
@@ -134,196 +133,199 @@ class _WalletSettingsViewState extends State<WalletSettingsView> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Settings",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Settings",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: LayoutBuilder(
-        builder: (builderContext, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.stretch,
-                      children: [
-                        RoundedWhiteContainer(
-                          padding: const EdgeInsets.all(4),
-                          child: Column(
-                            children: [
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.addressBook,
-                                iconSize: 16,
-                                title: "Address book",
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                    AddressBookView.routeName,
-                                    arguments: coin,
-                                  );
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.node,
-                                iconSize: 16,
-                                title: "Network",
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                    WalletNetworkSettingsView.routeName,
-                                    arguments: Tuple3(
-                                      walletId,
-                                      _currentSyncStatus,
-                                      widget.initialNodeStatus,
-                                    ),
-                                  );
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              Consumer(
-                                builder: (_, ref, __) {
-                                  return SettingsListButton(
-                                    iconAssetName: Assets.svg.lock,
-                                    iconSize: 16,
-                                    title: "Wallet backup",
-                                    onPressed: () async {
-                                      final mnemonic = await ref
-                                          .read(walletsChangeNotifierProvider)
-                                          .getManager(walletId)
-                                          .mnemonic;
+        body: LayoutBuilder(
+          builder: (builderContext, constraints) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.stretch,
+                        children: [
+                          RoundedWhiteContainer(
+                            padding: const EdgeInsets.all(4),
+                            child: Column(
+                              children: [
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.addressBook,
+                                  iconSize: 16,
+                                  title: "Address book",
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                      AddressBookView.routeName,
+                                      arguments: coin,
+                                    );
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.node,
+                                  iconSize: 16,
+                                  title: "Network",
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                      WalletNetworkSettingsView.routeName,
+                                      arguments: Tuple3(
+                                        walletId,
+                                        _currentSyncStatus,
+                                        widget.initialNodeStatus,
+                                      ),
+                                    );
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                Consumer(
+                                  builder: (_, ref, __) {
+                                    return SettingsListButton(
+                                      iconAssetName: Assets.svg.lock,
+                                      iconSize: 16,
+                                      title: "Wallet backup",
+                                      onPressed: () async {
+                                        final mnemonic = await ref
+                                            .read(walletsChangeNotifierProvider)
+                                            .getManager(walletId)
+                                            .mnemonic;
 
-                                      if (mounted) {
-                                        Navigator.push(
-                                          context,
-                                          RouteGenerator.getRoute(
-                                            shouldUseMaterialRoute:
-                                                RouteGenerator
-                                                    .useMaterialPageRoute,
-                                            builder: (_) => LockscreenView(
-                                              routeOnSuccessArguments:
-                                                  Tuple2(walletId, mnemonic),
-                                              showBackButton: true,
-                                              routeOnSuccess:
-                                                  WalletBackupView.routeName,
-                                              biometricsCancelButtonString:
-                                                  "CANCEL",
-                                              biometricsLocalizedReason:
-                                                  "Authenticate to view recovery phrase",
-                                              biometricsAuthenticationTitle:
-                                                  "View recovery phrase",
+                                        if (mounted) {
+                                          Navigator.push(
+                                            context,
+                                            RouteGenerator.getRoute(
+                                              shouldUseMaterialRoute:
+                                                  RouteGenerator
+                                                      .useMaterialPageRoute,
+                                              builder: (_) => LockscreenView(
+                                                routeOnSuccessArguments:
+                                                    Tuple2(walletId, mnemonic),
+                                                showBackButton: true,
+                                                routeOnSuccess:
+                                                    WalletBackupView.routeName,
+                                                biometricsCancelButtonString:
+                                                    "CANCEL",
+                                                biometricsLocalizedReason:
+                                                    "Authenticate to view recovery phrase",
+                                                biometricsAuthenticationTitle:
+                                                    "View recovery phrase",
+                                              ),
+                                              settings: const RouteSettings(
+                                                  name:
+                                                      "/viewRecoverPhraseLockscreen"),
                                             ),
-                                            settings: const RouteSettings(
-                                                name:
-                                                    "/viewRecoverPhraseLockscreen"),
-                                          ),
-                                        );
-                                      }
-                                    },
-                                  );
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.downloadFolder,
-                                title: "Wallet settings",
-                                iconSize: 16,
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                    WalletSettingsWalletSettingsView.routeName,
-                                    arguments: walletId,
-                                  );
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.arrowRotate3,
-                                title: "Syncing preferences",
-                                onPressed: () {
-                                  Navigator.of(context).pushNamed(
-                                      SyncingPreferencesView.routeName);
-                                },
-                              ),
-                              const SizedBox(
-                                height: 8,
-                              ),
-                              SettingsListButton(
-                                iconAssetName: Assets.svg.ellipsis,
-                                title: "Debug Info",
-                                onPressed: () {
-                                  Navigator.of(context)
-                                      .pushNamed(DebugView.routeName);
-                                },
-                              ),
-                            ],
+                                          );
+                                        }
+                                      },
+                                    );
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.downloadFolder,
+                                  title: "Wallet settings",
+                                  iconSize: 16,
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                      WalletSettingsWalletSettingsView
+                                          .routeName,
+                                      arguments: walletId,
+                                    );
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.arrowRotate3,
+                                  title: "Syncing preferences",
+                                  onPressed: () {
+                                    Navigator.of(context).pushNamed(
+                                        SyncingPreferencesView.routeName);
+                                  },
+                                ),
+                                const SizedBox(
+                                  height: 8,
+                                ),
+                                SettingsListButton(
+                                  iconAssetName: Assets.svg.ellipsis,
+                                  title: "Debug Info",
+                                  onPressed: () {
+                                    Navigator.of(context)
+                                        .pushNamed(DebugView.routeName);
+                                  },
+                                ),
+                              ],
+                            ),
                           ),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        const Spacer(),
-                        Consumer(
-                          builder: (_, ref, __) {
-                            return TextButton(
-                              onPressed: () {
-                                ref
-                                    .read(walletsChangeNotifierProvider)
-                                    .getManager(walletId)
-                                    .isActiveWallet = false;
-                                ref
-                                    .read(transactionFilterProvider.state)
-                                    .state = null;
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          const Spacer(),
+                          Consumer(
+                            builder: (_, ref, __) {
+                              return TextButton(
+                                onPressed: () {
+                                  ref
+                                      .read(walletsChangeNotifierProvider)
+                                      .getManager(walletId)
+                                      .isActiveWallet = false;
+                                  ref
+                                      .read(transactionFilterProvider.state)
+                                      .state = null;
 
-                                Navigator.of(context).popUntil(
-                                  ModalRoute.withName(HomeView.routeName),
-                                );
-                              },
-                              style: Theme.of(context)
-                                  .extension<StackColors>()!
-                                  .getSecondaryEnabledButtonColor(context),
-                              child: Text(
-                                "Log out",
-                                style: STextStyles.button(context).copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .accentColorDark),
-                              ),
-                            );
-                          },
-                        ),
-                      ],
+                                  Navigator.of(context).popUntil(
+                                    ModalRoute.withName(HomeView.routeName),
+                                  );
+                                },
+                                style: Theme.of(context)
+                                    .extension<StackColors>()!
+                                    .getSecondaryEnabledButtonColor(context),
+                                child: Text(
+                                  "Log out",
+                                  style: STextStyles.button(context).copyWith(
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .accentColorDark),
+                                ),
+                              );
+                            },
+                          ),
+                        ],
+                      ),
                     ),
                   ),
                 ),
               ),
-            ),
-          );
-        },
+            );
+          },
+        ),
       ),
     );
   }
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart
index 66d666c20..5543bf1c0 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart
@@ -13,6 +13,7 @@ import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
@@ -54,164 +55,167 @@ class _DeleteWalletRecoveryPhraseViewState
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
-        ),
-        actions: [
-          Padding(
-            padding: const EdgeInsets.all(10),
-            child: AspectRatio(
-              aspectRatio: 1,
-              child: AppBarIconButton(
-                color: Theme.of(context).extension<StackColors>()!.background,
-                shadows: const [],
-                icon: SvgPicture.asset(
-                  Assets.svg.copy,
-                  width: 20,
-                  height: 20,
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .topNavIconPrimary,
-                ),
-                onPressed: () async {
-                  final words = await _manager.mnemonic;
-                  await _clipboardInterface
-                      .setData(ClipboardData(text: words.join(" ")));
-                  showFloatingFlushBar(
-                    type: FlushBarType.info,
-                    message: "Copied to clipboard",
-                    iconAsset: Assets.svg.copy,
-                    context: context,
-                  );
-                },
-              ),
-            ),
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
           ),
-        ],
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            const SizedBox(
-              height: 4,
-            ),
-            Text(
-              _manager.walletName,
-              textAlign: TextAlign.center,
-              style: STextStyles.label(context).copyWith(
-                fontSize: 12,
-              ),
-            ),
-            const SizedBox(
-              height: 4,
-            ),
-            Text(
-              "Recovery Phrase",
-              textAlign: TextAlign.center,
-              style: STextStyles.pageTitleH1(context),
-            ),
-            const SizedBox(
-              height: 16,
-            ),
-            Container(
-              decoration: BoxDecoration(
-                color: Theme.of(context).extension<StackColors>()!.popupBG,
-                borderRadius:
-                    BorderRadius.circular(Constants.size.circularBorderRadius),
-              ),
-              child: Padding(
-                padding: const EdgeInsets.all(12),
-                child: Text(
-                  "Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
-                  style: STextStyles.label(context).copyWith(
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .accentColorDark),
-                ),
-              ),
-            ),
-            const SizedBox(
-              height: 8,
-            ),
-            Expanded(
-              child: SingleChildScrollView(
-                child: MnemonicTable(
-                  words: _mnemonic,
-                  isDesktop: false,
-                ),
-              ),
-            ),
-            const SizedBox(
-              height: 16,
-            ),
-            TextButton(
-              style: Theme.of(context)
-                  .extension<StackColors>()!
-                  .getPrimaryEnabledButtonColor(context),
-              onPressed: () {
-                showDialog<dynamic>(
-                  barrierDismissible: true,
-                  context: context,
-                  builder: (_) => StackDialog(
-                    title: "Thanks! Your wallet will be deleted.",
-                    leftButton: TextButton(
-                      style: Theme.of(context)
-                          .extension<StackColors>()!
-                          .getSecondaryEnabledButtonColor(context),
-                      onPressed: () {
-                        Navigator.pop(context);
-                      },
-                      child: Text(
-                        "Cancel",
-                        style: STextStyles.button(context).copyWith(
-                            color: Theme.of(context)
-                                .extension<StackColors>()!
-                                .accentColorDark),
-                      ),
-                    ),
-                    rightButton: TextButton(
-                      style: Theme.of(context)
-                          .extension<StackColors>()!
-                          .getPrimaryEnabledButtonColor(context),
-                      onPressed: () async {
-                        final walletId = _manager.walletId;
-                        final walletsInstance =
-                            ref.read(walletsChangeNotifierProvider);
-                        await ref
-                            .read(walletsServiceChangeNotifierProvider)
-                            .deleteWallet(_manager.walletName, true);
-
-                        if (mounted) {
-                          Navigator.of(context).popUntil(
-                              ModalRoute.withName(HomeView.routeName));
-                        }
-
-                        // wait for widget tree to dispose of any widgets watching the manager
-                        await Future<void>.delayed(const Duration(seconds: 1));
-                        walletsInstance.removeWallet(walletId: walletId);
-                      },
-                      child: Text(
-                        "Ok",
-                        style: STextStyles.button(context),
-                      ),
-                    ),
+          actions: [
+            Padding(
+              padding: const EdgeInsets.all(10),
+              child: AspectRatio(
+                aspectRatio: 1,
+                child: AppBarIconButton(
+                  color: Theme.of(context).extension<StackColors>()!.background,
+                  shadows: const [],
+                  icon: SvgPicture.asset(
+                    Assets.svg.copy,
+                    width: 20,
+                    height: 20,
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .topNavIconPrimary,
                   ),
-                );
-              },
-              child: Text(
-                "Continue",
-                style: STextStyles.button(context),
+                  onPressed: () async {
+                    final words = await _manager.mnemonic;
+                    await _clipboardInterface
+                        .setData(ClipboardData(text: words.join(" ")));
+                    showFloatingFlushBar(
+                      type: FlushBarType.info,
+                      message: "Copied to clipboard",
+                      iconAsset: Assets.svg.copy,
+                      context: context,
+                    );
+                  },
+                ),
               ),
             ),
           ],
         ),
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              const SizedBox(
+                height: 4,
+              ),
+              Text(
+                _manager.walletName,
+                textAlign: TextAlign.center,
+                style: STextStyles.label(context).copyWith(
+                  fontSize: 12,
+                ),
+              ),
+              const SizedBox(
+                height: 4,
+              ),
+              Text(
+                "Recovery Phrase",
+                textAlign: TextAlign.center,
+                style: STextStyles.pageTitleH1(context),
+              ),
+              const SizedBox(
+                height: 16,
+              ),
+              Container(
+                decoration: BoxDecoration(
+                  color: Theme.of(context).extension<StackColors>()!.popupBG,
+                  borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius),
+                ),
+                child: Padding(
+                  padding: const EdgeInsets.all(12),
+                  child: Text(
+                    "Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
+                    style: STextStyles.label(context).copyWith(
+                        color: Theme.of(context)
+                            .extension<StackColors>()!
+                            .accentColorDark),
+                  ),
+                ),
+              ),
+              const SizedBox(
+                height: 8,
+              ),
+              Expanded(
+                child: SingleChildScrollView(
+                  child: MnemonicTable(
+                    words: _mnemonic,
+                    isDesktop: false,
+                  ),
+                ),
+              ),
+              const SizedBox(
+                height: 16,
+              ),
+              TextButton(
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getPrimaryEnabledButtonColor(context),
+                onPressed: () {
+                  showDialog<dynamic>(
+                    barrierDismissible: true,
+                    context: context,
+                    builder: (_) => StackDialog(
+                      title: "Thanks! Your wallet will be deleted.",
+                      leftButton: TextButton(
+                        style: Theme.of(context)
+                            .extension<StackColors>()!
+                            .getSecondaryEnabledButtonColor(context),
+                        onPressed: () {
+                          Navigator.pop(context);
+                        },
+                        child: Text(
+                          "Cancel",
+                          style: STextStyles.button(context).copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorDark),
+                        ),
+                      ),
+                      rightButton: TextButton(
+                        style: Theme.of(context)
+                            .extension<StackColors>()!
+                            .getPrimaryEnabledButtonColor(context),
+                        onPressed: () async {
+                          final walletId = _manager.walletId;
+                          final walletsInstance =
+                              ref.read(walletsChangeNotifierProvider);
+                          await ref
+                              .read(walletsServiceChangeNotifierProvider)
+                              .deleteWallet(_manager.walletName, true);
+
+                          if (mounted) {
+                            Navigator.of(context).popUntil(
+                                ModalRoute.withName(HomeView.routeName));
+                          }
+
+                          // wait for widget tree to dispose of any widgets watching the manager
+                          await Future<void>.delayed(
+                              const Duration(seconds: 1));
+                          walletsInstance.removeWallet(walletId: walletId);
+                        },
+                        child: Text(
+                          "Ok",
+                          style: STextStyles.button(context),
+                        ),
+                      ),
+                    ),
+                  );
+                },
+                child: Text(
+                  "Continue",
+                  style: STextStyles.button(context),
+                ),
+              ),
+            ],
+          ),
+        ),
       ),
     );
   }
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart
index ec8c5a128..f740eee12 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart
@@ -4,6 +4,7 @@ import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_set
 import 'package:stackwallet/providers/providers.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:tuple/tuple.dart';
@@ -20,93 +21,96 @@ class DeleteWalletWarningView extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
         ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.only(
-          top: 12,
-          left: 16,
-          right: 16,
-        ),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            const SizedBox(
-              height: 32,
-            ),
-            Center(
-              child: Text(
-                "Attention!",
-                style: STextStyles.pageTitleH1(context),
+        body: Padding(
+          padding: const EdgeInsets.only(
+            top: 12,
+            left: 16,
+            right: 16,
+          ),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              const SizedBox(
+                height: 32,
               ),
-            ),
-            const SizedBox(
-              height: 16,
-            ),
-            RoundedContainer(
-              color:
-                  Theme.of(context).extension<StackColors>()!.warningBackground,
-              child: Text(
-                "You are going to permanently delete you wallet.\n\nIf you delete your wallet, the only way you can have access to your funds is by using your backup key.\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet.\n\nPLEASE SAVE YOUR BACKUP KEY.",
-                style: STextStyles.baseXS(context).copyWith(
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .warningForeground,
+              Center(
+                child: Text(
+                  "Attention!",
+                  style: STextStyles.pageTitleH1(context),
                 ),
               ),
-            ),
-            const Spacer(),
-            TextButton(
-              style: Theme.of(context)
-                  .extension<StackColors>()!
-                  .getSecondaryEnabledButtonColor(context),
-              onPressed: () {
-                Navigator.pop(context);
-              },
-              child: Text(
-                "Cancel",
-                style: STextStyles.button(context).copyWith(
+              const SizedBox(
+                height: 16,
+              ),
+              RoundedContainer(
+                color: Theme.of(context)
+                    .extension<StackColors>()!
+                    .warningBackground,
+                child: Text(
+                  "You are going to permanently delete you wallet.\n\nIf you delete your wallet, the only way you can have access to your funds is by using your backup key.\n\nStack Wallet does not keep nor is able to restore your backup key or your wallet.\n\nPLEASE SAVE YOUR BACKUP KEY.",
+                  style: STextStyles.baseXS(context).copyWith(
                     color: Theme.of(context)
                         .extension<StackColors>()!
-                        .accentColorDark),
-              ),
-            ),
-            const SizedBox(
-              height: 12,
-            ),
-            TextButton(
-              style: Theme.of(context)
-                  .extension<StackColors>()!
-                  .getPrimaryEnabledButtonColor(context),
-              onPressed: () async {
-                final manager = ref
-                    .read(walletsChangeNotifierProvider)
-                    .getManager(walletId);
-                final mnemonic = await manager.mnemonic;
-                Navigator.of(context).pushNamed(
-                  DeleteWalletRecoveryPhraseView.routeName,
-                  arguments: Tuple2(
-                    manager,
-                    mnemonic,
+                        .warningForeground,
                   ),
-                );
-              },
-              child: Text(
-                "View Backup Key",
-                style: STextStyles.button(context),
+                ),
               ),
-            ),
-            const SizedBox(
-              height: 16,
-            ),
-          ],
+              const Spacer(),
+              TextButton(
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getSecondaryEnabledButtonColor(context),
+                onPressed: () {
+                  Navigator.pop(context);
+                },
+                child: Text(
+                  "Cancel",
+                  style: STextStyles.button(context).copyWith(
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark),
+                ),
+              ),
+              const SizedBox(
+                height: 12,
+              ),
+              TextButton(
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getPrimaryEnabledButtonColor(context),
+                onPressed: () async {
+                  final manager = ref
+                      .read(walletsChangeNotifierProvider)
+                      .getManager(walletId);
+                  final mnemonic = await manager.mnemonic;
+                  Navigator.of(context).pushNamed(
+                    DeleteWalletRecoveryPhraseView.routeName,
+                    arguments: Tuple2(
+                      manager,
+                      mnemonic,
+                    ),
+                  );
+                },
+                child: Text(
+                  "View Backup Key",
+                  style: STextStyles.button(context),
+                ),
+              ),
+              const SizedBox(
+                height: 16,
+              ),
+            ],
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart
index e9eb14868..f76422750 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart
@@ -6,13 +6,13 @@ import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_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';
 
-import 'package:stackwallet/utilities/util.dart';
-
 class RenameWalletView extends ConsumerStatefulWidget {
   const RenameWalletView({
     Key? key,
@@ -53,102 +53,104 @@ class _RenameWalletViewState extends ConsumerState<RenameWalletView> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Rename wallet",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Rename wallet",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.all(16),
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            ClipRRect(
-              borderRadius: BorderRadius.circular(
-                Constants.size.circularBorderRadius,
-              ),
-              child: TextField(
-                autocorrect: Util.isDesktop ? false : true,
-                enableSuggestions: Util.isDesktop ? false : true,
-                controller: _controller,
-                focusNode: _focusNode,
-                style: STextStyles.field(context),
-                onChanged: (_) => setState(() {}),
-                decoration: standardInputDecoration(
-                  "Wallet name",
-                  _focusNode,
-                  context,
-                ).copyWith(
-                  suffixIcon: _controller.text.isNotEmpty
-                      ? Padding(
-                          padding: const EdgeInsets.only(right: 0),
-                          child: UnconstrainedBox(
-                            child: Row(
-                              children: [
-                                TextFieldIconButton(
-                                  child: const XIcon(),
-                                  onTap: () async {
-                                    setState(() {
-                                      _controller.text = "";
-                                    });
-                                  },
-                                ),
-                              ],
+        body: Padding(
+          padding: const EdgeInsets.all(16),
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.stretch,
+            children: [
+              ClipRRect(
+                borderRadius: BorderRadius.circular(
+                  Constants.size.circularBorderRadius,
+                ),
+                child: TextField(
+                  autocorrect: Util.isDesktop ? false : true,
+                  enableSuggestions: Util.isDesktop ? false : true,
+                  controller: _controller,
+                  focusNode: _focusNode,
+                  style: STextStyles.field(context),
+                  onChanged: (_) => setState(() {}),
+                  decoration: standardInputDecoration(
+                    "Wallet name",
+                    _focusNode,
+                    context,
+                  ).copyWith(
+                    suffixIcon: _controller.text.isNotEmpty
+                        ? Padding(
+                            padding: const EdgeInsets.only(right: 0),
+                            child: UnconstrainedBox(
+                              child: Row(
+                                children: [
+                                  TextFieldIconButton(
+                                    child: const XIcon(),
+                                    onTap: () async {
+                                      setState(() {
+                                        _controller.text = "";
+                                      });
+                                    },
+                                  ),
+                                ],
+                              ),
                             ),
-                          ),
-                        )
-                      : null,
+                          )
+                        : null,
+                  ),
                 ),
               ),
-            ),
-            const Spacer(),
-            TextButton(
-              style: Theme.of(context)
-                  .extension<StackColors>()!
-                  .getPrimaryEnabledButtonColor(context),
-              onPressed: () async {
-                final newName = _controller.text;
-                final success = await ref
-                    .read(walletsServiceChangeNotifierProvider)
-                    .renameWallet(
-                      from: originalName,
-                      to: newName,
-                      shouldNotifyListeners: true,
-                    );
+              const Spacer(),
+              TextButton(
+                style: Theme.of(context)
+                    .extension<StackColors>()!
+                    .getPrimaryEnabledButtonColor(context),
+                onPressed: () async {
+                  final newName = _controller.text;
+                  final success = await ref
+                      .read(walletsServiceChangeNotifierProvider)
+                      .renameWallet(
+                        from: originalName,
+                        to: newName,
+                        shouldNotifyListeners: true,
+                      );
 
-                if (success) {
-                  ref
-                      .read(walletsChangeNotifierProvider)
-                      .getManager(walletId)
-                      .walletName = newName;
-                  Navigator.of(context).pop();
-                  showFloatingFlushBar(
-                    type: FlushBarType.success,
-                    message: "Wallet renamed",
-                    context: context,
-                  );
-                } else {
-                  showFloatingFlushBar(
-                    type: FlushBarType.warning,
-                    message: "Wallet named \"$newName\" already exists",
-                    context: context,
-                  );
-                }
-              },
-              child: Text(
-                "Save",
-                style: STextStyles.button(context),
+                  if (success) {
+                    ref
+                        .read(walletsChangeNotifierProvider)
+                        .getManager(walletId)
+                        .walletName = newName;
+                    Navigator.of(context).pop();
+                    showFloatingFlushBar(
+                      type: FlushBarType.success,
+                      message: "Wallet renamed",
+                      context: context,
+                    );
+                  } else {
+                    showFloatingFlushBar(
+                      type: FlushBarType.warning,
+                      message: "Wallet named \"$newName\" already exists",
+                      context: context,
+                    );
+                  }
+                },
+                child: Text(
+                  "Save",
+                  style: STextStyles.button(context),
+                ),
               ),
-            ),
-          ],
+            ],
+          ),
         ),
       ),
     );
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart
index 52aa6027a..a9c0f92af 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart
@@ -8,6 +8,7 @@ import 'package:stackwallet/route_generator.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/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -24,149 +25,151 @@ class WalletSettingsWalletSettingsView extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    return Scaffold(
-      backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-      appBar: AppBar(
-        leading: AppBarBackButton(
-          onPressed: () {
-            Navigator.of(context).pop();
-          },
+    return Background(
+      child: Scaffold(
+        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
+        appBar: AppBar(
+          leading: AppBarBackButton(
+            onPressed: () {
+              Navigator.of(context).pop();
+            },
+          ),
+          title: Text(
+            "Wallet settings",
+            style: STextStyles.navBarTitle(context),
+          ),
         ),
-        title: Text(
-          "Wallet settings",
-          style: STextStyles.navBarTitle(context),
-        ),
-      ),
-      body: Padding(
-        padding: const EdgeInsets.only(
-          top: 12,
-          left: 16,
-          right: 16,
-        ),
-        child: SingleChildScrollView(
-          child: Column(
-            crossAxisAlignment: CrossAxisAlignment.stretch,
-            children: [
-              RoundedWhiteContainer(
-                padding: const EdgeInsets.all(0),
-                child: RawMaterialButton(
-                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                  shape: RoundedRectangleBorder(
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
-                    ),
-                  ),
-                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-                  onPressed: () {
-                    Navigator.of(context).pushNamed(
-                      RenameWalletView.routeName,
-                      arguments: walletId,
-                    );
-                  },
-                  child: Padding(
-                    padding: const EdgeInsets.symmetric(
-                      horizontal: 12.0,
-                      vertical: 20,
-                    ),
-                    child: Row(
-                      children: [
-                        Text(
-                          "Rename wallet",
-                          style: STextStyles.titleBold12(context),
-                        ),
-                      ],
-                    ),
-                  ),
-                ),
-              ),
-              const SizedBox(
-                height: 8,
-              ),
-              RoundedWhiteContainer(
-                padding: const EdgeInsets.all(0),
-                child: RawMaterialButton(
-                  // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-                  shape: RoundedRectangleBorder(
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
-                    ),
-                  ),
-                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+        body: Padding(
+          padding: const EdgeInsets.only(
+            top: 12,
+            left: 16,
+            right: 16,
+          ),
+          child: SingleChildScrollView(
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.stretch,
+              children: [
+                RoundedWhiteContainer(
                   padding: const EdgeInsets.all(0),
-                  onPressed: () {
-                    showDialog(
-                      barrierDismissible: true,
-                      context: context,
-                      builder: (_) => StackDialog(
-                        title:
-                            "Do you want to delete ${ref.read(walletsChangeNotifierProvider).getManager(walletId).walletName}?",
-                        leftButton: TextButton(
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getSecondaryEnabledButtonColor(context),
-                          onPressed: () {
-                            Navigator.pop(context);
-                          },
-                          child: Text(
-                            "Cancel",
-                            style: STextStyles.button(context).copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorDark),
-                          ),
-                        ),
-                        rightButton: TextButton(
-                          style: Theme.of(context)
-                              .extension<StackColors>()!
-                              .getPrimaryEnabledButtonColor(context),
-                          onPressed: () {
-                            Navigator.pop(context);
-                            Navigator.push(
-                              context,
-                              RouteGenerator.getRoute(
-                                shouldUseMaterialRoute:
-                                    RouteGenerator.useMaterialPageRoute,
-                                builder: (_) => LockscreenView(
-                                  routeOnSuccessArguments: walletId,
-                                  showBackButton: true,
-                                  routeOnSuccess:
-                                      DeleteWalletWarningView.routeName,
-                                  biometricsCancelButtonString: "CANCEL",
-                                  biometricsLocalizedReason:
-                                      "Authenticate to delete wallet",
-                                  biometricsAuthenticationTitle:
-                                      "Delete wallet",
-                                ),
-                                settings: const RouteSettings(
-                                    name: "/deleteWalletLockscreen"),
-                              ),
-                            );
-                          },
-                          child: Text(
-                            "Delete",
-                            style: STextStyles.button(context),
-                          ),
-                        ),
+                  child: RawMaterialButton(
+                    // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
                       ),
-                    );
-                  },
-                  child: Padding(
-                    padding: const EdgeInsets.symmetric(
-                      horizontal: 12.0,
-                      vertical: 20,
                     ),
-                    child: Row(
-                      children: [
-                        Text(
-                          "Delete wallet",
-                          style: STextStyles.titleBold12(context),
-                        ),
-                      ],
+                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                    onPressed: () {
+                      Navigator.of(context).pushNamed(
+                        RenameWalletView.routeName,
+                        arguments: walletId,
+                      );
+                    },
+                    child: Padding(
+                      padding: const EdgeInsets.symmetric(
+                        horizontal: 12.0,
+                        vertical: 20,
+                      ),
+                      child: Row(
+                        children: [
+                          Text(
+                            "Rename wallet",
+                            style: STextStyles.titleBold12(context),
+                          ),
+                        ],
+                      ),
                     ),
                   ),
                 ),
-              ),
-            ],
+                const SizedBox(
+                  height: 8,
+                ),
+                RoundedWhiteContainer(
+                  padding: const EdgeInsets.all(0),
+                  child: RawMaterialButton(
+                    // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
+                    shape: RoundedRectangleBorder(
+                      borderRadius: BorderRadius.circular(
+                        Constants.size.circularBorderRadius,
+                      ),
+                    ),
+                    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+                    padding: const EdgeInsets.all(0),
+                    onPressed: () {
+                      showDialog(
+                        barrierDismissible: true,
+                        context: context,
+                        builder: (_) => StackDialog(
+                          title:
+                              "Do you want to delete ${ref.read(walletsChangeNotifierProvider).getManager(walletId).walletName}?",
+                          leftButton: TextButton(
+                            style: Theme.of(context)
+                                .extension<StackColors>()!
+                                .getSecondaryEnabledButtonColor(context),
+                            onPressed: () {
+                              Navigator.pop(context);
+                            },
+                            child: Text(
+                              "Cancel",
+                              style: STextStyles.button(context).copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .accentColorDark),
+                            ),
+                          ),
+                          rightButton: TextButton(
+                            style: Theme.of(context)
+                                .extension<StackColors>()!
+                                .getPrimaryEnabledButtonColor(context),
+                            onPressed: () {
+                              Navigator.pop(context);
+                              Navigator.push(
+                                context,
+                                RouteGenerator.getRoute(
+                                  shouldUseMaterialRoute:
+                                      RouteGenerator.useMaterialPageRoute,
+                                  builder: (_) => LockscreenView(
+                                    routeOnSuccessArguments: walletId,
+                                    showBackButton: true,
+                                    routeOnSuccess:
+                                        DeleteWalletWarningView.routeName,
+                                    biometricsCancelButtonString: "CANCEL",
+                                    biometricsLocalizedReason:
+                                        "Authenticate to delete wallet",
+                                    biometricsAuthenticationTitle:
+                                        "Delete wallet",
+                                  ),
+                                  settings: const RouteSettings(
+                                      name: "/deleteWalletLockscreen"),
+                                ),
+                              );
+                            },
+                            child: Text(
+                              "Delete",
+                              style: STextStyles.button(context),
+                            ),
+                          ),
+                        ),
+                      );
+                    },
+                    child: Padding(
+                      padding: const EdgeInsets.symmetric(
+                        horizontal: 12.0,
+                        vertical: 20,
+                      ),
+                      child: Row(
+                        children: [
+                          Text(
+                            "Delete wallet",
+                            style: STextStyles.titleBold12(context),
+                          ),
+                        ],
+                      ),
+                    ),
+                  ),
+                ),
+              ],
+            ),
           ),
         ),
       ),
diff --git a/lib/pages/wallet_view/transaction_views/edit_note_view.dart b/lib/pages/wallet_view/transaction_views/edit_note_view.dart
index 4baaaffc9..e8d7b05f9 100644
--- a/lib/pages/wallet_view/transaction_views/edit_note_view.dart
+++ b/lib/pages/wallet_view/transaction_views/edit_note_view.dart
@@ -5,6 +5,8 @@ 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';
@@ -53,120 +55,141 @@ class _EditNoteViewState extends ConsumerState<EditNoteView> {
 
   @override
   Widget build(BuildContext context) {
-    return 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();
-                  }
-                },
+    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 note",
+                  style: STextStyles.navBarTitle(context),
+                ),
               ),
-              title: Text(
-                "Edit note",
-                style: STextStyles.navBarTitle(context),
-              ),
-            ),
-      body: MobileEditNoteScaffold(
-        child: Column(
-          crossAxisAlignment: CrossAxisAlignment.stretch,
-          children: [
-            if (isDesktop)
+        body: MobileEditNoteScaffold(
+          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 note",
+                        style: STextStyles.desktopH3(context),
+                      ),
+                      const DesktopDialogCloseButton(),
+                    ],
+                  ),
+                ),
               Padding(
-                padding: const EdgeInsets.only(
-                  left: 32,
-                  bottom: 12,
-                ),
-                child: Row(
-                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                  children: [
-                    Text(
-                      "Edit note",
-                      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: _noteController,
-                  style: isDesktop
-                      ? STextStyles.desktopTextExtraSmall(context).copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .textFieldActiveText,
-                          height: 1.8,
-                        )
-                      : STextStyles.field(context),
-                  focusNode: noteFieldFocusNode,
-                  decoration: standardInputDecoration(
-                    "Note",
-                    noteFieldFocusNode,
-                    context,
-                    desktopMed: isDesktop,
-                  ).copyWith(
-                    contentPadding: isDesktop
-                        ? const EdgeInsets.only(
-                            left: 16,
-                            top: 11,
-                            bottom: 12,
-                            right: 5,
+                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: _noteController,
+                    style: isDesktop
+                        ? STextStyles.desktopTextExtraSmall(context).copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textFieldActiveText,
+                            height: 1.8,
                           )
-                        : null,
-                    suffixIcon: _noteController.text.isNotEmpty
-                        ? Padding(
-                            padding: const EdgeInsets.only(right: 0),
-                            child: UnconstrainedBox(
-                              child: Row(
-                                children: [
-                                  TextFieldIconButton(
-                                    child: const XIcon(),
-                                    onTap: () async {
-                                      setState(() {
-                                        _noteController.text = "";
-                                      });
-                                    },
-                                  ),
-                                ],
+                        : STextStyles.field(context),
+                    focusNode: noteFieldFocusNode,
+                    decoration: standardInputDecoration(
+                      "Note",
+                      noteFieldFocusNode,
+                      context,
+                      desktopMed: isDesktop,
+                    ).copyWith(
+                      contentPadding: isDesktop
+                          ? const EdgeInsets.only(
+                              left: 16,
+                              top: 11,
+                              bottom: 12,
+                              right: 5,
+                            )
+                          : null,
+                      suffixIcon: _noteController.text.isNotEmpty
+                          ? Padding(
+                              padding: const EdgeInsets.only(right: 0),
+                              child: UnconstrainedBox(
+                                child: Row(
+                                  children: [
+                                    TextFieldIconButton(
+                                      child: const XIcon(),
+                                      onTap: () async {
+                                        setState(() {
+                                          _noteController.text = "";
+                                        });
+                                      },
+                                    ),
+                                  ],
+                                ),
                               ),
-                            ),
-                          )
-                        : null,
+                            )
+                          : null,
+                    ),
                   ),
                 ),
               ),
-            ),
-            // if (!isDesktop)
-            const Spacer(),
-            if (isDesktop)
-              Padding(
-                padding: const EdgeInsets.all(32),
-                child: PrimaryButton(
-                  label: "Save",
+              // if (!isDesktop)
+              const Spacer(),
+              if (isDesktop)
+                Padding(
+                  padding: const EdgeInsets.all(32),
+                  child: PrimaryButton(
+                    label: "Save",
+                    onPressed: () async {
+                      await ref
+                          .read(notesServiceChangeNotifierProvider(
+                              widget.walletId))
+                          .editOrAddNote(
+                            txid: widget.txid,
+                            note: _noteController.text,
+                          );
+                      if (mounted) {
+                        Navigator.of(context).pop();
+                      }
+                    },
+                  ),
+                ),
+              if (!isDesktop)
+                TextButton(
                   onPressed: () async {
                     await ref
                         .read(
@@ -179,30 +202,16 @@ class _EditNoteViewState extends ConsumerState<EditNoteView> {
                       Navigator.of(context).pop();
                     }
                   },
-                ),
-              ),
-            if (!isDesktop)
-              TextButton(
-                onPressed: () async {
-                  await ref
-                      .read(notesServiceChangeNotifierProvider(widget.walletId))
-                      .editOrAddNote(
-                        txid: widget.txid,
-                        note: _noteController.text,
-                      );
-                  if (mounted) {
-                    Navigator.of(context).pop();
-                  }
-                },
-                style: Theme.of(context)
-                    .extension<StackColors>()!
-                    .getPrimaryEnabledButtonColor(context),
-                child: Text(
-                  "Save",
-                  style: STextStyles.button(context),
-                ),
-              )
-          ],
+                  style: Theme.of(context)
+                      .extension<StackColors>()!
+                      .getPrimaryEnabledButtonColor(context),
+                  child: Text(
+                    "Save",
+                    style: STextStyles.button(context),
+                  ),
+                )
+            ],
+          ),
         ),
       ),
     );
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 c2a0590e4..738ef721b 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -25,6 +25,7 @@ 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/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
@@ -297,177 +298,290 @@ class _TransactionDetailsViewState
 
   @override
   Widget build(BuildContext context) {
-    return 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(Duration(milliseconds: 50));
-                  // }
-                  Navigator.of(context).pop();
-                },
-              ),
-              title: Text(
-                "Transaction details",
-                style: STextStyles.navBarTitle(context),
-              ),
-            ),
-      body: Padding(
-        padding: isDesktop
-            ? const EdgeInsets.only(left: 32)
-            : const EdgeInsets.all(12),
-        child: Column(
-          children: [
-            if (isDesktop)
-              Row(
-                mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                children: [
-                  Text(
-                    "Transaction details",
-                    style: STextStyles.desktopH3(context),
-                  ),
-                  const DesktopDialogCloseButton(),
-                ],
-              ),
-            Expanded(
-              child: Padding(
-                padding: isDesktop
-                    ? const EdgeInsets.only(
-                        right: 32,
-                        bottom: 32,
-                      )
-                    : const EdgeInsets.all(0),
-                child: ConditionalParent(
-                  condition: isDesktop,
-                  builder: (child) {
-                    return RoundedWhiteContainer(
-                      borderColor: isDesktop
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .background
-                          : null,
-                      padding: const EdgeInsets.all(0),
-                      child: child,
-                    );
+    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(Duration(milliseconds: 50));
+                    // }
+                    Navigator.of(context).pop();
                   },
-                  child: SingleChildScrollView(
-                    primary: isDesktop ? false : null,
-                    child: Padding(
-                      padding: isDesktop
-                          ? const EdgeInsets.all(0)
-                          : const EdgeInsets.all(4),
-                      child: Column(
-                        crossAxisAlignment: CrossAxisAlignment.stretch,
-                        children: [
-                          RoundedWhiteContainer(
-                            padding: isDesktop
-                                ? const EdgeInsets.all(0)
-                                : const EdgeInsets.all(12),
-                            child: Container(
-                              decoration: isDesktop
-                                  ? BoxDecoration(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .background,
-                                      borderRadius: BorderRadius.vertical(
-                                        top: Radius.circular(
-                                          Constants.size.circularBorderRadius,
+                ),
+                title: Text(
+                  "Transaction details",
+                  style: STextStyles.navBarTitle(context),
+                ),
+              ),
+        body: Padding(
+          padding: isDesktop
+              ? const EdgeInsets.only(left: 32)
+              : const EdgeInsets.all(12),
+          child: Column(
+            children: [
+              if (isDesktop)
+                Row(
+                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                  children: [
+                    Text(
+                      "Transaction details",
+                      style: STextStyles.desktopH3(context),
+                    ),
+                    const DesktopDialogCloseButton(),
+                  ],
+                ),
+              Expanded(
+                child: Padding(
+                  padding: isDesktop
+                      ? const EdgeInsets.only(
+                          right: 32,
+                          bottom: 32,
+                        )
+                      : const EdgeInsets.all(0),
+                  child: ConditionalParent(
+                    condition: isDesktop,
+                    builder: (child) {
+                      return RoundedWhiteContainer(
+                        borderColor: isDesktop
+                            ? Theme.of(context)
+                                .extension<StackColors>()!
+                                .background
+                            : null,
+                        padding: const EdgeInsets.all(0),
+                        child: child,
+                      );
+                    },
+                    child: SingleChildScrollView(
+                      primary: isDesktop ? false : null,
+                      child: Padding(
+                        padding: isDesktop
+                            ? const EdgeInsets.all(0)
+                            : const EdgeInsets.all(4),
+                        child: Column(
+                          crossAxisAlignment: CrossAxisAlignment.stretch,
+                          children: [
+                            RoundedWhiteContainer(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(0)
+                                  : const EdgeInsets.all(12),
+                              child: Container(
+                                decoration: isDesktop
+                                    ? BoxDecoration(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .background,
+                                        borderRadius: BorderRadius.vertical(
+                                          top: Radius.circular(
+                                            Constants.size.circularBorderRadius,
+                                          ),
                                         ),
-                                      ),
-                                    )
-                                  : null,
-                              child: Padding(
-                                padding: isDesktop
-                                    ? const EdgeInsets.all(12)
-                                    : const EdgeInsets.all(0),
-                                child: Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
-                                  children: [
-                                    if (isDesktop)
-                                      Row(
-                                        children: [
-                                          TxIcon(
-                                            transaction: _transaction,
-                                          ),
-                                          const SizedBox(
-                                            width: 16,
-                                          ),
-                                          SelectableText(
-                                            _transaction.isCancelled
-                                                ? "Cancelled"
-                                                : whatIsIt(_transaction.txType),
-                                            style:
-                                                STextStyles.desktopTextMedium(
-                                                    context),
-                                          ),
-                                        ],
-                                      ),
-                                    Column(
-                                      crossAxisAlignment: isDesktop
-                                          ? CrossAxisAlignment.end
-                                          : CrossAxisAlignment.start,
-                                      children: [
-                                        SelectableText(
-                                          "$amountPrefix${Format.localizedStringAsFixed(
-                                            value: amount,
-                                            locale: ref.watch(
-                                              localeServiceChangeNotifierProvider
-                                                  .select(
-                                                      (value) => value.locale),
+                                      )
+                                    : null,
+                                child: Padding(
+                                  padding: isDesktop
+                                      ? const EdgeInsets.all(12)
+                                      : const EdgeInsets.all(0),
+                                  child: Row(
+                                    mainAxisAlignment:
+                                        MainAxisAlignment.spaceBetween,
+                                    children: [
+                                      if (isDesktop)
+                                        Row(
+                                          children: [
+                                            TxIcon(
+                                              transaction: _transaction,
                                             ),
-                                            decimalPlaces:
-                                                Constants.decimalPlacesForCoin(
-                                                    coin),
-                                          )} ${coin.ticker}",
-                                          style: isDesktop
-                                              ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .textDark,
-                                                )
-                                              : STextStyles.titleBold12(
-                                                  context),
+                                            const SizedBox(
+                                              width: 16,
+                                            ),
+                                            SelectableText(
+                                              _transaction.isCancelled
+                                                  ? "Cancelled"
+                                                  : whatIsIt(
+                                                      _transaction.txType),
+                                              style:
+                                                  STextStyles.desktopTextMedium(
+                                                      context),
+                                            ),
+                                          ],
                                         ),
-                                        const SizedBox(
-                                          height: 2,
-                                        ),
-                                        if (ref.watch(
-                                            prefsChangeNotifierProvider.select(
-                                                (value) =>
-                                                    value.externalCalls)))
+                                      Column(
+                                        crossAxisAlignment: isDesktop
+                                            ? CrossAxisAlignment.end
+                                            : CrossAxisAlignment.start,
+                                        children: [
                                           SelectableText(
                                             "$amountPrefix${Format.localizedStringAsFixed(
-                                              value: amount *
-                                                  ref.watch(
-                                                    priceAnd24hChangeNotifierProvider
-                                                        .select((value) => value
-                                                            .getPrice(coin)
-                                                            .item1),
-                                                  ),
+                                              value: amount,
                                               locale: ref.watch(
                                                 localeServiceChangeNotifierProvider
                                                     .select((value) =>
                                                         value.locale),
                                               ),
-                                              decimalPlaces: 2,
-                                            )} ${ref.watch(
+                                              decimalPlaces: Constants
+                                                  .decimalPlacesForCoin(coin),
+                                            )} ${coin.ticker}",
+                                            style: isDesktop
+                                                ? STextStyles
+                                                        .desktopTextExtraExtraSmall(
+                                                            context)
+                                                    .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark,
+                                                  )
+                                                : STextStyles.titleBold12(
+                                                    context),
+                                          ),
+                                          const SizedBox(
+                                            height: 2,
+                                          ),
+                                          if (ref.watch(
                                               prefsChangeNotifierProvider
-                                                  .select(
-                                                (value) => value.currency,
-                                              ),
-                                            )}",
+                                                  .select((value) =>
+                                                      value.externalCalls)))
+                                            SelectableText(
+                                              "$amountPrefix${Format.localizedStringAsFixed(
+                                                value: amount *
+                                                    ref.watch(
+                                                      priceAnd24hChangeNotifierProvider
+                                                          .select((value) =>
+                                                              value
+                                                                  .getPrice(
+                                                                      coin)
+                                                                  .item1),
+                                                    ),
+                                                locale: ref.watch(
+                                                  localeServiceChangeNotifierProvider
+                                                      .select((value) =>
+                                                          value.locale),
+                                                ),
+                                                decimalPlaces: 2,
+                                              )} ${ref.watch(
+                                                prefsChangeNotifierProvider
+                                                    .select(
+                                                  (value) => value.currency,
+                                                ),
+                                              )}",
+                                              style: isDesktop
+                                                  ? STextStyles
+                                                      .desktopTextExtraExtraSmall(
+                                                          context)
+                                                  : STextStyles.itemSubtitle(
+                                                      context),
+                                            ),
+                                        ],
+                                      ),
+                                      if (!isDesktop)
+                                        TxIcon(
+                                          transaction: _transaction,
+                                        ),
+                                    ],
+                                  ),
+                                ),
+                              ),
+                            ),
+
+                            isDesktop
+                                ? const _Divider()
+                                : const SizedBox(
+                                    height: 12,
+                                  ),
+                            RoundedWhiteContainer(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(16)
+                                  : const EdgeInsets.all(12),
+                              child: Row(
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
+                                children: [
+                                  Text(
+                                    "Status",
+                                    style: isDesktop
+                                        ? STextStyles
+                                            .desktopTextExtraExtraSmall(context)
+                                        : STextStyles.itemSubtitle(context),
+                                  ),
+                                  // Flexible(
+                                  //   child: FittedBox(
+                                  //     fit: BoxFit.scaleDown,
+                                  //     child:
+                                  SelectableText(
+                                    _transaction.isCancelled
+                                        ? "Cancelled"
+                                        : whatIsIt(_transaction.txType),
+                                    style: isDesktop
+                                        ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            .copyWith(
+                                            color: _transaction.txType == "Sent"
+                                                ? Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .accentColorOrange
+                                                : Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .accentColorGreen,
+                                          )
+                                        : STextStyles.itemSubtitle12(context),
+                                  ),
+                                  //   ),
+                                  // ),
+                                ],
+                              ),
+                            ),
+                            if (!((coin == Coin.monero ||
+                                        coin == Coin.wownero) &&
+                                    _transaction.txType.toLowerCase() ==
+                                        "sent") &&
+                                !((coin == Coin.firo ||
+                                        coin == Coin.firoTestNet) &&
+                                    _transaction.subType == "mint"))
+                              isDesktop
+                                  ? const _Divider()
+                                  : const SizedBox(
+                                      height: 12,
+                                    ),
+                            if (!((coin == Coin.monero ||
+                                        coin == Coin.wownero) &&
+                                    _transaction.txType.toLowerCase() ==
+                                        "sent") &&
+                                !((coin == Coin.firo ||
+                                        coin == Coin.firoTestNet) &&
+                                    _transaction.subType == "mint"))
+                              RoundedWhiteContainer(
+                                padding: isDesktop
+                                    ? const EdgeInsets.all(16)
+                                    : const EdgeInsets.all(12),
+                                child: Row(
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Expanded(
+                                      child: Column(
+                                        crossAxisAlignment:
+                                            CrossAxisAlignment.start,
+                                        children: [
+                                          Text(
+                                            _transaction.txType.toLowerCase() ==
+                                                    "sent"
+                                                ? "Sent to"
+                                                : "Receiving address",
                                             style: isDesktop
                                                 ? STextStyles
                                                     .desktopTextExtraExtraSmall(
@@ -475,81 +589,192 @@ class _TransactionDetailsViewState
                                                 : STextStyles.itemSubtitle(
                                                     context),
                                           ),
-                                      ],
+                                          const SizedBox(
+                                            height: 8,
+                                          ),
+                                          _transaction.txType.toLowerCase() ==
+                                                  "received"
+                                              ? FutureBuilder(
+                                                  future: fetchContactNameFor(
+                                                      _transaction.address),
+                                                  builder: (builderContext,
+                                                      AsyncSnapshot<String>
+                                                          snapshot) {
+                                                    String
+                                                        addressOrContactName =
+                                                        _transaction.address;
+                                                    if (snapshot.connectionState ==
+                                                            ConnectionState
+                                                                .done &&
+                                                        snapshot.hasData) {
+                                                      addressOrContactName =
+                                                          snapshot.data!;
+                                                    }
+                                                    return SelectableText(
+                                                      addressOrContactName,
+                                                      style: isDesktop
+                                                          ? STextStyles
+                                                                  .desktopTextExtraExtraSmall(
+                                                                      context)
+                                                              .copyWith(
+                                                              color: Theme.of(
+                                                                      context)
+                                                                  .extension<
+                                                                      StackColors>()!
+                                                                  .textDark,
+                                                            )
+                                                          : STextStyles
+                                                              .itemSubtitle12(
+                                                                  context),
+                                                    );
+                                                  },
+                                                )
+                                              : SelectableText(
+                                                  _transaction.address,
+                                                  style: isDesktop
+                                                      ? STextStyles
+                                                              .desktopTextExtraExtraSmall(
+                                                                  context)
+                                                          .copyWith(
+                                                          color: Theme.of(
+                                                                  context)
+                                                              .extension<
+                                                                  StackColors>()!
+                                                              .textDark,
+                                                        )
+                                                      : STextStyles
+                                                          .itemSubtitle12(
+                                                              context),
+                                                ),
+                                        ],
+                                      ),
                                     ),
-                                    if (!isDesktop)
-                                      TxIcon(
-                                        transaction: _transaction,
+                                    if (isDesktop)
+                                      IconCopyButton(
+                                        data: _transaction.address,
                                       ),
                                   ],
                                 ),
                               ),
-                            ),
-                          ),
-
-                          isDesktop
-                              ? const _Divider()
-                              : const SizedBox(
-                                  height: 12,
-                                ),
-                          RoundedWhiteContainer(
-                            padding: isDesktop
-                                ? const EdgeInsets.all(16)
-                                : const EdgeInsets.all(12),
-                            child: Row(
-                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                              children: [
-                                Text(
-                                  "Status",
-                                  style: isDesktop
-                                      ? STextStyles.desktopTextExtraExtraSmall(
-                                          context)
-                                      : STextStyles.itemSubtitle(context),
-                                ),
-                                // Flexible(
-                                //   child: FittedBox(
-                                //     fit: BoxFit.scaleDown,
-                                //     child:
-                                SelectableText(
-                                  _transaction.isCancelled
-                                      ? "Cancelled"
-                                      : whatIsIt(_transaction.txType),
-                                  style: isDesktop
-                                      ? STextStyles.desktopTextExtraExtraSmall(
-                                              context)
-                                          .copyWith(
-                                          color: _transaction.txType == "Sent"
-                                              ? Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .accentColorOrange
-                                              : Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .accentColorGreen,
-                                        )
-                                      : STextStyles.itemSubtitle12(context),
-                                ),
-                                //   ),
-                                // ),
-                              ],
-                            ),
-                          ),
-                          if (!((coin == Coin.monero || coin == Coin.wownero) &&
-                                  _transaction.txType.toLowerCase() ==
-                                      "sent") &&
-                              !((coin == Coin.firo ||
-                                      coin == Coin.firoTestNet) &&
-                                  _transaction.subType == "mint"))
                             isDesktop
                                 ? const _Divider()
                                 : const SizedBox(
                                     height: 12,
                                   ),
-                          if (!((coin == Coin.monero || coin == Coin.wownero) &&
-                                  _transaction.txType.toLowerCase() ==
-                                      "sent") &&
-                              !((coin == Coin.firo ||
-                                      coin == Coin.firoTestNet) &&
-                                  _transaction.subType == "mint"))
+
+                            RoundedWhiteContainer(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(16)
+                                  : const EdgeInsets.all(12),
+                              child: Column(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Row(
+                                    mainAxisAlignment:
+                                        MainAxisAlignment.spaceBetween,
+                                    children: [
+                                      Text(
+                                        "Note",
+                                        style: isDesktop
+                                            ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            : STextStyles.itemSubtitle(context),
+                                      ),
+                                      isDesktop
+                                          ? IconPencilButton(
+                                              onPressed: () {
+                                                showDialog<void>(
+                                                  context: context,
+                                                  builder: (context) {
+                                                    return DesktopDialog(
+                                                      maxWidth: 580,
+                                                      maxHeight: 360,
+                                                      child: EditNoteView(
+                                                        txid: _transaction.txid,
+                                                        walletId: walletId,
+                                                        note: _note,
+                                                      ),
+                                                    );
+                                                  },
+                                                );
+                                              },
+                                            )
+                                          : GestureDetector(
+                                              onTap: () {
+                                                Navigator.of(context).pushNamed(
+                                                  EditNoteView.routeName,
+                                                  arguments: Tuple3(
+                                                    _transaction.txid,
+                                                    walletId,
+                                                    _note,
+                                                  ),
+                                                );
+                                              },
+                                              child: Row(
+                                                children: [
+                                                  SvgPicture.asset(
+                                                    Assets.svg.pencil,
+                                                    width: 10,
+                                                    height: 10,
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .infoItemIcons,
+                                                  ),
+                                                  const SizedBox(
+                                                    width: 4,
+                                                  ),
+                                                  Text(
+                                                    "Edit",
+                                                    style: STextStyles.link2(
+                                                        context),
+                                                  ),
+                                                ],
+                                              ),
+                                            ),
+                                    ],
+                                  ),
+                                  const SizedBox(
+                                    height: 8,
+                                  ),
+                                  FutureBuilder(
+                                    future: ref.watch(
+                                        notesServiceChangeNotifierProvider(
+                                                walletId)
+                                            .select((value) => value.getNoteFor(
+                                                txid: _transaction.txid))),
+                                    builder: (builderContext,
+                                        AsyncSnapshot<String> snapshot) {
+                                      if (snapshot.connectionState ==
+                                              ConnectionState.done &&
+                                          snapshot.hasData) {
+                                        _note = snapshot.data ?? "";
+                                      }
+                                      return SelectableText(
+                                        _note,
+                                        style: isDesktop
+                                            ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark,
+                                              )
+                                            : STextStyles.itemSubtitle12(
+                                                context),
+                                      );
+                                    },
+                                  ),
+                                ],
+                              ),
+                            ),
+                            isDesktop
+                                ? const _Divider()
+                                : const SizedBox(
+                                    height: 12,
+                                  ),
                             RoundedWhiteContainer(
                               padding: isDesktop
                                   ? const EdgeInsets.all(16)
@@ -558,6 +783,249 @@ class _TransactionDetailsViewState
                                 mainAxisAlignment:
                                     MainAxisAlignment.spaceBetween,
                                 crossAxisAlignment: CrossAxisAlignment.start,
+                                children: [
+                                  Column(
+                                    crossAxisAlignment:
+                                        CrossAxisAlignment.start,
+                                    children: [
+                                      Text(
+                                        "Date",
+                                        style: isDesktop
+                                            ? STextStyles
+                                                .desktopTextExtraExtraSmall(
+                                                    context)
+                                            : STextStyles.itemSubtitle(context),
+                                      ),
+                                      if (isDesktop)
+                                        const SizedBox(
+                                          height: 2,
+                                        ),
+                                      if (isDesktop)
+                                        SelectableText(
+                                          Format.extractDateFrom(
+                                            _transaction.timestamp,
+                                          ),
+                                          style: isDesktop
+                                              ? STextStyles
+                                                      .desktopTextExtraExtraSmall(
+                                                          context)
+                                                  .copyWith(
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark,
+                                                )
+                                              : STextStyles.itemSubtitle12(
+                                                  context),
+                                        ),
+                                    ],
+                                  ),
+                                  if (!isDesktop)
+                                    SelectableText(
+                                      Format.extractDateFrom(
+                                        _transaction.timestamp,
+                                      ),
+                                      style: isDesktop
+                                          ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              .copyWith(
+                                              color: Theme.of(context)
+                                                  .extension<StackColors>()!
+                                                  .textDark,
+                                            )
+                                          : STextStyles.itemSubtitle12(context),
+                                    ),
+                                  if (isDesktop)
+                                    IconCopyButton(
+                                      data: Format.extractDateFrom(
+                                        _transaction.timestamp,
+                                      ),
+                                    ),
+                                ],
+                              ),
+                            ),
+                            isDesktop
+                                ? const _Divider()
+                                : const SizedBox(
+                                    height: 12,
+                                  ),
+                            RoundedWhiteContainer(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(16)
+                                  : const EdgeInsets.all(12),
+                              child: Builder(builder: (context) {
+                                final feeString = showFeePending
+                                    ? _transaction.confirmedStatus
+                                        ? Format.localizedStringAsFixed(
+                                            value: fee,
+                                            locale: ref.watch(
+                                                localeServiceChangeNotifierProvider
+                                                    .select((value) =>
+                                                        value.locale)),
+                                            decimalPlaces:
+                                                Constants.decimalPlacesForCoin(
+                                                    coin))
+                                        : "Pending"
+                                    : Format.localizedStringAsFixed(
+                                        value: fee,
+                                        locale: ref.watch(
+                                            localeServiceChangeNotifierProvider
+                                                .select(
+                                                    (value) => value.locale)),
+                                        decimalPlaces:
+                                            Constants.decimalPlacesForCoin(coin));
+
+                                return Row(
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Column(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        Text(
+                                          "Transaction fee",
+                                          style: isDesktop
+                                              ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              : STextStyles.itemSubtitle(
+                                                  context),
+                                        ),
+                                        if (isDesktop)
+                                          const SizedBox(
+                                            height: 2,
+                                          ),
+                                        if (isDesktop)
+                                          SelectableText(
+                                            feeString,
+                                            style: isDesktop
+                                                ? STextStyles
+                                                        .desktopTextExtraExtraSmall(
+                                                            context)
+                                                    .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark,
+                                                  )
+                                                : STextStyles.itemSubtitle12(
+                                                    context),
+                                          ),
+                                      ],
+                                    ),
+                                    if (!isDesktop)
+                                      SelectableText(
+                                        feeString,
+                                        style: isDesktop
+                                            ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark,
+                                              )
+                                            : STextStyles.itemSubtitle12(
+                                                context),
+                                      ),
+                                    if (isDesktop)
+                                      IconCopyButton(data: feeString)
+                                  ],
+                                );
+                              }),
+                            ),
+                            isDesktop
+                                ? const _Divider()
+                                : const SizedBox(
+                                    height: 12,
+                                  ),
+                            RoundedWhiteContainer(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(16)
+                                  : const EdgeInsets.all(12),
+                              child: Builder(builder: (context) {
+                                final height = widget.coin != Coin.epicCash &&
+                                        _transaction.confirmedStatus
+                                    ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
+                                    : _transaction.confirmations > 0
+                                        ? "${_transaction.height}"
+                                        : "Pending";
+
+                                return Row(
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  children: [
+                                    Column(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        Text(
+                                          "Block height",
+                                          style: isDesktop
+                                              ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              : STextStyles.itemSubtitle(
+                                                  context),
+                                        ),
+                                        if (isDesktop)
+                                          const SizedBox(
+                                            height: 2,
+                                          ),
+                                        if (isDesktop)
+                                          SelectableText(
+                                            height,
+                                            style: isDesktop
+                                                ? STextStyles
+                                                        .desktopTextExtraExtraSmall(
+                                                            context)
+                                                    .copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark,
+                                                  )
+                                                : STextStyles.itemSubtitle12(
+                                                    context),
+                                          ),
+                                      ],
+                                    ),
+                                    if (!isDesktop)
+                                      SelectableText(
+                                        height,
+                                        style: isDesktop
+                                            ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                        context)
+                                                .copyWith(
+                                                color: Theme.of(context)
+                                                    .extension<StackColors>()!
+                                                    .textDark,
+                                              )
+                                            : STextStyles.itemSubtitle12(
+                                                context),
+                                      ),
+                                    if (isDesktop) IconCopyButton(data: height),
+                                  ],
+                                );
+                              }),
+                            ),
+                            isDesktop
+                                ? const _Divider()
+                                : const SizedBox(
+                                    height: 12,
+                                  ),
+                            RoundedWhiteContainer(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(16)
+                                  : const EdgeInsets.all(12),
+                              child: Row(
+                                crossAxisAlignment: CrossAxisAlignment.start,
+                                mainAxisAlignment:
+                                    MainAxisAlignment.spaceBetween,
                                 children: [
                                   Expanded(
                                     child: Column(
@@ -565,10 +1033,7 @@ class _TransactionDetailsViewState
                                           CrossAxisAlignment.start,
                                       children: [
                                         Text(
-                                          _transaction.txType.toLowerCase() ==
-                                                  "sent"
-                                              ? "Sent to"
-                                              : "Receiving address",
+                                          "Transaction ID",
                                           style: isDesktop
                                               ? STextStyles
                                                   .desktopTextExtraExtraSmall(
@@ -579,771 +1044,338 @@ class _TransactionDetailsViewState
                                         const SizedBox(
                                           height: 8,
                                         ),
-                                        _transaction.txType.toLowerCase() ==
-                                                "received"
-                                            ? FutureBuilder(
-                                                future: fetchContactNameFor(
-                                                    _transaction.address),
-                                                builder: (builderContext,
-                                                    AsyncSnapshot<String>
-                                                        snapshot) {
-                                                  String addressOrContactName =
-                                                      _transaction.address;
-                                                  if (snapshot.connectionState ==
-                                                          ConnectionState
-                                                              .done &&
-                                                      snapshot.hasData) {
-                                                    addressOrContactName =
-                                                        snapshot.data!;
-                                                  }
-                                                  return SelectableText(
-                                                    addressOrContactName,
-                                                    style: isDesktop
-                                                        ? STextStyles
-                                                                .desktopTextExtraExtraSmall(
-                                                                    context)
-                                                            .copyWith(
-                                                            color: Theme.of(
-                                                                    context)
-                                                                .extension<
-                                                                    StackColors>()!
-                                                                .textDark,
-                                                          )
-                                                        : STextStyles
-                                                            .itemSubtitle12(
-                                                                context),
-                                                  );
-                                                },
-                                              )
-                                            : SelectableText(
-                                                _transaction.address,
-                                                style: isDesktop
-                                                    ? STextStyles
-                                                            .desktopTextExtraExtraSmall(
-                                                                context)
-                                                        .copyWith(
-                                                        color: Theme.of(context)
-                                                            .extension<
-                                                                StackColors>()!
-                                                            .textDark,
-                                                      )
-                                                    : STextStyles
-                                                        .itemSubtitle12(
-                                                            context),
-                                              ),
+                                        // Flexible(
+                                        //   child: FittedBox(
+                                        //     fit: BoxFit.scaleDown,
+                                        //     child:
+                                        SelectableText(
+                                          _transaction.txid,
+                                          style: isDesktop
+                                              ? STextStyles
+                                                      .desktopTextExtraExtraSmall(
+                                                          context)
+                                                  .copyWith(
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark,
+                                                )
+                                              : STextStyles.itemSubtitle12(
+                                                  context),
+                                        ),
+                                        if (coin != Coin.epicCash)
+                                          const SizedBox(
+                                            height: 8,
+                                          ),
+                                        if (coin != Coin.epicCash)
+                                          BlueTextButton(
+                                            text: "Open in block explorer",
+                                            onTap: () async {
+                                              final uri =
+                                                  getBlockExplorerTransactionUrlFor(
+                                                coin: coin,
+                                                txid: _transaction.txid,
+                                              );
+
+                                              if (ref
+                                                      .read(
+                                                          prefsChangeNotifierProvider)
+                                                      .hideBlockExplorerWarning ==
+                                                  false) {
+                                                final shouldContinue =
+                                                    await showExplorerWarning(
+                                                        "${uri.scheme}://${uri.host}");
+
+                                                if (!shouldContinue) {
+                                                  return;
+                                                }
+                                              }
+
+                                              // ref
+                                              //     .read(
+                                              //         shouldShowLockscreenOnResumeStateProvider
+                                              //             .state)
+                                              //     .state = false;
+                                              try {
+                                                await launchUrl(
+                                                  uri,
+                                                  mode: LaunchMode
+                                                      .externalApplication,
+                                                );
+                                              } catch (_) {
+                                                unawaited(
+                                                  showDialog<void>(
+                                                    context: context,
+                                                    builder: (_) =>
+                                                        StackOkDialog(
+                                                      title:
+                                                          "Could not open in block explorer",
+                                                      message:
+                                                          "Failed to open \"${uri.toString()}\"",
+                                                    ),
+                                                  ),
+                                                );
+                                              } finally {
+                                                // Future<void>.delayed(
+                                                //   const Duration(seconds: 1),
+                                                //   () => ref
+                                                //       .read(
+                                                //           shouldShowLockscreenOnResumeStateProvider
+                                                //               .state)
+                                                //       .state = true,
+                                                // );
+                                              }
+                                            },
+                                          ),
+                                        //   ),
+                                        // ),
                                       ],
                                     ),
                                   ),
-                                  if (isDesktop)
-                                    IconCopyButton(
-                                      data: _transaction.address,
-                                    ),
-                                ],
-                              ),
-                            ),
-                          isDesktop
-                              ? const _Divider()
-                              : const SizedBox(
-                                  height: 12,
-                                ),
-
-                          RoundedWhiteContainer(
-                            padding: isDesktop
-                                ? const EdgeInsets.all(16)
-                                : const EdgeInsets.all(12),
-                            child: Column(
-                              crossAxisAlignment: CrossAxisAlignment.start,
-                              children: [
-                                Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
-                                  children: [
-                                    Text(
-                                      "Note",
-                                      style: isDesktop
-                                          ? STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          : STextStyles.itemSubtitle(context),
-                                    ),
-                                    isDesktop
-                                        ? IconPencilButton(
-                                            onPressed: () {
-                                              showDialog<void>(
-                                                context: context,
-                                                builder: (context) {
-                                                  return DesktopDialog(
-                                                    maxWidth: 580,
-                                                    maxHeight: 360,
-                                                    child: EditNoteView(
-                                                      txid: _transaction.txid,
-                                                      walletId: walletId,
-                                                      note: _note,
-                                                    ),
-                                                  );
-                                                },
-                                              );
-                                            },
-                                          )
-                                        : GestureDetector(
-                                            onTap: () {
-                                              Navigator.of(context).pushNamed(
-                                                EditNoteView.routeName,
-                                                arguments: Tuple3(
-                                                  _transaction.txid,
-                                                  walletId,
-                                                  _note,
-                                                ),
-                                              );
-                                            },
-                                            child: Row(
-                                              children: [
-                                                SvgPicture.asset(
-                                                  Assets.svg.pencil,
-                                                  width: 10,
-                                                  height: 10,
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .infoItemIcons,
-                                                ),
-                                                const SizedBox(
-                                                  width: 4,
-                                                ),
-                                                Text(
-                                                  "Edit",
-                                                  style: STextStyles.link2(
-                                                      context),
-                                                ),
-                                              ],
-                                            ),
-                                          ),
-                                  ],
-                                ),
-                                const SizedBox(
-                                  height: 8,
-                                ),
-                                FutureBuilder(
-                                  future: ref.watch(
-                                      notesServiceChangeNotifierProvider(
-                                              walletId)
-                                          .select((value) => value.getNoteFor(
-                                              txid: _transaction.txid))),
-                                  builder: (builderContext,
-                                      AsyncSnapshot<String> snapshot) {
-                                    if (snapshot.connectionState ==
-                                            ConnectionState.done &&
-                                        snapshot.hasData) {
-                                      _note = snapshot.data ?? "";
-                                    }
-                                    return SelectableText(
-                                      _note,
-                                      style: isDesktop
-                                          ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark,
-                                            )
-                                          : STextStyles.itemSubtitle12(context),
-                                    );
-                                  },
-                                ),
-                              ],
-                            ),
-                          ),
-                          isDesktop
-                              ? const _Divider()
-                              : const SizedBox(
-                                  height: 12,
-                                ),
-                          RoundedWhiteContainer(
-                            padding: isDesktop
-                                ? const EdgeInsets.all(16)
-                                : const EdgeInsets.all(12),
-                            child: Row(
-                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                              crossAxisAlignment: CrossAxisAlignment.start,
-                              children: [
-                                Column(
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Text(
-                                      "Date",
-                                      style: isDesktop
-                                          ? STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          : STextStyles.itemSubtitle(context),
-                                    ),
-                                    if (isDesktop)
-                                      const SizedBox(
-                                        height: 2,
-                                      ),
-                                    if (isDesktop)
-                                      SelectableText(
-                                        Format.extractDateFrom(
-                                          _transaction.timestamp,
-                                        ),
-                                        style: isDesktop
-                                            ? STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark,
-                                              )
-                                            : STextStyles.itemSubtitle12(
-                                                context),
-                                      ),
-                                  ],
-                                ),
-                                if (!isDesktop)
-                                  SelectableText(
-                                    Format.extractDateFrom(
-                                      _transaction.timestamp,
-                                    ),
-                                    style: isDesktop
-                                        ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            .copyWith(
-                                            color: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .textDark,
-                                          )
-                                        : STextStyles.itemSubtitle12(context),
-                                  ),
-                                if (isDesktop)
-                                  IconCopyButton(
-                                    data: Format.extractDateFrom(
-                                      _transaction.timestamp,
-                                    ),
-                                  ),
-                              ],
-                            ),
-                          ),
-                          isDesktop
-                              ? const _Divider()
-                              : const SizedBox(
-                                  height: 12,
-                                ),
-                          RoundedWhiteContainer(
-                            padding: isDesktop
-                                ? const EdgeInsets.all(16)
-                                : const EdgeInsets.all(12),
-                            child: Builder(builder: (context) {
-                              final feeString = showFeePending
-                                  ? _transaction.confirmedStatus
-                                      ? Format.localizedStringAsFixed(
-                                          value: fee,
-                                          locale: ref.watch(
-                                              localeServiceChangeNotifierProvider
-                                                  .select(
-                                                      (value) => value.locale)),
-                                          decimalPlaces:
-                                              Constants.decimalPlacesForCoin(
-                                                  coin))
-                                      : "Pending"
-                                  : Format.localizedStringAsFixed(
-                                      value: fee,
-                                      locale: ref.watch(
-                                          localeServiceChangeNotifierProvider
-                                              .select((value) => value.locale)),
-                                      decimalPlaces:
-                                          Constants.decimalPlacesForCoin(coin));
-
-                              return Row(
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
-                                crossAxisAlignment: CrossAxisAlignment.start,
-                                children: [
-                                  Column(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.start,
-                                    children: [
-                                      Text(
-                                        "Transaction fee",
-                                        style: isDesktop
-                                            ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            : STextStyles.itemSubtitle(context),
-                                      ),
-                                      if (isDesktop)
-                                        const SizedBox(
-                                          height: 2,
-                                        ),
-                                      if (isDesktop)
-                                        SelectableText(
-                                          feeString,
-                                          style: isDesktop
-                                              ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .textDark,
-                                                )
-                                              : STextStyles.itemSubtitle12(
-                                                  context),
-                                        ),
-                                    ],
-                                  ),
-                                  if (!isDesktop)
-                                    SelectableText(
-                                      feeString,
-                                      style: isDesktop
-                                          ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark,
-                                            )
-                                          : STextStyles.itemSubtitle12(context),
-                                    ),
-                                  if (isDesktop) IconCopyButton(data: feeString)
-                                ],
-                              );
-                            }),
-                          ),
-                          isDesktop
-                              ? const _Divider()
-                              : const SizedBox(
-                                  height: 12,
-                                ),
-                          RoundedWhiteContainer(
-                            padding: isDesktop
-                                ? const EdgeInsets.all(16)
-                                : const EdgeInsets.all(12),
-                            child: Builder(builder: (context) {
-                              final height = widget.coin != Coin.epicCash &&
-                                      _transaction.confirmedStatus
-                                  ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
-                                  : _transaction.confirmations > 0
-                                      ? "${_transaction.height}"
-                                      : "Pending";
-
-                              return Row(
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
-                                crossAxisAlignment: CrossAxisAlignment.start,
-                                children: [
-                                  Column(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.start,
-                                    children: [
-                                      Text(
-                                        "Block height",
-                                        style: isDesktop
-                                            ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            : STextStyles.itemSubtitle(context),
-                                      ),
-                                      if (isDesktop)
-                                        const SizedBox(
-                                          height: 2,
-                                        ),
-                                      if (isDesktop)
-                                        SelectableText(
-                                          height,
-                                          style: isDesktop
-                                              ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .textDark,
-                                                )
-                                              : STextStyles.itemSubtitle12(
-                                                  context),
-                                        ),
-                                    ],
-                                  ),
-                                  if (!isDesktop)
-                                    SelectableText(
-                                      height,
-                                      style: isDesktop
-                                          ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<StackColors>()!
-                                                  .textDark,
-                                            )
-                                          : STextStyles.itemSubtitle12(context),
-                                    ),
-                                  if (isDesktop) IconCopyButton(data: height),
-                                ],
-                              );
-                            }),
-                          ),
-                          isDesktop
-                              ? const _Divider()
-                              : const SizedBox(
-                                  height: 12,
-                                ),
-                          RoundedWhiteContainer(
-                            padding: isDesktop
-                                ? const EdgeInsets.all(16)
-                                : const EdgeInsets.all(12),
-                            child: Row(
-                              crossAxisAlignment: CrossAxisAlignment.start,
-                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                              children: [
-                                Expanded(
-                                  child: Column(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.start,
-                                    children: [
-                                      Text(
-                                        "Transaction ID",
-                                        style: isDesktop
-                                            ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            : STextStyles.itemSubtitle(context),
-                                      ),
-                                      const SizedBox(
-                                        height: 8,
-                                      ),
-                                      // Flexible(
-                                      //   child: FittedBox(
-                                      //     fit: BoxFit.scaleDown,
-                                      //     child:
-                                      SelectableText(
-                                        _transaction.txid,
-                                        style: isDesktop
-                                            ? STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark,
-                                              )
-                                            : STextStyles.itemSubtitle12(
-                                                context),
-                                      ),
-                                      if (coin != Coin.epicCash)
-                                        const SizedBox(
-                                          height: 8,
-                                        ),
-                                      if (coin != Coin.epicCash)
-                                        BlueTextButton(
-                                          text: "Open in block explorer",
-                                          onTap: () async {
-                                            final uri =
-                                                getBlockExplorerTransactionUrlFor(
-                                              coin: coin,
-                                              txid: _transaction.txid,
-                                            );
-
-                                            if (ref
-                                                    .read(
-                                                        prefsChangeNotifierProvider)
-                                                    .hideBlockExplorerWarning ==
-                                                false) {
-                                              final shouldContinue =
-                                                  await showExplorerWarning(
-                                                      "${uri.scheme}://${uri.host}");
-
-                                              if (!shouldContinue) {
-                                                return;
-                                              }
-                                            }
-
-                                            // ref
-                                            //     .read(
-                                            //         shouldShowLockscreenOnResumeStateProvider
-                                            //             .state)
-                                            //     .state = false;
-                                            try {
-                                              await launchUrl(
-                                                uri,
-                                                mode: LaunchMode
-                                                    .externalApplication,
-                                              );
-                                            } catch (_) {
-                                              unawaited(
-                                                showDialog<void>(
-                                                  context: context,
-                                                  builder: (_) => StackOkDialog(
-                                                    title:
-                                                        "Could not open in block explorer",
-                                                    message:
-                                                        "Failed to open \"${uri.toString()}\"",
-                                                  ),
-                                                ),
-                                              );
-                                            } finally {
-                                              // Future<void>.delayed(
-                                              //   const Duration(seconds: 1),
-                                              //   () => ref
-                                              //       .read(
-                                              //           shouldShowLockscreenOnResumeStateProvider
-                                              //               .state)
-                                              //       .state = true,
-                                              // );
-                                            }
-                                          },
-                                        ),
-                                      //   ),
-                                      // ),
-                                    ],
-                                  ),
-                                ),
-                                if (isDesktop)
-                                  const SizedBox(
-                                    width: 12,
-                                  ),
-                                if (isDesktop)
-                                  IconCopyButton(
-                                    data: _transaction.txid,
-                                  ),
-                              ],
-                            ),
-                          ),
-                          // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
-                          //     _transaction.subType == "mint")
-                          //   const SizedBox(
-                          //     height: 12,
-                          //   ),
-                          // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
-                          //     _transaction.subType == "mint")
-                          //   RoundedWhiteContainer(
-                          //     child: Column(
-                          //       crossAxisAlignment: CrossAxisAlignment.start,
-                          //       children: [
-                          //         Row(
-                          //           mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                          //           children: [
-                          //             Text(
-                          //               "Mint Transaction ID",
-                          //               style: STextStyles.itemSubtitle(context),
-                          //             ),
-                          //           ],
-                          //         ),
-                          //         const SizedBox(
-                          //           height: 8,
-                          //         ),
-                          //         // Flexible(
-                          //         //   child: FittedBox(
-                          //         //     fit: BoxFit.scaleDown,
-                          //         //     child:
-                          //         SelectableText(
-                          //           _transaction.otherData ?? "Unknown",
-                          //           style: STextStyles.itemSubtitle12(context),
-                          //         ),
-                          //         //   ),
-                          //         // ),
-                          //         const SizedBox(
-                          //           height: 8,
-                          //         ),
-                          //         BlueTextButton(
-                          //           text: "Open in block explorer",
-                          //           onTap: () async {
-                          //             final uri = getBlockExplorerTransactionUrlFor(
-                          //               coin: coin,
-                          //               txid: _transaction.otherData ?? "Unknown",
-                          //             );
-                          //             // ref
-                          //             //     .read(
-                          //             //         shouldShowLockscreenOnResumeStateProvider
-                          //             //             .state)
-                          //             //     .state = false;
-                          //             try {
-                          //               await launchUrl(
-                          //                 uri,
-                          //                 mode: LaunchMode.externalApplication,
-                          //               );
-                          //             } catch (_) {
-                          //               unawaited(showDialog<void>(
-                          //                 context: context,
-                          //                 builder: (_) => StackOkDialog(
-                          //                   title: "Could not open in block explorer",
-                          //                   message:
-                          //                       "Failed to open \"${uri.toString()}\"",
-                          //                 ),
-                          //               ));
-                          //             } finally {
-                          //               // Future<void>.delayed(
-                          //               //   const Duration(seconds: 1),
-                          //               //   () => ref
-                          //               //       .read(
-                          //               //           shouldShowLockscreenOnResumeStateProvider
-                          //               //               .state)
-                          //               //       .state = true,
-                          //               // );
-                          //             }
-                          //           },
-                          //         ),
-                          //       ],
-                          //     ),
-                          //   ),
-                          if (coin == Coin.epicCash)
-                            isDesktop
-                                ? const _Divider()
-                                : const SizedBox(
-                                    height: 12,
-                                  ),
-                          if (coin == Coin.epicCash)
-                            RoundedWhiteContainer(
-                              padding: isDesktop
-                                  ? const EdgeInsets.all(16)
-                                  : const EdgeInsets.all(12),
-                              child: Row(
-                                crossAxisAlignment: CrossAxisAlignment.start,
-                                mainAxisAlignment:
-                                    MainAxisAlignment.spaceBetween,
-                                children: [
-                                  Column(
-                                    crossAxisAlignment:
-                                        CrossAxisAlignment.start,
-                                    children: [
-                                      Text(
-                                        "Slate ID",
-                                        style: isDesktop
-                                            ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            : STextStyles.itemSubtitle(context),
-                                      ),
-                                      // Flexible(
-                                      //   child: FittedBox(
-                                      //     fit: BoxFit.scaleDown,
-                                      //     child:
-                                      SelectableText(
-                                        _transaction.slateId ?? "Unknown",
-                                        style: isDesktop
-                                            ? STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark,
-                                              )
-                                            : STextStyles.itemSubtitle12(
-                                                context),
-                                      ),
-                                      //   ),
-                                      // ),
-                                    ],
-                                  ),
                                   if (isDesktop)
                                     const SizedBox(
                                       width: 12,
                                     ),
                                   if (isDesktop)
                                     IconCopyButton(
-                                      data: _transaction.slateId ?? "Unknown",
+                                      data: _transaction.txid,
                                     ),
                                 ],
                               ),
                             ),
-                          if (!isDesktop)
-                            const SizedBox(
-                              height: 12,
-                            ),
-                        ],
+                            // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                            //     _transaction.subType == "mint")
+                            //   const SizedBox(
+                            //     height: 12,
+                            //   ),
+                            // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                            //     _transaction.subType == "mint")
+                            //   RoundedWhiteContainer(
+                            //     child: Column(
+                            //       crossAxisAlignment: CrossAxisAlignment.start,
+                            //       children: [
+                            //         Row(
+                            //           mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                            //           children: [
+                            //             Text(
+                            //               "Mint Transaction ID",
+                            //               style: STextStyles.itemSubtitle(context),
+                            //             ),
+                            //           ],
+                            //         ),
+                            //         const SizedBox(
+                            //           height: 8,
+                            //         ),
+                            //         // Flexible(
+                            //         //   child: FittedBox(
+                            //         //     fit: BoxFit.scaleDown,
+                            //         //     child:
+                            //         SelectableText(
+                            //           _transaction.otherData ?? "Unknown",
+                            //           style: STextStyles.itemSubtitle12(context),
+                            //         ),
+                            //         //   ),
+                            //         // ),
+                            //         const SizedBox(
+                            //           height: 8,
+                            //         ),
+                            //         BlueTextButton(
+                            //           text: "Open in block explorer",
+                            //           onTap: () async {
+                            //             final uri = getBlockExplorerTransactionUrlFor(
+                            //               coin: coin,
+                            //               txid: _transaction.otherData ?? "Unknown",
+                            //             );
+                            //             // ref
+                            //             //     .read(
+                            //             //         shouldShowLockscreenOnResumeStateProvider
+                            //             //             .state)
+                            //             //     .state = false;
+                            //             try {
+                            //               await launchUrl(
+                            //                 uri,
+                            //                 mode: LaunchMode.externalApplication,
+                            //               );
+                            //             } catch (_) {
+                            //               unawaited(showDialog<void>(
+                            //                 context: context,
+                            //                 builder: (_) => StackOkDialog(
+                            //                   title: "Could not open in block explorer",
+                            //                   message:
+                            //                       "Failed to open \"${uri.toString()}\"",
+                            //                 ),
+                            //               ));
+                            //             } finally {
+                            //               // Future<void>.delayed(
+                            //               //   const Duration(seconds: 1),
+                            //               //   () => ref
+                            //               //       .read(
+                            //               //           shouldShowLockscreenOnResumeStateProvider
+                            //               //               .state)
+                            //               //       .state = true,
+                            //               // );
+                            //             }
+                            //           },
+                            //         ),
+                            //       ],
+                            //     ),
+                            //   ),
+                            if (coin == Coin.epicCash)
+                              isDesktop
+                                  ? const _Divider()
+                                  : const SizedBox(
+                                      height: 12,
+                                    ),
+                            if (coin == Coin.epicCash)
+                              RoundedWhiteContainer(
+                                padding: isDesktop
+                                    ? const EdgeInsets.all(16)
+                                    : const EdgeInsets.all(12),
+                                child: Row(
+                                  crossAxisAlignment: CrossAxisAlignment.start,
+                                  mainAxisAlignment:
+                                      MainAxisAlignment.spaceBetween,
+                                  children: [
+                                    Column(
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        Text(
+                                          "Slate ID",
+                                          style: isDesktop
+                                              ? STextStyles
+                                                  .desktopTextExtraExtraSmall(
+                                                      context)
+                                              : STextStyles.itemSubtitle(
+                                                  context),
+                                        ),
+                                        // Flexible(
+                                        //   child: FittedBox(
+                                        //     fit: BoxFit.scaleDown,
+                                        //     child:
+                                        SelectableText(
+                                          _transaction.slateId ?? "Unknown",
+                                          style: isDesktop
+                                              ? STextStyles
+                                                      .desktopTextExtraExtraSmall(
+                                                          context)
+                                                  .copyWith(
+                                                  color: Theme.of(context)
+                                                      .extension<StackColors>()!
+                                                      .textDark,
+                                                )
+                                              : STextStyles.itemSubtitle12(
+                                                  context),
+                                        ),
+                                        //   ),
+                                        // ),
+                                      ],
+                                    ),
+                                    if (isDesktop)
+                                      const SizedBox(
+                                        width: 12,
+                                      ),
+                                    if (isDesktop)
+                                      IconCopyButton(
+                                        data: _transaction.slateId ?? "Unknown",
+                                      ),
+                                  ],
+                                ),
+                              ),
+                            if (!isDesktop)
+                              const SizedBox(
+                                height: 12,
+                              ),
+                          ],
+                        ),
                       ),
                     ),
                   ),
                 ),
               ),
-            ),
-          ],
+            ],
+          ),
         ),
-      ),
-      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
-      floatingActionButton: (coin == Coin.epicCash &&
-              _transaction.confirmedStatus == false &&
-              _transaction.isCancelled == false &&
-              _transaction.txType == "Sent")
-          ? SizedBox(
-              width: MediaQuery.of(context).size.width - 32,
-              child: TextButton(
-                style: ButtonStyle(
-                  backgroundColor: MaterialStateProperty.all<Color>(
-                    Theme.of(context).extension<StackColors>()!.textError,
+        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
+        floatingActionButton: (coin == Coin.epicCash &&
+                _transaction.confirmedStatus == false &&
+                _transaction.isCancelled == false &&
+                _transaction.txType == "Sent")
+            ? SizedBox(
+                width: MediaQuery.of(context).size.width - 32,
+                child: TextButton(
+                  style: ButtonStyle(
+                    backgroundColor: MaterialStateProperty.all<Color>(
+                      Theme.of(context).extension<StackColors>()!.textError,
+                    ),
                   ),
-                ),
-                onPressed: () async {
-                  final Manager manager = ref
-                      .read(walletsChangeNotifierProvider)
-                      .getManager(walletId);
+                  onPressed: () async {
+                    final Manager manager = ref
+                        .read(walletsChangeNotifierProvider)
+                        .getManager(walletId);
 
-                  if (manager.wallet is EpicCashWallet) {
-                    final String? id = _transaction.slateId;
-                    if (id == null) {
+                    if (manager.wallet is EpicCashWallet) {
+                      final String? id = _transaction.slateId;
+                      if (id == null) {
+                        unawaited(showFloatingFlushBar(
+                          type: FlushBarType.warning,
+                          message: "Could not find Epic transaction ID",
+                          context: context,
+                        ));
+                        return;
+                      }
+
+                      unawaited(showDialog<dynamic>(
+                        barrierDismissible: false,
+                        context: context,
+                        builder: (_) =>
+                            const CancellingTransactionProgressDialog(),
+                      ));
+
+                      final result = await (manager.wallet as EpicCashWallet)
+                          .cancelPendingTransactionAndPost(id);
+                      if (mounted) {
+                        // pop progress dialog
+                        Navigator.of(context).pop();
+
+                        if (result.isEmpty) {
+                          await showDialog<dynamic>(
+                            context: context,
+                            builder: (_) => StackOkDialog(
+                              title: "Transaction cancelled",
+                              onOkPressed: (_) {
+                                manager.refresh();
+                                Navigator.of(context).popUntil(
+                                    ModalRoute.withName(WalletView.routeName));
+                              },
+                            ),
+                          );
+                        } else {
+                          await showDialog<dynamic>(
+                            context: context,
+                            builder: (_) => StackOkDialog(
+                              title: "Failed to cancel transaction",
+                              message: result,
+                            ),
+                          );
+                        }
+                      }
+                    } else {
                       unawaited(showFloatingFlushBar(
                         type: FlushBarType.warning,
-                        message: "Could not find Epic transaction ID",
+                        message: "ERROR: Wallet type is not Epic Cash",
                         context: context,
                       ));
                       return;
                     }
-
-                    unawaited(showDialog<dynamic>(
-                      barrierDismissible: false,
-                      context: context,
-                      builder: (_) =>
-                          const CancellingTransactionProgressDialog(),
-                    ));
-
-                    final result = await (manager.wallet as EpicCashWallet)
-                        .cancelPendingTransactionAndPost(id);
-                    if (mounted) {
-                      // pop progress dialog
-                      Navigator.of(context).pop();
-
-                      if (result.isEmpty) {
-                        await showDialog<dynamic>(
-                          context: context,
-                          builder: (_) => StackOkDialog(
-                            title: "Transaction cancelled",
-                            onOkPressed: (_) {
-                              manager.refresh();
-                              Navigator.of(context).popUntil(
-                                  ModalRoute.withName(WalletView.routeName));
-                            },
-                          ),
-                        );
-                      } else {
-                        await showDialog<dynamic>(
-                          context: context,
-                          builder: (_) => StackOkDialog(
-                            title: "Failed to cancel transaction",
-                            message: result,
-                          ),
-                        );
-                      }
-                    }
-                  } else {
-                    unawaited(showFloatingFlushBar(
-                      type: FlushBarType.warning,
-                      message: "ERROR: Wallet type is not Epic Cash",
-                      context: context,
-                    ));
-                    return;
-                  }
-                },
-                child: Text(
-                  "Cancel Transaction",
-                  style: STextStyles.button(context),
+                  },
+                  child: Text(
+                    "Cancel Transaction",
+                    style: STextStyles.button(context),
+                  ),
                 ),
-              ),
-            )
-          : null,
+              )
+            : null,
+      ),
     );
   }
 }
diff --git a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
index 0b3fd3acb..7e1b53cbb 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
@@ -15,6 +15,7 @@ import 'package:stackwallet/utilities/format.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/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
@@ -428,42 +429,46 @@ class _TransactionSearchViewState
         ),
       );
     } else {
-      return Scaffold(
-        backgroundColor: Theme.of(context).extension<StackColors>()!.background,
-        appBar: AppBar(
+      return Background(
+        child: Scaffold(
           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();
-              }
-            },
+          appBar: 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(
+              "Transactions filter",
+              style: STextStyles.navBarTitle(context),
+            ),
           ),
-          title: Text(
-            "Transactions filter",
-            style: STextStyles.navBarTitle(context),
-          ),
-        ),
-        body: Padding(
-          padding: EdgeInsets.symmetric(
-            horizontal: Constants.size.standardPadding,
-          ),
-          child: LayoutBuilder(
-            builder: (context, constraints) {
-              return SingleChildScrollView(
-                child: ConstrainedBox(
-                  constraints: BoxConstraints(minHeight: constraints.maxHeight),
-                  child: IntrinsicHeight(
-                    child: _buildContent(context),
+          body: Padding(
+            padding: EdgeInsets.symmetric(
+              horizontal: Constants.size.standardPadding,
+            ),
+            child: LayoutBuilder(
+              builder: (context, constraints) {
+                return SingleChildScrollView(
+                  child: ConstrainedBox(
+                    constraints:
+                        BoxConstraints(minHeight: constraints.maxHeight),
+                    child: IntrinsicHeight(
+                      child: _buildContent(context),
+                    ),
                   ),
-                ),
-              );
-            },
+                );
+              },
+            ),
           ),
         ),
       );
@@ -869,7 +874,7 @@ class _TransactionSearchViewState
             Expanded(
               child: SecondaryButton(
                 label: "Cancel",
-                buttonHeight: ButtonHeight.l,
+                buttonHeight: isDesktop ? ButtonHeight.l : null,
                 onPressed: () async {
                   if (!isDesktop) {
                     if (FocusScope.of(context).hasFocus) {
@@ -919,7 +924,7 @@ class _TransactionSearchViewState
             ),
             Expanded(
               child: PrimaryButton(
-                buttonHeight: ButtonHeight.l,
+                buttonHeight: isDesktop ? ButtonHeight.l : null,
                 onPressed: () async {
                   await _onApplyPressed();
                 },
diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart
index c84ddf2b9..61a1da0ac 100644
--- a/lib/pages/wallet_view/wallet_view.dart
+++ b/lib/pages/wallet_view/wallet_view.dart
@@ -40,6 +40,7 @@ import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.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/background.dart';
 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';
@@ -378,401 +379,415 @@ class _WalletViewState extends ConsumerState<WalletView> {
 
     return WillPopScope(
       onWillPop: _onWillPop,
-      child: Scaffold(
-        appBar: AppBar(
-          leading: AppBarBackButton(
-            onPressed: () {
-              _logout();
-              Navigator.of(context).pop();
-            },
-          ),
-          titleSpacing: 0,
-          title: Row(
-            children: [
-              SvgPicture.asset(
-                Assets.svg.iconFor(coin: coin),
-                // color: Theme.of(context).extension<StackColors>()!.accentColorDark
-                width: 24,
-                height: 24,
-              ),
-              const SizedBox(
-                width: 16,
-              ),
-              Expanded(
-                child: Text(
-                  ref.watch(
-                      managerProvider.select((value) => value.walletName)),
-                  style: STextStyles.navBarTitle(context),
-                  overflow: TextOverflow.ellipsis,
+      child: Background(
+        child: Scaffold(
+          backgroundColor:
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: AppBar(
+            leading: AppBarBackButton(
+              onPressed: () {
+                _logout();
+                Navigator.of(context).pop();
+              },
+            ),
+            titleSpacing: 0,
+            title: Row(
+              children: [
+                SvgPicture.asset(
+                  Assets.svg.iconFor(coin: coin),
+                  // color: Theme.of(context).extension<StackColors>()!.accentColorDark
+                  width: 24,
+                  height: 24,
                 ),
-              )
+                const SizedBox(
+                  width: 16,
+                ),
+                Expanded(
+                  child: Text(
+                    ref.watch(
+                        managerProvider.select((value) => value.walletName)),
+                    style: STextStyles.navBarTitle(context),
+                    overflow: TextOverflow.ellipsis,
+                  ),
+                )
+              ],
+            ),
+            actions: [
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
+                ),
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("walletViewRadioButton"),
+                    size: 36,
+                    shadows: const [],
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    icon: _buildNetworkIcon(_currentSyncStatus),
+                    onPressed: () {
+                      Navigator.of(context).pushNamed(
+                        WalletNetworkSettingsView.routeName,
+                        arguments: Tuple3(
+                          walletId,
+                          _currentSyncStatus,
+                          _currentNodeStatus,
+                        ),
+                      );
+                    },
+                  ),
+                ),
+              ),
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
+                ),
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("walletViewAlertsButton"),
+                    size: 36,
+                    shadows: const [],
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    icon: SvgPicture.asset(
+                      ref.watch(notificationsProvider.select((value) =>
+                              value.hasUnreadNotificationsFor(walletId)))
+                          ? Assets.svg.bellNew(context)
+                          : Assets.svg.bell,
+                      width: 20,
+                      height: 20,
+                      color: ref.watch(notificationsProvider.select((value) =>
+                              value.hasUnreadNotificationsFor(walletId)))
+                          ? null
+                          : Theme.of(context)
+                              .extension<StackColors>()!
+                              .topNavIconPrimary,
+                    ),
+                    onPressed: () {
+                      // reset unread state
+                      ref.refresh(unreadNotificationsStateProvider);
+
+                      Navigator.of(context)
+                          .pushNamed(
+                        NotificationsView.routeName,
+                        arguments: walletId,
+                      )
+                          .then((_) {
+                        final Set<int> unreadNotificationIds = ref
+                            .read(unreadNotificationsStateProvider.state)
+                            .state;
+                        if (unreadNotificationIds.isEmpty) return;
+
+                        List<Future<dynamic>> futures = [];
+                        for (int i = 0;
+                            i < unreadNotificationIds.length - 1;
+                            i++) {
+                          futures.add(ref
+                              .read(notificationsProvider)
+                              .markAsRead(
+                                  unreadNotificationIds.elementAt(i), false));
+                        }
+
+                        // wait for multiple to update if any
+                        Future.wait(futures).then((_) {
+                          // only notify listeners once
+                          ref
+                              .read(notificationsProvider)
+                              .markAsRead(unreadNotificationIds.last, true);
+                        });
+                      });
+                    },
+                  ),
+                ),
+              ),
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
+                ),
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("walletViewSettingsButton"),
+                    size: 36,
+                    shadows: const [],
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    icon: SvgPicture.asset(
+                      Assets.svg.bars,
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                      width: 20,
+                      height: 20,
+                    ),
+                    onPressed: () {
+                      debugPrint("wallet view settings tapped");
+                      Navigator.of(context).pushNamed(
+                        WalletSettingsView.routeName,
+                        arguments: Tuple4(
+                          walletId,
+                          ref.read(managerProvider).coin,
+                          _currentSyncStatus,
+                          _currentNodeStatus,
+                        ),
+                      );
+                    },
+                  ),
+                ),
+              ),
             ],
           ),
-          actions: [
-            Padding(
-              padding: const EdgeInsets.only(
-                top: 10,
-                bottom: 10,
-                right: 10,
-              ),
-              child: AspectRatio(
-                aspectRatio: 1,
-                child: AppBarIconButton(
-                  key: const Key("walletViewRadioButton"),
-                  size: 36,
-                  shadows: const [],
-                  color: Theme.of(context).extension<StackColors>()!.background,
-                  icon: _buildNetworkIcon(_currentSyncStatus),
-                  onPressed: () {
-                    Navigator.of(context).pushNamed(
-                      WalletNetworkSettingsView.routeName,
-                      arguments: Tuple3(
-                        walletId,
-                        _currentSyncStatus,
-                        _currentNodeStatus,
-                      ),
-                    );
-                  },
-                ),
-              ),
-            ),
-            Padding(
-              padding: const EdgeInsets.only(
-                top: 10,
-                bottom: 10,
-                right: 10,
-              ),
-              child: AspectRatio(
-                aspectRatio: 1,
-                child: AppBarIconButton(
-                  key: const Key("walletViewAlertsButton"),
-                  size: 36,
-                  shadows: const [],
-                  color: Theme.of(context).extension<StackColors>()!.background,
-                  icon: SvgPicture.asset(
-                    ref.watch(notificationsProvider.select((value) =>
-                            value.hasUnreadNotificationsFor(walletId)))
-                        ? Assets.svg.bellNew(context)
-                        : Assets.svg.bell,
-                    width: 20,
-                    height: 20,
-                    color: ref.watch(notificationsProvider.select((value) =>
-                            value.hasUnreadNotificationsFor(walletId)))
-                        ? null
-                        : Theme.of(context)
-                            .extension<StackColors>()!
-                            .topNavIconPrimary,
-                  ),
-                  onPressed: () {
-                    // reset unread state
-                    ref.refresh(unreadNotificationsStateProvider);
-
-                    Navigator.of(context)
-                        .pushNamed(
-                      NotificationsView.routeName,
-                      arguments: walletId,
-                    )
-                        .then((_) {
-                      final Set<int> unreadNotificationIds = ref
-                          .read(unreadNotificationsStateProvider.state)
-                          .state;
-                      if (unreadNotificationIds.isEmpty) return;
-
-                      List<Future<dynamic>> futures = [];
-                      for (int i = 0;
-                          i < unreadNotificationIds.length - 1;
-                          i++) {
-                        futures.add(ref.read(notificationsProvider).markAsRead(
-                            unreadNotificationIds.elementAt(i), false));
-                      }
-
-                      // wait for multiple to update if any
-                      Future.wait(futures).then((_) {
-                        // only notify listeners once
-                        ref
-                            .read(notificationsProvider)
-                            .markAsRead(unreadNotificationIds.last, true);
-                      });
-                    });
-                  },
-                ),
-              ),
-            ),
-            Padding(
-              padding: const EdgeInsets.only(
-                top: 10,
-                bottom: 10,
-                right: 10,
-              ),
-              child: AspectRatio(
-                aspectRatio: 1,
-                child: AppBarIconButton(
-                  key: const Key("walletViewSettingsButton"),
-                  size: 36,
-                  shadows: const [],
-                  color: Theme.of(context).extension<StackColors>()!.background,
-                  icon: SvgPicture.asset(
-                    Assets.svg.bars,
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .accentColorDark,
-                    width: 20,
-                    height: 20,
-                  ),
-                  onPressed: () {
-                    debugPrint("wallet view settings tapped");
-                    Navigator.of(context).pushNamed(
-                      WalletSettingsView.routeName,
-                      arguments: Tuple4(
-                        walletId,
-                        ref.read(managerProvider).coin,
-                        _currentSyncStatus,
-                        _currentNodeStatus,
-                      ),
-                    );
-                  },
-                ),
-              ),
-            ),
-          ],
-        ),
-        body: SafeArea(
-          child: Container(
-            color: Theme.of(context).extension<StackColors>()!.background,
-            child: Column(
-              children: [
-                const SizedBox(
-                  height: 10,
-                ),
-                Center(
-                  child: Padding(
-                    padding: const EdgeInsets.symmetric(horizontal: 16),
-                    child: WalletSummary(
-                      walletId: walletId,
-                      managerProvider: managerProvider,
-                      initialSyncStatus: ref.watch(managerProvider
-                              .select((value) => value.isRefreshing))
-                          ? WalletSyncStatus.syncing
-                          : WalletSyncStatus.synced,
-                    ),
-                  ),
-                ),
-                if (coin == Coin.firo)
+          body: SafeArea(
+            child: Container(
+              color: Theme.of(context).extension<StackColors>()!.background,
+              child: Column(
+                children: [
                   const SizedBox(
                     height: 10,
                   ),
-                if (coin == Coin.firo)
-                  Padding(
-                    padding: const EdgeInsets.symmetric(horizontal: 16),
-                    child: Row(
-                      children: [
-                        Expanded(
-                          child: TextButton(
-                            style: Theme.of(context)
-                                .extension<StackColors>()!
-                                .getSecondaryEnabledButtonColor(context),
-                            onPressed: () async {
-                              await showDialog<void>(
-                                context: context,
-                                builder: (context) => StackDialog(
-                                  title: "Attention!",
-                                  message:
-                                      "You're about to anonymize all of your public funds.",
-                                  leftButton: TextButton(
-                                    onPressed: () {
-                                      Navigator.of(context).pop();
-                                    },
-                                    child: Text(
-                                      "Cancel",
-                                      style:
-                                          STextStyles.button(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorDark,
+                  Center(
+                    child: Padding(
+                      padding: const EdgeInsets.symmetric(horizontal: 16),
+                      child: WalletSummary(
+                        walletId: walletId,
+                        managerProvider: managerProvider,
+                        initialSyncStatus: ref.watch(managerProvider
+                                .select((value) => value.isRefreshing))
+                            ? WalletSyncStatus.syncing
+                            : WalletSyncStatus.synced,
+                      ),
+                    ),
+                  ),
+                  if (coin == Coin.firo)
+                    const SizedBox(
+                      height: 10,
+                    ),
+                  if (coin == Coin.firo)
+                    Padding(
+                      padding: const EdgeInsets.symmetric(horizontal: 16),
+                      child: Row(
+                        children: [
+                          Expanded(
+                            child: TextButton(
+                              style: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .getSecondaryEnabledButtonColor(context),
+                              onPressed: () async {
+                                await showDialog<void>(
+                                  context: context,
+                                  builder: (context) => StackDialog(
+                                    title: "Attention!",
+                                    message:
+                                        "You're about to anonymize all of your public funds.",
+                                    leftButton: TextButton(
+                                      onPressed: () {
+                                        Navigator.of(context).pop();
+                                      },
+                                      child: Text(
+                                        "Cancel",
+                                        style: STextStyles.button(context)
+                                            .copyWith(
+                                          color: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .accentColorDark,
+                                        ),
+                                      ),
+                                    ),
+                                    rightButton: TextButton(
+                                      onPressed: () async {
+                                        Navigator.of(context).pop();
+
+                                        unawaited(attemptAnonymize());
+                                      },
+                                      style: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .getPrimaryEnabledButtonColor(
+                                              context),
+                                      child: Text(
+                                        "Continue",
+                                        style: STextStyles.button(context),
                                       ),
                                     ),
                                   ),
-                                  rightButton: TextButton(
-                                    onPressed: () async {
-                                      Navigator.of(context).pop();
-
-                                      unawaited(attemptAnonymize());
-                                    },
-                                    style: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .getPrimaryEnabledButtonColor(context),
-                                    child: Text(
-                                      "Continue",
-                                      style: STextStyles.button(context),
-                                    ),
-                                  ),
+                                );
+                              },
+                              child: Text(
+                                "Anonymize funds",
+                                style: STextStyles.button(context).copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .buttonTextSecondary,
                                 ),
-                              );
-                            },
-                            child: Text(
-                              "Anonymize funds",
-                              style: STextStyles.button(context).copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .buttonTextSecondary,
                               ),
                             ),
                           ),
+                        ],
+                      ),
+                    ),
+                  const SizedBox(
+                    height: 20,
+                  ),
+                  Padding(
+                    padding: const EdgeInsets.symmetric(horizontal: 16),
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Text(
+                          "Transactions",
+                          style: STextStyles.itemSubtitle(context).copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark3,
+                          ),
+                        ),
+                        BlueTextButton(
+                          text: "See all",
+                          onTap: () {
+                            Navigator.of(context).pushNamed(
+                              AllTransactionsView.routeName,
+                              arguments: walletId,
+                            );
+                          },
                         ),
                       ],
                     ),
                   ),
-                const SizedBox(
-                  height: 20,
-                ),
-                Padding(
-                  padding: const EdgeInsets.symmetric(horizontal: 16),
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                    children: [
-                      Text(
-                        "Transactions",
-                        style: STextStyles.itemSubtitle(context).copyWith(
-                          color: Theme.of(context)
-                              .extension<StackColors>()!
-                              .textDark3,
-                        ),
-                      ),
-                      BlueTextButton(
-                        text: "See all",
-                        onTap: () {
-                          Navigator.of(context).pushNamed(
-                            AllTransactionsView.routeName,
-                            arguments: walletId,
-                          );
-                        },
-                      ),
-                    ],
+                  const SizedBox(
+                    height: 12,
                   ),
-                ),
-                const SizedBox(
-                  height: 12,
-                ),
-                Expanded(
-                  child: Stack(
-                    children: [
-                      Padding(
-                        padding: const EdgeInsets.symmetric(horizontal: 16),
-                        child: Padding(
-                          padding: const EdgeInsets.only(bottom: 14),
-                          child: ClipRRect(
-                            borderRadius: BorderRadius.vertical(
-                              top: Radius.circular(
-                                Constants.size.circularBorderRadius,
-                              ),
-                              bottom: Radius.circular(
-                                // WalletView.navBarHeight / 2.0,
-                                Constants.size.circularBorderRadius,
-                              ),
-                            ),
-                            child: Container(
-                              decoration: BoxDecoration(
-                                color: Colors.transparent,
-                                borderRadius: BorderRadius.circular(
+                  Expanded(
+                    child: Stack(
+                      children: [
+                        Padding(
+                          padding: const EdgeInsets.symmetric(horizontal: 16),
+                          child: Padding(
+                            padding: const EdgeInsets.only(bottom: 14),
+                            child: ClipRRect(
+                              borderRadius: BorderRadius.vertical(
+                                top: Radius.circular(
+                                  Constants.size.circularBorderRadius,
+                                ),
+                                bottom: Radius.circular(
+                                  // WalletView.navBarHeight / 2.0,
                                   Constants.size.circularBorderRadius,
                                 ),
                               ),
-                              child: Column(
-                                crossAxisAlignment: CrossAxisAlignment.stretch,
-                                children: [
-                                  Expanded(
-                                    child: TransactionsList(
-                                      managerProvider: managerProvider,
-                                      walletId: walletId,
-                                    ),
+                              child: Container(
+                                decoration: BoxDecoration(
+                                  color: Colors.transparent,
+                                  borderRadius: BorderRadius.circular(
+                                    Constants.size.circularBorderRadius,
                                   ),
-                                ],
+                                ),
+                                child: Column(
+                                  crossAxisAlignment:
+                                      CrossAxisAlignment.stretch,
+                                  children: [
+                                    Expanded(
+                                      child: TransactionsList(
+                                        managerProvider: managerProvider,
+                                        walletId: walletId,
+                                      ),
+                                    ),
+                                  ],
+                                ),
                               ),
                             ),
                           ),
                         ),
-                      ),
-                      Column(
-                        mainAxisAlignment: MainAxisAlignment.end,
-                        children: [
-                          const Spacer(),
-                          Row(
-                            mainAxisAlignment: MainAxisAlignment.center,
-                            children: [
-                              Padding(
-                                padding: const EdgeInsets.only(
-                                  bottom: 14,
-                                  left: 16,
-                                  right: 16,
-                                ),
-                                child: SizedBox(
-                                  height: WalletView.navBarHeight,
-                                  child: WalletNavigationBar(
-                                    enableExchange: Constants.enableExchange &&
-                                        ref.watch(managerProvider.select(
-                                                (value) => value.coin)) !=
-                                            Coin.epicCash,
+                        Column(
+                          mainAxisAlignment: MainAxisAlignment.end,
+                          children: [
+                            const Spacer(),
+                            Row(
+                              mainAxisAlignment: MainAxisAlignment.center,
+                              children: [
+                                Padding(
+                                  padding: const EdgeInsets.only(
+                                    bottom: 14,
+                                    left: 16,
+                                    right: 16,
+                                  ),
+                                  child: SizedBox(
                                     height: WalletView.navBarHeight,
-                                    onExchangePressed: () =>
-                                        _onExchangePressed(context),
-                                    onReceivePressed: () async {
-                                      final coin =
-                                          ref.read(managerProvider).coin;
-                                      if (mounted) {
-                                        unawaited(
-                                            Navigator.of(context).pushNamed(
-                                          ReceiveView.routeName,
+                                    child: WalletNavigationBar(
+                                      enableExchange:
+                                          Constants.enableExchange &&
+                                              ref.watch(managerProvider.select(
+                                                      (value) => value.coin)) !=
+                                                  Coin.epicCash,
+                                      height: WalletView.navBarHeight,
+                                      onExchangePressed: () =>
+                                          _onExchangePressed(context),
+                                      onReceivePressed: () async {
+                                        final coin =
+                                            ref.read(managerProvider).coin;
+                                        if (mounted) {
+                                          unawaited(
+                                              Navigator.of(context).pushNamed(
+                                            ReceiveView.routeName,
+                                            arguments: Tuple2(
+                                              walletId,
+                                              coin,
+                                            ),
+                                          ));
+                                        }
+                                      },
+                                      onSendPressed: () {
+                                        final walletId =
+                                            ref.read(managerProvider).walletId;
+                                        final coin =
+                                            ref.read(managerProvider).coin;
+                                        switch (ref
+                                            .read(
+                                                walletBalanceToggleStateProvider
+                                                    .state)
+                                            .state) {
+                                          case WalletBalanceToggleState.full:
+                                            ref
+                                                .read(
+                                                    publicPrivateBalanceStateProvider
+                                                        .state)
+                                                .state = "Public";
+                                            break;
+                                          case WalletBalanceToggleState
+                                              .available:
+                                            ref
+                                                .read(
+                                                    publicPrivateBalanceStateProvider
+                                                        .state)
+                                                .state = "Private";
+                                            break;
+                                        }
+                                        Navigator.of(context).pushNamed(
+                                          SendView.routeName,
                                           arguments: Tuple2(
                                             walletId,
                                             coin,
                                           ),
-                                        ));
-                                      }
-                                    },
-                                    onSendPressed: () {
-                                      final walletId =
-                                          ref.read(managerProvider).walletId;
-                                      final coin =
-                                          ref.read(managerProvider).coin;
-                                      switch (ref
-                                          .read(walletBalanceToggleStateProvider
-                                              .state)
-                                          .state) {
-                                        case WalletBalanceToggleState.full:
-                                          ref
-                                              .read(
-                                                  publicPrivateBalanceStateProvider
-                                                      .state)
-                                              .state = "Public";
-                                          break;
-                                        case WalletBalanceToggleState.available:
-                                          ref
-                                              .read(
-                                                  publicPrivateBalanceStateProvider
-                                                      .state)
-                                              .state = "Private";
-                                          break;
-                                      }
-                                      Navigator.of(context).pushNamed(
-                                        SendView.routeName,
-                                        arguments: Tuple2(
-                                          walletId,
-                                          coin,
-                                        ),
-                                      );
-                                    },
-                                    onBuyPressed: () {},
+                                        );
+                                      },
+                                      onBuyPressed: () {},
+                                    ),
                                   ),
                                 ),
-                              ),
-                            ],
-                          ),
-                        ],
-                      )
-                    ],
+                              ],
+                            ),
+                          ],
+                        )
+                      ],
+                    ),
                   ),
-                ),
-              ],
+                ],
+              ),
             ),
           ),
         ),
diff --git a/lib/pages_desktop_specific/desktop_login_view.dart b/lib/pages_desktop_specific/desktop_login_view.dart
index eb5dec18a..9bddda3da 100644
--- a/lib/pages_desktop_specific/desktop_login_view.dart
+++ b/lib/pages_desktop_specific/desktop_login_view.dart
@@ -10,7 +10,6 @@ import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.da
 import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index 9791cd867..54c74fe88 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -13,6 +13,7 @@ import 'package:stackwallet/providers/global/notifications_provider.dart';
 import 'package:stackwallet/providers/ui/unread_notifications_provider.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/background.dart';
 
 class DesktopHomeView extends ConsumerStatefulWidget {
   const DesktopHomeView({Key? key}) : super(key: key);
@@ -98,21 +99,23 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
   Widget build(BuildContext context) {
     return Material(
       color: Theme.of(context).extension<StackColors>()!.background,
-      child: Row(
-        children: [
-          DesktopMenu(
-            // onSelectionChanged: onMenuSelectionChanged,
-            onSelectionWillChange: onMenuSelectionWillChange,
-          ),
-          Container(
-            width: 1,
-            color: Theme.of(context).extension<StackColors>()!.background,
-          ),
-          Expanded(
-            child: contentViews[
-                ref.watch(currentDesktopMenuItemProvider.state).state]!,
-          ),
-        ],
+      child: Background(
+        child: Row(
+          children: [
+            DesktopMenu(
+              // onSelectionChanged: onMenuSelectionChanged,
+              onSelectionWillChange: onMenuSelectionWillChange,
+            ),
+            Container(
+              width: 1,
+              color: Theme.of(context).extension<StackColors>()!.background,
+            ),
+            Expanded(
+              child: contentViews[
+                  ref.watch(currentDesktopMenuItemProvider.state).state]!,
+            ),
+          ],
+        ),
       ),
     );
   }
diff --git a/lib/pages_desktop_specific/home/my_stack_view/my_stack_view.dart b/lib/pages_desktop_specific/home/my_stack_view/my_stack_view.dart
index 6b60902c4..6710c23a4 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/my_stack_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/my_stack_view.dart
@@ -6,6 +6,7 @@ import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_wallets
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 
 class MyStackView extends ConsumerStatefulWidget {
@@ -23,36 +24,38 @@ class _MyStackViewState extends ConsumerState<MyStackView> {
     debugPrint("BUILD: $runtimeType");
     final hasWallets = ref.watch(walletsChangeNotifierProvider).hasWallets;
 
-    return Column(
-      children: [
-        DesktopAppBar(
-          isCompactHeight: true,
-          leading: Row(
-            children: [
-              const SizedBox(
-                width: 24,
-              ),
-              SizedBox(
-                width: 32,
-                height: 32,
-                child: SvgPicture.asset(
-                  Assets.svg.stackIcon(context),
+    return Background(
+      child: Column(
+        children: [
+          DesktopAppBar(
+            isCompactHeight: true,
+            leading: Row(
+              children: [
+                const SizedBox(
+                  width: 24,
                 ),
-              ),
-              const SizedBox(
-                width: 12,
-              ),
-              Text(
-                "My Stack",
-                style: STextStyles.desktopH3(context),
-              )
-            ],
+                SizedBox(
+                  width: 32,
+                  height: 32,
+                  child: SvgPicture.asset(
+                    Assets.svg.stackIcon(context),
+                  ),
+                ),
+                const SizedBox(
+                  width: 12,
+                ),
+                Text(
+                  "My Stack",
+                  style: STextStyles.desktopH3(context),
+                )
+              ],
+            ),
           ),
-        ),
-        Expanded(
-          child: hasWallets ? const MyWallets() : const EmptyWallets(),
-        ),
-      ],
+          Expanded(
+            child: hasWallets ? const MyWallets() : const EmptyWallets(),
+          ),
+        ],
+      ),
     );
   }
 }
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 149d46b3c..27c8fe3b4 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/theme/color_theme.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
 abstract class Assets {
@@ -28,6 +29,16 @@ class _EXCHANGE {
 
 class _SVG {
   const _SVG();
+  String? background(BuildContext context) {
+    switch (Theme.of(context).extension<StackColors>()!.themeType) {
+      case ThemeType.light:
+      case ThemeType.dark:
+        return null;
+
+      case ThemeType.oceanBreeze:
+        return "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/bg.svg";
+    }
+  }
 
   String bellNew(BuildContext context) =>
       "assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/bell-new.svg";
diff --git a/lib/utilities/theme/color_theme.dart b/lib/utilities/theme/color_theme.dart
index 852e2f586..4a480491c 100644
--- a/lib/utilities/theme/color_theme.dart
+++ b/lib/utilities/theme/color_theme.dart
@@ -1,5 +1,4 @@
-import 'dart:ui';
-
+import 'package:flutter/material.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 enum ThemeType {
@@ -12,6 +11,10 @@ abstract class StackColorTheme {
   ThemeType get themeType;
 
   Color get background;
+  Color get backgroundAppBar;
+
+  Gradient? get gradientBackground;
+
   Color get overlay;
 
   Color get accentColorBlue;
diff --git a/lib/utilities/theme/dark_colors.dart b/lib/utilities/theme/dark_colors.dart
index e7c4e51db..d55581921 100644
--- a/lib/utilities/theme/dark_colors.dart
+++ b/lib/utilities/theme/dark_colors.dart
@@ -7,6 +7,11 @@ class DarkColors extends StackColorTheme {
 
   @override
   Color get background => const Color(0xFF2A2D34);
+  @override
+  Color get backgroundAppBar => background;
+  @override
+  Gradient? get gradientBackground => null;
+
   @override
   Color get overlay => const Color(0xFF111215);
 
diff --git a/lib/utilities/theme/light_colors.dart b/lib/utilities/theme/light_colors.dart
index 896ae4e5e..1303d0b75 100644
--- a/lib/utilities/theme/light_colors.dart
+++ b/lib/utilities/theme/light_colors.dart
@@ -7,6 +7,11 @@ class LightColors extends StackColorTheme {
 
   @override
   Color get background => const Color(0xFFF7F7F7);
+  @override
+  Color get backgroundAppBar => background;
+  @override
+  Gradient? get gradientBackground => null;
+
   @override
   Color get overlay => const Color(0xFF111215);
 
diff --git a/lib/utilities/theme/ocean_breeze_colors.dart b/lib/utilities/theme/ocean_breeze_colors.dart
index 665eaa0c3..8c4259bb9 100644
--- a/lib/utilities/theme/ocean_breeze_colors.dart
+++ b/lib/utilities/theme/ocean_breeze_colors.dart
@@ -6,7 +6,19 @@ class OceanBreezeColors extends StackColorTheme {
   ThemeType get themeType => ThemeType.oceanBreeze;
 
   @override
-  Color get background => const Color(0xFFF3F7FA);
+  Color get background => Colors.transparent;
+  @override
+  Color get backgroundAppBar => const Color(0xFFF3F7FA);
+  @override
+  Gradient? get gradientBackground => const LinearGradient(
+        begin: Alignment.topCenter,
+        end: Alignment.bottomCenter,
+        colors: [
+          Color(0xFFF3F7FA),
+          Color(0xFFE8F2F9),
+        ],
+      );
+
   @override
   Color get overlay => const Color(0xFF111215);
 
diff --git a/lib/utilities/theme/stack_colors.dart b/lib/utilities/theme/stack_colors.dart
index 8249dccf4..935fa03ae 100644
--- a/lib/utilities/theme/stack_colors.dart
+++ b/lib/utilities/theme/stack_colors.dart
@@ -6,6 +6,9 @@ class StackColors extends ThemeExtension<StackColors> {
   final ThemeType themeType;
 
   final Color background;
+  final Color backgroundAppBar;
+  final Gradient? gradientBackground;
+
   final Color overlay;
 
   final Color accentColorBlue;
@@ -173,6 +176,8 @@ class StackColors extends ThemeExtension<StackColors> {
   StackColors({
     required this.themeType,
     required this.background,
+    required this.backgroundAppBar,
+    required this.gradientBackground,
     required this.overlay,
     required this.accentColorBlue,
     required this.accentColorGreen,
@@ -307,6 +312,8 @@ class StackColors extends ThemeExtension<StackColors> {
     return StackColors(
       themeType: colorTheme.themeType,
       background: colorTheme.background,
+      backgroundAppBar: colorTheme.backgroundAppBar,
+      gradientBackground: colorTheme.gradientBackground,
       overlay: colorTheme.overlay,
       accentColorBlue: colorTheme.accentColorBlue,
       accentColorGreen: colorTheme.accentColorGreen,
@@ -444,6 +451,8 @@ class StackColors extends ThemeExtension<StackColors> {
   ThemeExtension<StackColors> copyWith({
     ThemeType? themeType,
     Color? background,
+    Color? backgroundAppBar,
+    Gradient? gradientBackground,
     Color? overlay,
     Color? accentColorBlue,
     Color? accentColorGreen,
@@ -576,6 +585,8 @@ class StackColors extends ThemeExtension<StackColors> {
     return StackColors(
       themeType: themeType ?? this.themeType,
       background: background ?? this.background,
+      backgroundAppBar: backgroundAppBar ?? this.backgroundAppBar,
+      gradientBackground: gradientBackground ?? this.gradientBackground,
       overlay: overlay ?? this.overlay,
       accentColorBlue: accentColorBlue ?? this.accentColorBlue,
       accentColorGreen: accentColorGreen ?? this.accentColorGreen,
@@ -755,11 +766,17 @@ class StackColors extends ThemeExtension<StackColors> {
 
     return StackColors(
       themeType: other.themeType,
+      gradientBackground: other.gradientBackground,
       background: Color.lerp(
         background,
         other.background,
         t,
       )!,
+      backgroundAppBar: Color.lerp(
+        backgroundAppBar,
+        other.backgroundAppBar,
+        t,
+      )!,
       overlay: Color.lerp(
         overlay,
         other.overlay,
diff --git a/lib/widgets/background.dart b/lib/widgets/background.dart
new file mode 100644
index 000000000..4f70f5252
--- /dev/null
+++ b/lib/widgets/background.dart
@@ -0,0 +1,67 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/providers/ui/color_theme_provider.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/theme/color_theme.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
+
+class Background extends ConsumerWidget {
+  const Background({
+    Key? key,
+    required this.child,
+  }) : super(key: key);
+
+  final Widget child;
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final colorTheme = ref.watch(colorThemeProvider.state).state;
+
+    Color? color;
+
+    switch (colorTheme.themeType) {
+      case ThemeType.light:
+      case ThemeType.dark:
+        color = Theme.of(context).extension<StackColors>()!.background;
+        break;
+      case ThemeType.oceanBreeze:
+        color = null;
+        break;
+    }
+
+    final bgAsset = Assets.svg.background(context);
+
+    return Container(
+      decoration: BoxDecoration(
+        color: color,
+        gradient:
+            Theme.of(context).extension<StackColors>()!.gradientBackground,
+      ),
+      child: ConditionalParent(
+        condition: bgAsset != null,
+        builder: (child) => Stack(
+          children: [
+            Positioned.fill(
+              child: Padding(
+                padding: EdgeInsets.only(
+                  top: MediaQuery.of(context).size.height * (1 / 8),
+                  bottom: MediaQuery.of(context).size.height * (1 / 12),
+                ),
+                child: SvgPicture.asset(
+                  bgAsset!,
+                  fit: BoxFit.fill,
+                ),
+              ),
+            ),
+            Positioned.fill(
+              child: child,
+            ),
+          ],
+        ),
+        child: child,
+      ),
+    );
+  }
+}
diff --git a/lib/widgets/desktop/desktop_scaffold.dart b/lib/widgets/desktop/desktop_scaffold.dart
index 439289518..51fa9f3a5 100644
--- a/lib/widgets/desktop/desktop_scaffold.dart
+++ b/lib/widgets/desktop/desktop_scaffold.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/background.dart';
 
 class DesktopScaffold extends StatelessWidget {
   const DesktopScaffold({
@@ -18,15 +19,17 @@ class DesktopScaffold extends StatelessWidget {
     return Material(
       color:
           background ?? Theme.of(context).extension<StackColors>()!.background,
-      child: Column(
-        // crossAxisAlignment: CrossAxisAlignment.stretch,
-        children: [
-          if (appBar != null) appBar!,
-          if (body != null)
-            Expanded(
-              child: body!,
-            ),
-        ],
+      child: Background(
+        child: Column(
+          // crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: [
+            if (appBar != null) appBar!,
+            if (body != null)
+              Expanded(
+                child: body!,
+              ),
+          ],
+        ),
       ),
     );
   }
@@ -50,17 +53,18 @@ class MasterScaffold extends StatelessWidget {
   Widget build(BuildContext context) {
     if (isDesktop) {
       return DesktopScaffold(
-        background: background ??
-            Theme.of(context).extension<StackColors>()!.background,
+        background: background,
         appBar: appBar,
         body: body,
       );
     } else {
-      return Scaffold(
-        backgroundColor: background ??
-            Theme.of(context).extension<StackColors>()!.background,
-        appBar: appBar as PreferredSizeWidget?,
-        body: body,
+      return Background(
+        child: Scaffold(
+          backgroundColor: background ??
+              Theme.of(context).extension<StackColors>()!.background,
+          appBar: appBar as PreferredSizeWidget?,
+          body: body,
+        ),
       );
     }
   }
diff --git a/pubspec.yaml b/pubspec.yaml
index 7ca368d29..2397fbfbc 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -380,6 +380,7 @@ flutter:
     - assets/svg/oceanBreeze/bell-new.svg
     - assets/svg/oceanBreeze/stack-icon1.svg
     - assets/svg/oceanBreeze/buy-coins-icon.svg
+    - assets/svg/oceanBreeze/bg.svg
 
   # An image asset can refer to one or more resolution-specific "variants", see
   # https://flutter.dev/assets-and-images/#resolution-aware.

From 05bdc8c52fe53d1ff3d07dc1f7899480fa20a4d2 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 25 Nov 2022 13:50:13 -0600
Subject: [PATCH 405/426] fix node loading on initial start for desktop, only
 add default node back if there are no nodes exist for a certain coin

---
 .../create_password/create_password_view.dart     |  6 +++++-
 lib/services/node_service.dart                    | 15 ++++++++++-----
 lib/utilities/default_nodes.dart                  |  3 ++-
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/lib/pages_desktop_specific/create_password/create_password_view.dart b/lib/pages_desktop_specific/create_password/create_password_view.dart
index 8e752f508..a8c9e7758 100644
--- a/lib/pages_desktop_specific/create_password/create_password_view.dart
+++ b/lib/pages_desktop_specific/create_password/create_password_view.dart
@@ -7,9 +7,9 @@ import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.dart';
 import 'package:stackwallet/providers/global/secure_store_provider.dart';
+import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -81,6 +81,10 @@ class _CreatePasswordViewState extends ConsumerState<CreatePasswordView> {
 
       await ref.read(storageCryptoHandlerProvider).initFromNew(passphrase);
       await (ref.read(secureStoreProvider).store as DesktopSecureStore).init();
+
+      // load default nodes now as node service requires storage handler to exist
+
+      await ref.read(nodeServiceChangeNotifierProvider).updateDefaults();
     } catch (e) {
       unawaited(showFloatingFlushBar(
         type: FlushBarType.warning,
diff --git a/lib/services/node_service.dart b/lib/services/node_service.dart
index aa8d5a6d9..ca1aae082 100644
--- a/lib/services/node_service.dart
+++ b/lib/services/node_service.dart
@@ -24,11 +24,14 @@ class NodeService extends ChangeNotifier {
       final savedNode = DB.instance
           .get<NodeModel>(boxName: DB.boxNameNodeModels, key: defaultNode.id);
       if (savedNode == null) {
-        // save the default node to hive
-        await DB.instance.put<NodeModel>(
+        // save the default node to hive only if no other nodes for the specific coin exist
+        if (getNodesFor(coinFromPrettyName(defaultNode.coinName)).isEmpty) {
+          await DB.instance.put<NodeModel>(
             boxName: DB.boxNameNodeModels,
             key: defaultNode.id,
-            value: defaultNode);
+            value: defaultNode,
+          );
+        }
       } else {
         // update all fields but copy over previously set enabled state
         await DB.instance.put<NodeModel>(
@@ -81,14 +84,16 @@ class NodeService extends ChangeNotifier {
     final list = DB.instance
         .values<NodeModel>(boxName: DB.boxNameNodeModels)
         .where((e) =>
-            e.coinName == coin.name && e.name != DefaultNodes.defaultName)
+            e.coinName == coin.name &&
+            !e.id.startsWith(DefaultNodes.defaultNodeIdPrefix))
         .toList();
 
     // add default to end of list
     list.addAll(DB.instance
         .values<NodeModel>(boxName: DB.boxNameNodeModels)
         .where((e) =>
-            e.coinName == coin.name && e.name == DefaultNodes.defaultName)
+            e.coinName == coin.name &&
+            e.id.startsWith(DefaultNodes.defaultNodeIdPrefix))
         .toList());
 
     // return reversed list so default node appears at beginning
diff --git a/lib/utilities/default_nodes.dart b/lib/utilities/default_nodes.dart
index abe702b78..c9e96fbac 100644
--- a/lib/utilities/default_nodes.dart
+++ b/lib/utilities/default_nodes.dart
@@ -4,7 +4,8 @@ import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 abstract class DefaultNodes {
-  static String _nodeId(Coin coin) => "default_${coin.name}";
+  static const String defaultNodeIdPrefix = "default_";
+  static String _nodeId(Coin coin) => "$defaultNodeIdPrefix${coin.name}";
   static const String defaultName = "Stack Default";
 
   static List<NodeModel> get all => [

From 276d08d22f6c174ea2db9204c07f52b24f592826 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 25 Nov 2022 14:28:53 -0600
Subject: [PATCH 406/426] allow default node deletion if other nodes exist

---
 lib/models/node_model.dart                    |   3 +-
 .../add_edit_node_view.dart                   |   7 +-
 .../manage_nodes_views/node_details_view.dart | 124 +++++++++++-------
 lib/widgets/node_card.dart                    |  17 +--
 lib/widgets/node_options_sheet.dart           |   6 +-
 5 files changed, 94 insertions(+), 63 deletions(-)

diff --git a/lib/models/node_model.dart b/lib/models/node_model.dart
index 2628c5dd9..af5f8cbc1 100644
--- a/lib/models/node_model.dart
+++ b/lib/models/node_model.dart
@@ -1,4 +1,5 @@
 import 'package:hive/hive.dart';
+import 'package:stackwallet/utilities/default_nodes.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 part 'type_adaptors/node_model.g.dart';
@@ -84,7 +85,7 @@ class NodeModel {
     return map;
   }
 
-  bool get isDefault => id.startsWith("default_");
+  bool get isDefault => id.startsWith(DefaultNodes.defaultNodeIdPrefix);
 
   @override
   String toString() {
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index bd6e5c6d8..32fa3974a 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -432,7 +432,12 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
               style: STextStyles.navBarTitle(context),
             ),
             actions: [
-              if (viewType == AddEditNodeViewType.edit)
+              if (viewType == AddEditNodeViewType.edit &&
+                  ref
+                          .watch(nodeServiceChangeNotifierProvider
+                              .select((value) => value.getNodesFor(coin)))
+                          .length >
+                      1)
                 Padding(
                   padding: const EdgeInsets.only(
                     top: 10,
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index 2e43b5595..24af0e78e 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -10,7 +10,6 @@ import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/test_epic_box_connection.dart';
@@ -178,6 +177,11 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
     final node = ref.watch(nodeServiceChangeNotifierProvider
         .select((value) => value.getNodeById(id: nodeId)));
 
+    final nodesForCoin = ref.watch(nodeServiceChangeNotifierProvider
+        .select((value) => value.getNodesFor(coin)));
+
+    final canDelete = nodesForCoin.length > 1;
+
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) => Background(
@@ -201,44 +205,43 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
               style: STextStyles.navBarTitle(context),
             ),
             actions: [
-              if (!nodeId.startsWith("default"))
-                Padding(
-                  padding: const EdgeInsets.only(
-                    top: 10,
-                    bottom: 10,
-                    right: 10,
-                  ),
-                  child: AspectRatio(
-                    aspectRatio: 1,
-                    child: AppBarIconButton(
-                      key: const Key("nodeDetailsEditNodeAppBarButtonKey"),
-                      size: 36,
-                      shadows: const [],
+              // if (!nodeId.startsWith(DefaultNodes.defaultNodeIdPrefix))
+              Padding(
+                padding: const EdgeInsets.only(
+                  top: 10,
+                  bottom: 10,
+                  right: 10,
+                ),
+                child: AspectRatio(
+                  aspectRatio: 1,
+                  child: AppBarIconButton(
+                    key: const Key("nodeDetailsEditNodeAppBarButtonKey"),
+                    size: 36,
+                    shadows: const [],
+                    color:
+                        Theme.of(context).extension<StackColors>()!.background,
+                    icon: SvgPicture.asset(
+                      Assets.svg.pencil,
                       color: Theme.of(context)
                           .extension<StackColors>()!
-                          .background,
-                      icon: SvgPicture.asset(
-                        Assets.svg.pencil,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .accentColorDark,
-                        width: 20,
-                        height: 20,
-                      ),
-                      onPressed: () {
-                        Navigator.of(context).pushNamed(
-                          AddEditNodeView.routeName,
-                          arguments: Tuple4(
-                            AddEditNodeViewType.edit,
-                            coin,
-                            nodeId,
-                            popRouteName,
-                          ),
-                        );
-                      },
+                          .accentColorDark,
+                      width: 20,
+                      height: 20,
                     ),
+                    onPressed: () {
+                      Navigator.of(context).pushNamed(
+                        AddEditNodeView.routeName,
+                        arguments: Tuple4(
+                          AddEditNodeViewType.edit,
+                          coin,
+                          nodeId,
+                          popRouteName,
+                        ),
+                      );
+                    },
                   ),
                 ),
+              ),
             ],
           ),
           body: Padding(
@@ -315,7 +318,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
               const SizedBox(
                 height: 22,
               ),
-            if (isDesktop)
+            if (isDesktop && canDelete)
               SizedBox(
                 height: 56,
                 child: _desktopReadOnly
@@ -345,7 +348,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
                         ],
                       ),
               ),
-            if (isDesktop && !_desktopReadOnly)
+            if (isDesktop && !_desktopReadOnly && canDelete)
               const SizedBox(
                 height: 45,
               ),
@@ -366,22 +369,41 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
                   ),
                 if (isDesktop)
                   Expanded(
-                    child: !nodeId.startsWith("default")
-                        ? PrimaryButton(
-                            label: _desktopReadOnly ? "Edit" : "Save",
-                            buttonHeight: ButtonHeight.l,
-                            onPressed: () async {
-                              final shouldSave = _desktopReadOnly == false;
-                              setState(() {
-                                _desktopReadOnly = !_desktopReadOnly;
-                              });
+                    child:
+                        // !nodeId.startsWith(DefaultNodes.defaultNodeIdPrefix)
+                        //     ?
+                        PrimaryButton(
+                      label: _desktopReadOnly ? "Edit" : "Save",
+                      buttonHeight: ButtonHeight.l,
+                      onPressed: () async {
+                        final shouldSave = _desktopReadOnly == false;
+                        setState(() {
+                          _desktopReadOnly = !_desktopReadOnly;
+                        });
 
-                              if (shouldSave) {
-                                // todo save node
-                              }
-                            },
-                          )
-                        : Container(),
+                        if (shouldSave) {
+                          final editedNode = node!.copyWith(
+                            host: ref.read(nodeFormDataProvider).host,
+                            port: ref.read(nodeFormDataProvider).port,
+                            name: ref.read(nodeFormDataProvider).name,
+                            useSSL: ref.read(nodeFormDataProvider).useSSL,
+                            loginName: ref.read(nodeFormDataProvider).login,
+                            isFailover:
+                                ref.read(nodeFormDataProvider).isFailover,
+                          );
+
+                          await ref
+                              .read(nodeServiceChangeNotifierProvider)
+                              .edit(
+                                editedNode,
+                                ref.read(nodeFormDataProvider).password,
+                                true,
+                              );
+                        }
+                      },
+                    )
+                    // : Container()
+                    ,
                   ),
               ],
             ),
diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart
index c3fb36c70..fb8260b24 100644
--- a/lib/widgets/node_card.dart
+++ b/lib/widgets/node_card.dart
@@ -306,7 +306,7 @@ class _NodeCardState extends ConsumerState<NodeCard> {
                   width: isDesktop ? 40 : 24,
                   height: isDesktop ? 40 : 24,
                   decoration: BoxDecoration(
-                    color: _node.name == DefaultNodes.defaultName
+                    color: _node.id.startsWith(DefaultNodes.defaultNodeIdPrefix)
                         ? Theme.of(context)
                             .extension<StackColors>()!
                             .buttonBackSecondary
@@ -321,13 +321,14 @@ class _NodeCardState extends ConsumerState<NodeCard> {
                       Assets.svg.node,
                       height: isDesktop ? 18 : 11,
                       width: isDesktop ? 20 : 14,
-                      color: _node.name == DefaultNodes.defaultName
-                          ? Theme.of(context)
-                              .extension<StackColors>()!
-                              .accentColorDark
-                          : Theme.of(context)
-                              .extension<StackColors>()!
-                              .infoItemIcons,
+                      color:
+                          _node.id.startsWith(DefaultNodes.defaultNodeIdPrefix)
+                              ? Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorDark
+                              : Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .infoItemIcons,
                     ),
                   ),
                 ),
diff --git a/lib/widgets/node_options_sheet.dart b/lib/widgets/node_options_sheet.dart
index 7ffd290f3..1ef9b07fe 100644
--- a/lib/widgets/node_options_sheet.dart
+++ b/lib/widgets/node_options_sheet.dart
@@ -234,7 +234,8 @@ class NodeOptionsSheet extends ConsumerWidget {
                         width: 32,
                         height: 32,
                         decoration: BoxDecoration(
-                          color: node.name == DefaultNodes.defaultName
+                          color: node.id
+                                  .startsWith(DefaultNodes.defaultNodeIdPrefix)
                               ? Theme.of(context)
                                   .extension<StackColors>()!
                                   .textSubtitle4
@@ -249,7 +250,8 @@ class NodeOptionsSheet extends ConsumerWidget {
                             Assets.svg.node,
                             height: 15,
                             width: 19,
-                            color: node.name == DefaultNodes.defaultName
+                            color: node.id.startsWith(
+                                    DefaultNodes.defaultNodeIdPrefix)
                                 ? Theme.of(context)
                                     .extension<StackColors>()!
                                     .accentColorDark

From 4b0d44a239d5e94248b30eb07fca21a45d4e86b3 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 25 Nov 2022 16:49:43 -0600
Subject: [PATCH 407/426] emoji search

---
 lib/widgets/emoji_select_sheet.dart | 178 ++++++++++++++++++++++------
 1 file changed, 143 insertions(+), 35 deletions(-)

diff --git a/lib/widgets/emoji_select_sheet.dart b/lib/widgets/emoji_select_sheet.dart
index 7bf02e967..d5a37d142 100644
--- a/lib/widgets/emoji_select_sheet.dart
+++ b/lib/widgets/emoji_select_sheet.dart
@@ -1,14 +1,19 @@
 import 'package:emojis/emoji.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/utilities/assets.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/conditional_parent.dart';
 import 'package:stackwallet/widgets/desktop/secondary_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 EmojiSelectSheet extends ConsumerWidget {
+class EmojiSelectSheet extends ConsumerStatefulWidget {
   const EmojiSelectSheet({
     Key? key,
   }) : super(key: key);
@@ -18,17 +23,59 @@ class EmojiSelectSheet extends ConsumerWidget {
   final double minimumEmojiSpacing = 25;
 
   @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final isDesktop = Util.isDesktop;
+  ConsumerState<EmojiSelectSheet> createState() => _EmojiSelectSheetState();
+}
 
+class _EmojiSelectSheetState extends ConsumerState<EmojiSelectSheet> {
+  final isDesktop = Util.isDesktop;
+
+  late final TextEditingController _searchController;
+  late final FocusNode _searchFocusNode;
+  late final double horizontalPadding = 24;
+  late final double emojiSize = 24;
+  late final double minimumEmojiSpacing = 25;
+
+  String _searchTerm = "";
+
+  List<Emoji> filtered(String text) {
+    if (text.isEmpty) {
+      return Emoji.all();
+    }
+
+    text = text.toLowerCase();
+
+    return Emoji.all()
+        .where((e) => e.keywords
+            .where(
+              (e) => e.contains(text),
+            )
+            .isNotEmpty)
+        .toList(growable: false);
+  }
+
+  @override
+  void initState() {
+    _searchController = TextEditingController();
+    _searchFocusNode = FocusNode();
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    _searchController.dispose();
+    _searchFocusNode.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
     final size = isDesktop ? const Size(600, 700) : MediaQuery.of(context).size;
-    final double maxHeight = size.height * 0.60;
-    final double availableWidth = size.width - (2 * horizontalPadding);
-    final int emojisPerRow =
+    final maxHeight = size.height * (isDesktop ? 0.6 : 0.9);
+    final availableWidth = size.width - (2 * horizontalPadding);
+    final emojisPerRow =
         ((availableWidth - emojiSize) ~/ (emojiSize + minimumEmojiSpacing)) + 1;
 
-    final itemCount = Emoji.all().length;
-
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) => Container(
@@ -81,40 +128,101 @@ class EmojiSelectSheet extends ConsumerWidget {
                 : STextStyles.pageTitleH2(context),
             textAlign: TextAlign.left,
           ),
+          SizedBox(
+            height: isDesktop ? 16 : 12,
+          ),
+          ClipRRect(
+            borderRadius: BorderRadius.circular(
+              Constants.size.circularBorderRadius,
+            ),
+            child: TextField(
+              autocorrect: Util.isDesktop ? false : true,
+              enableSuggestions: Util.isDesktop ? false : true,
+              controller: _searchController,
+              focusNode: _searchFocusNode,
+              onChanged: (newString) {
+                setState(() => _searchTerm = newString);
+              },
+              style: STextStyles.field(context),
+              decoration: standardInputDecoration(
+                "Search",
+                _searchFocusNode,
+                context,
+              ).copyWith(
+                prefixIcon: Padding(
+                  padding: const EdgeInsets.symmetric(
+                    horizontal: 10,
+                    vertical: 16,
+                  ),
+                  child: SvgPicture.asset(
+                    Assets.svg.search,
+                    width: 16,
+                    height: 16,
+                  ),
+                ),
+                suffixIcon: _searchController.text.isNotEmpty
+                    ? Padding(
+                        padding: const EdgeInsets.only(right: 0),
+                        child: UnconstrainedBox(
+                          child: Row(
+                            children: [
+                              TextFieldIconButton(
+                                child: const XIcon(),
+                                onTap: () async {
+                                  setState(() {
+                                    _searchController.text = "";
+                                    _searchTerm = "";
+                                  });
+                                },
+                              ),
+                            ],
+                          ),
+                        ),
+                      )
+                    : null,
+              ),
+            ),
+          ),
           SizedBox(
             height: isDesktop ? 28 : 16,
           ),
-          Flexible(
+          Expanded(
             child: Row(
               mainAxisAlignment: MainAxisAlignment.center,
               children: [
-                Flexible(
-                  child: GridView.builder(
-                    itemCount: itemCount,
-                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
-                      crossAxisCount: emojisPerRow,
-                    ),
-                    itemBuilder: (context, index) {
-                      final emoji = Emoji.all()[index];
-                      return GestureDetector(
-                        onTap: () {
-                          Navigator.of(context).pop(emoji);
-                        },
-                        child: Container(
-                          decoration: BoxDecoration(
-                            borderRadius: BorderRadius.circular(100),
-                            color: Colors.transparent,
-                          ),
-                          child: Padding(
-                            padding: const EdgeInsets.all(8.0),
-                            child: Text(
-                              emoji.char,
-                              style: isDesktop
-                                  ? STextStyles.desktopTextSmall(context)
-                                  : null,
-                            ),
-                          ),
+                Expanded(
+                  child: Builder(
+                    builder: (context) {
+                      final emojis = filtered(_searchTerm);
+                      final itemCount = emojis.length;
+                      return GridView.builder(
+                        itemCount: itemCount,
+                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+                          crossAxisCount: emojisPerRow,
                         ),
+                        itemBuilder: (context, index) {
+                          final emoji = emojis[index];
+                          return GestureDetector(
+                            onTap: () {
+                              Navigator.of(context).pop(emoji);
+                            },
+                            child: Container(
+                              decoration: BoxDecoration(
+                                borderRadius: BorderRadius.circular(100),
+                                color: Colors.transparent,
+                              ),
+                              child: Padding(
+                                padding: const EdgeInsets.all(8.0),
+                                child: Text(
+                                  emoji.char,
+                                  style: isDesktop
+                                      ? STextStyles.desktopTextSmall(context)
+                                      : null,
+                                ),
+                              ),
+                            ),
+                          );
+                        },
                       );
                     },
                   ),

From 9fce8ca107b1ce1dae9d96184b4f5affd2576840 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 25 Nov 2022 17:14:06 -0600
Subject: [PATCH 408/426] familiarity fix

---
 lib/hive/db.dart                              | 12 ------
 lib/main.dart                                 |  5 +++
 .../global_settings_view/hidden_settings.dart | 37 +++++++++++++++++++
 lib/utilities/prefs.dart                      | 22 +++++++++++
 4 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/lib/hive/db.dart b/lib/hive/db.dart
index 48e6ba154..1a52d64df 100644
--- a/lib/hive/db.dart
+++ b/lib/hive/db.dart
@@ -9,7 +9,6 @@ import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/models/notification_model.dart';
 import 'package:stackwallet/models/trade_wallet_lookup.dart';
 import 'package:stackwallet/services/wallets_service.dart';
-import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 
@@ -151,17 +150,6 @@ class DB {
         _loadSharedCoinCacheBoxes(),
       ]);
       _initialized = true;
-
-      try {
-        if (_boxPrefs!.get("familiarity") == null) {
-          await _boxPrefs!.put("familiarity", 0);
-        }
-        int count = _boxPrefs!.get("familiarity") as int;
-        await _boxPrefs!.put("familiarity", count + 1);
-        Constants.exchangeForExperiencedUsers(count + 1);
-      } catch (e, s) {
-        print("$e $s");
-      }
     }
   }
 
diff --git a/lib/main.dart b/lib/main.dart
index d5980409f..2086d351e 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -235,6 +235,11 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
     await DB.instance.init();
     await ref.read(prefsChangeNotifierProvider).init();
 
+    final familiarity = ref.read(prefsChangeNotifierProvider).familiarity + 1;
+    ref.read(prefsChangeNotifierProvider).familiarity = familiarity;
+
+    Constants.exchangeForExperiencedUsers(familiarity);
+
     if (Util.isDesktop) {
       _desktopHasPassword =
           await ref.read(storageCryptoHandlerProvider).hasPassword();
diff --git a/lib/pages/settings_views/global_settings_view/hidden_settings.dart b/lib/pages/settings_views/global_settings_view/hidden_settings.dart
index 7f35fcc86..d92b166d7 100644
--- a/lib/pages/settings_views/global_settings_view/hidden_settings.dart
+++ b/lib/pages/settings_views/global_settings_view/hidden_settings.dart
@@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/providers/global/debug_service_provider.dart';
 import 'package:stackwallet/providers/providers.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/widgets/background.dart';
@@ -127,6 +128,42 @@ class HiddenSettings extends StatelessWidget {
                             ),
                           );
                         }),
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        Consumer(
+                          builder: (_, ref, __) {
+                            if (ref.watch(prefsChangeNotifierProvider
+                                    .select((value) => value.familiarity)) <
+                                6) {
+                              return GestureDetector(
+                                onTap: () async {
+                                  final familiarity = ref
+                                      .read(prefsChangeNotifierProvider)
+                                      .familiarity;
+                                  if (familiarity < 6) {
+                                    ref
+                                        .read(prefsChangeNotifierProvider)
+                                        .familiarity = 6;
+
+                                    Constants.exchangeForExperiencedUsers(6);
+                                  }
+                                },
+                                child: RoundedWhiteContainer(
+                                  child: Text(
+                                    "Enable exchange",
+                                    style: STextStyles.button(context).copyWith(
+                                        color: Theme.of(context)
+                                            .extension<StackColors>()!
+                                            .accentColorDark),
+                                  ),
+                                ),
+                              );
+                            } else {
+                              return Container();
+                            }
+                          },
+                        ),
                         // const SizedBox(
                         //   height: 12,
                         // ),
diff --git a/lib/utilities/prefs.dart b/lib/utilities/prefs.dart
index 246291053..6b4b9821a 100644
--- a/lib/utilities/prefs.dart
+++ b/lib/utilities/prefs.dart
@@ -37,6 +37,7 @@ class Prefs extends ChangeNotifier {
       _gotoWalletOnStartup = await _getGotoWalletOnStartup();
       _startupWalletId = await _getStartupWalletId();
       _externalCalls = await _getHasExternalCalls();
+      _familiarity = await _getHasFamiliarity();
 
       _initialized = true;
     }
@@ -328,6 +329,27 @@ class Prefs extends ChangeNotifier {
         false;
   }
 
+  // familiarity
+
+  int _familiarity = 0;
+
+  int get familiarity => _familiarity;
+
+  set familiarity(int familiarity) {
+    if (_familiarity != familiarity) {
+      DB.instance.put<dynamic>(
+          boxName: DB.boxNamePrefs, key: "familiarity", value: familiarity);
+      _familiarity = familiarity;
+      notifyListeners();
+    }
+  }
+
+  Future<int> _getHasFamiliarity() async {
+    return await DB.instance.get<dynamic>(
+            boxName: DB.boxNamePrefs, key: "familiarity") as int? ??
+        0;
+  }
+
   // show testnet coins
 
   bool _showTestNetCoins = false;

From 56f54ac4872e8f063e20ab01cac53f6844f6e54d Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Fri, 25 Nov 2022 17:49:47 -0600
Subject: [PATCH 409/426] clean up and test fixes

---
 lib/widgets/background.dart                   | 10 +-
 lib/widgets/emoji_select_sheet.dart           | 97 ++++++++++---------
 .../widget_tests/emoji_select_sheet_test.dart | 14 ++-
 3 files changed, 63 insertions(+), 58 deletions(-)

diff --git a/lib/widgets/background.dart b/lib/widgets/background.dart
index 4f70f5252..67ff44f55 100644
--- a/lib/widgets/background.dart
+++ b/lib/widgets/background.dart
@@ -1,13 +1,11 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/providers/ui/color_theme_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/theme/color_theme.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 
-class Background extends ConsumerWidget {
+class Background extends StatelessWidget {
   const Background({
     Key? key,
     required this.child,
@@ -16,12 +14,10 @@ class Background extends ConsumerWidget {
   final Widget child;
 
   @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final colorTheme = ref.watch(colorThemeProvider.state).state;
-
+  Widget build(BuildContext context) {
     Color? color;
 
-    switch (colorTheme.themeType) {
+    switch (Theme.of(context).extension<StackColors>()!.themeType) {
       case ThemeType.light:
       case ThemeType.dark:
         color = Theme.of(context).extension<StackColors>()!.background;
diff --git a/lib/widgets/emoji_select_sheet.dart b/lib/widgets/emoji_select_sheet.dart
index d5a37d142..ecb6d1a1b 100644
--- a/lib/widgets/emoji_select_sheet.dart
+++ b/lib/widgets/emoji_select_sheet.dart
@@ -131,55 +131,58 @@ class _EmojiSelectSheetState extends ConsumerState<EmojiSelectSheet> {
           SizedBox(
             height: isDesktop ? 16 : 12,
           ),
-          ClipRRect(
-            borderRadius: BorderRadius.circular(
-              Constants.size.circularBorderRadius,
-            ),
-            child: TextField(
-              autocorrect: Util.isDesktop ? false : true,
-              enableSuggestions: Util.isDesktop ? false : true,
-              controller: _searchController,
-              focusNode: _searchFocusNode,
-              onChanged: (newString) {
-                setState(() => _searchTerm = newString);
-              },
-              style: STextStyles.field(context),
-              decoration: standardInputDecoration(
-                "Search",
-                _searchFocusNode,
-                context,
-              ).copyWith(
-                prefixIcon: Padding(
-                  padding: const EdgeInsets.symmetric(
-                    horizontal: 10,
-                    vertical: 16,
+          Material(
+            color: Colors.transparent,
+            child: ClipRRect(
+              borderRadius: BorderRadius.circular(
+                Constants.size.circularBorderRadius,
+              ),
+              child: TextField(
+                autocorrect: Util.isDesktop ? false : true,
+                enableSuggestions: Util.isDesktop ? false : true,
+                controller: _searchController,
+                focusNode: _searchFocusNode,
+                onChanged: (newString) {
+                  setState(() => _searchTerm = newString);
+                },
+                style: STextStyles.field(context),
+                decoration: standardInputDecoration(
+                  "Search",
+                  _searchFocusNode,
+                  context,
+                ).copyWith(
+                  prefixIcon: Padding(
+                    padding: const EdgeInsets.symmetric(
+                      horizontal: 10,
+                      vertical: 16,
+                    ),
+                    child: SvgPicture.asset(
+                      Assets.svg.search,
+                      width: 16,
+                      height: 16,
+                    ),
                   ),
-                  child: SvgPicture.asset(
-                    Assets.svg.search,
-                    width: 16,
-                    height: 16,
-                  ),
-                ),
-                suffixIcon: _searchController.text.isNotEmpty
-                    ? Padding(
-                        padding: const EdgeInsets.only(right: 0),
-                        child: UnconstrainedBox(
-                          child: Row(
-                            children: [
-                              TextFieldIconButton(
-                                child: const XIcon(),
-                                onTap: () async {
-                                  setState(() {
-                                    _searchController.text = "";
-                                    _searchTerm = "";
-                                  });
-                                },
-                              ),
-                            ],
+                  suffixIcon: _searchController.text.isNotEmpty
+                      ? Padding(
+                          padding: const EdgeInsets.only(right: 0),
+                          child: UnconstrainedBox(
+                            child: Row(
+                              children: [
+                                TextFieldIconButton(
+                                  child: const XIcon(),
+                                  onTap: () async {
+                                    setState(() {
+                                      _searchController.text = "";
+                                      _searchTerm = "";
+                                    });
+                                  },
+                                ),
+                              ],
+                            ),
                           ),
-                        ),
-                      )
-                    : null,
+                        )
+                      : null,
+                ),
               ),
             ),
           ),
diff --git a/test/widget_tests/emoji_select_sheet_test.dart b/test/widget_tests/emoji_select_sheet_test.dart
index 368a1d99b..aec05d580 100644
--- a/test/widget_tests/emoji_select_sheet_test.dart
+++ b/test/widget_tests/emoji_select_sheet_test.dart
@@ -1,8 +1,8 @@
 import 'package:emojis/emoji.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:mockingjay/mockingjay.dart' as mockingjay;
 import 'package:flutter_test/flutter_test.dart';
+import 'package:mockingjay/mockingjay.dart' as mockingjay;
 import 'package:stackwallet/utilities/theme/light_colors.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/emoji_select_sheet.dart';
@@ -43,15 +43,21 @@ void main() {
             ],
           ),
           home: mockingjay.MockNavigatorProvider(
-              navigator: navigator, child: emojiSelectSheet),
+            navigator: navigator,
+            child: Column(
+              children: const [
+                Expanded(child: emojiSelectSheet),
+              ],
+            ),
+          ),
         ),
       ),
     );
 
-    final gestureDetector = find.byType(GestureDetector).first;
+    final gestureDetector = find.byType(GestureDetector).at(5);
     expect(gestureDetector, findsOneWidget);
 
-    final emoji = Emoji.all()[0];
+    final emoji = Emoji.byChar("😅");
 
     await tester.tap(gestureDetector);
     await tester.pumpAndSettle();

From 8f157ccfc4dcc5e4ed3b1313b70e61b40746aa93 Mon Sep 17 00:00:00 2001
From: Diego Salazar <diego@cypherstack.com>
Date: Sat, 26 Nov 2022 13:12:38 -0700
Subject: [PATCH 410/426] Bump version. Mm!

---
 pubspec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index 2397fbfbc..ef1b495a5 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.19+91
+version: 1.5.20+92
 
 environment:
   sdk: ">=2.17.0 <3.0.0"

From d0b2a5a3fed1a41382ce109c85d9e55b45c37e01 Mon Sep 17 00:00:00 2001
From: Dan Miller <dan@cypherstack.com>
Date: Mon, 28 Nov 2022 08:59:23 -0800
Subject: [PATCH 411/426] Add tomli python lib to build script comment.

---
 scripts/linux/build_secure_storage_deps.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/linux/build_secure_storage_deps.sh b/scripts/linux/build_secure_storage_deps.sh
index 7a725d65c..69b452e2d 100755
--- a/scripts/linux/build_secure_storage_deps.sh
+++ b/scripts/linux/build_secure_storage_deps.sh
@@ -20,7 +20,7 @@ cd "$LINUX_DIRECTORY" || exit
 # Build libSecret
 # sudo apt install meson libgirepository1.0-dev valac xsltproc gi-docgen docbook-xsl
 # sudo apt install python3-pip
-#pip3 install --user meson markdown --upgrade
+#pip3 install --user meson markdown tomli --upgrade
 # pip3 install --user gi-docgen
 cd build || exit
 git -C libsecret pull || git clone https://gitlab.gnome.org/GNOME/libsecret.git libsecret

From 76e0616ade79a9ef56012e80a4f4e0ede7eb825d Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 28 Nov 2022 10:40:45 -0700
Subject: [PATCH 412/426] view backup keys text changed for wallet deletion

---
 .../wallet_view/sub_widgets/delete_wallet_keys_popup.dart      | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
index 70f4a3e13..a2d58465b 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
@@ -95,7 +95,8 @@ class _DeleteWalletKeysPopup extends ConsumerState<DeleteWalletKeysPopup> {
                 horizontal: 32,
               ),
               child: Text(
-                "Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
+                "Please write down your recovery phrase in the correct order and "
+                "save it to keep your funds secure. You will be shown your recovery phrase on the next screen.",
                 style: STextStyles.desktopTextExtraExtraSmall(context),
                 textAlign: TextAlign.center,
               ),

From 8960bb576464ecd5ac415cfa3494a53077d10677 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 28 Nov 2022 12:46:35 -0600
Subject: [PATCH 413/426] linux small screen width check

---
 lib/main.dart           |  8 +++++++-
 lib/utilities/util.dart | 14 ++++++++++++--
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/lib/main.dart b/lib/main.dart
index 2086d351e..a49bcab82 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -76,11 +76,17 @@ void main() async {
     Util.libraryPath = await getLibraryDirectory();
   }
 
+  Screen? screen;
+  if (Platform.isLinux || Util.isDesktop) {
+    screen = await getCurrentScreen();
+    Util.screenWidth = screen?.frame.width;
+  }
+
   if (Util.isDesktop) {
     setWindowTitle('Stack Wallet');
     setWindowMinSize(const Size(1220, 100));
     setWindowMaxSize(Size.infinite);
-    final screen = await getCurrentScreen();
+
     final screenHeight = screen?.frame.height;
     if (screenHeight != null) {
       // starting to height be 3/4 screen height or 900, whichever is smaller
diff --git a/lib/utilities/util.dart b/lib/utilities/util.dart
index 5963bfee9..2940b6d40 100644
--- a/lib/utilities/util.dart
+++ b/lib/utilities/util.dart
@@ -1,14 +1,24 @@
 import 'dart:io';
 
 import 'package:flutter/material.dart';
-import 'package:path_provider/path_provider.dart';
 
 abstract class Util {
   static Directory? libraryPath;
+  static double? screenWidth;
+
   static bool get isDesktop {
-    if(Platform.isIOS && libraryPath != null && !libraryPath!.path.contains("/var/mobile/")){
+    // special check for running on linux based phones
+    if (Platform.isLinux && screenWidth != null && screenWidth! < 800) {
+      return false;
+    }
+
+    // special check for running under ipad mode in macos
+    if (Platform.isIOS &&
+        libraryPath != null &&
+        !libraryPath!.path.contains("/var/mobile/")) {
       return true;
     }
+
     return Platform.isLinux || Platform.isMacOS || Platform.isWindows;
   }
 

From 66ff5a437dd8a00bb55687aacbfc4fc5139f91e5 Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 28 Nov 2022 11:51:13 -0700
Subject: [PATCH 414/426] reverted mobile restore calendar height

---
 .../restore_options_view/restore_options_view.dart              | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
index ac84964ca..1ce5d713a 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
@@ -155,7 +155,7 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
     final date = await showRoundedDatePicker(
       context: context,
       initialDate: DateTime.now(),
-      height: height / 3.2,
+      height: height * 0.5,
       theme: ThemeData(
         primarySwatch: Util.createMaterialColor(fetchedColor),
       ),

From 221e654dd669b24e5e4426131947098b47774b21 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 28 Nov 2022 13:50:55 -0600
Subject: [PATCH 415/426] animated main menu

---
 .../home/desktop_menu.dart                    |  92 +++++++++++---
 .../home/desktop_menu_item.dart               | 119 +++++++++++++++---
 2 files changed, 174 insertions(+), 37 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_menu.dart b/lib/pages_desktop_specific/home/desktop_menu.dart
index d82d62883..6ae4b91a1 100644
--- a/lib/pages_desktop_specific/home/desktop_menu.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu.dart
@@ -38,6 +38,9 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
   static const expandedWidth = 225.0;
   static const minimizedWidth = 72.0;
 
+  final Duration duration = const Duration(milliseconds: 250);
+  late final List<DMIController> controllers;
+
   double _width = expandedWidth;
 
   void updateSelectedMenuItem(DesktopMenuItemId idKey) {
@@ -49,26 +52,58 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
   }
 
   void toggleMinimize() {
+    final expanded = _width == expandedWidth;
+
+    for (var e in controllers) {
+      e.toggle?.call();
+    }
+
     setState(() {
-      _width = _width == expandedWidth ? minimizedWidth : expandedWidth;
+      _width = expanded ? minimizedWidth : expandedWidth;
     });
   }
 
+  @override
+  void initState() {
+    controllers = [
+      DMIController(),
+      DMIController(),
+      DMIController(),
+      DMIController(),
+      DMIController(),
+      DMIController(),
+      DMIController(),
+      DMIController(),
+    ];
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    for (var e in controllers) {
+      e.dispose();
+    }
+    super.dispose();
+  }
+
   @override
   Widget build(BuildContext context) {
     return Material(
       color: Theme.of(context).extension<StackColors>()!.popupBG,
-      child: SizedBox(
+      child: AnimatedContainer(
         width: _width,
+        duration: duration,
         child: Column(
           crossAxisAlignment: CrossAxisAlignment.center,
           children: [
-            SizedBox(
-              height: _width == expandedWidth ? 22 : 25,
+            const SizedBox(
+              height: 25,
             ),
-            SizedBox(
+            AnimatedContainer(
+              duration: duration,
               width: _width == expandedWidth ? 70 : 32,
-              height: _width == expandedWidth ? 70 : 32,
+              height: 70, //_width == expandedWidth ? 70 : 32,
               child: SvgPicture.asset(
                 Assets.svg.stackIcon(context),
               ),
@@ -76,18 +111,26 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
             const SizedBox(
               height: 10,
             ),
-            Text(
-              _width == expandedWidth ? "Stack Wallet" : "",
-              style: STextStyles.desktopH2(context).copyWith(
-                fontSize: 18,
-                height: 23.4 / 18,
+            AnimatedOpacity(
+              duration: duration,
+              opacity: _width == expandedWidth ? 1 : 0,
+              child: SizedBox(
+                height: 28,
+                child: Text(
+                  "Stack Wallet",
+                  style: STextStyles.desktopH2(context).copyWith(
+                    fontSize: 18,
+                    height: 23.4 / 18,
+                  ),
+                ),
               ),
             ),
             const SizedBox(
               height: 60,
             ),
             Expanded(
-              child: SizedBox(
+              child: AnimatedContainer(
+                duration: duration,
                 width: _width == expandedWidth
                     ? _width - 32 // 16 padding on either side
                     : _width - 16, // 8 padding on either side
@@ -95,6 +138,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                   crossAxisAlignment: CrossAxisAlignment.stretch,
                   children: [
                     DesktopMenuItem(
+                      duration: duration,
                       icon: SvgPicture.asset(
                         Assets.svg.walletDesktop,
                         width: 20,
@@ -116,12 +160,13 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       group:
                           ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
-                      iconOnly: _width == minimizedWidth,
+                      controller: controllers[0],
                     ),
                     const SizedBox(
                       height: 2,
                     ),
                     DesktopMenuItem(
+                      duration: duration,
                       icon: SvgPicture.asset(
                         Assets.svg.exchangeDesktop,
                         width: 20,
@@ -143,12 +188,13 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       group:
                           ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
-                      iconOnly: _width == minimizedWidth,
+                      controller: controllers[1],
                     ),
                     const SizedBox(
                       height: 2,
                     ),
                     DesktopMenuItem(
+                      duration: duration,
                       icon: SvgPicture.asset(
                         ref.watch(notificationsProvider.select(
                                 (value) => value.hasUnreadNotifications))
@@ -177,12 +223,13 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       group:
                           ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
-                      iconOnly: _width == minimizedWidth,
+                      controller: controllers[2],
                     ),
                     const SizedBox(
                       height: 2,
                     ),
                     DesktopMenuItem(
+                      duration: duration,
                       icon: SvgPicture.asset(
                         Assets.svg.addressBookDesktop,
                         width: 20,
@@ -204,12 +251,13 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       group:
                           ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
-                      iconOnly: _width == minimizedWidth,
+                      controller: controllers[3],
                     ),
                     const SizedBox(
                       height: 2,
                     ),
                     DesktopMenuItem(
+                      duration: duration,
                       icon: SvgPicture.asset(
                         Assets.svg.gear,
                         width: 20,
@@ -231,12 +279,13 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       group:
                           ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
-                      iconOnly: _width == minimizedWidth,
+                      controller: controllers[4],
                     ),
                     const SizedBox(
                       height: 2,
                     ),
                     DesktopMenuItem(
+                      duration: duration,
                       icon: SvgPicture.asset(
                         Assets.svg.messageQuestion,
                         width: 20,
@@ -258,12 +307,13 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       group:
                           ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
-                      iconOnly: _width == minimizedWidth,
+                      controller: controllers[5],
                     ),
                     const SizedBox(
                       height: 2,
                     ),
                     DesktopMenuItem(
+                      duration: duration,
                       icon: SvgPicture.asset(
                         Assets.svg.aboutDesktop,
                         width: 20,
@@ -285,10 +335,12 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       group:
                           ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
-                      iconOnly: _width == minimizedWidth,
+                      controller: controllers[6],
                     ),
                     const Spacer(),
                     DesktopMenuItem(
+                      duration: duration,
+                      labelLength: 123,
                       icon: SvgPicture.asset(
                         Assets.svg.exitDesktop,
                         width: 20,
@@ -306,7 +358,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                         // todo: save stuff/ notify before exit?
                         exit(0);
                       },
-                      iconOnly: _width == minimizedWidth,
+                      controller: controllers[7],
                     ),
                   ],
                 ),
diff --git a/lib/pages_desktop_specific/home/desktop_menu_item.dart b/lib/pages_desktop_specific/home/desktop_menu_item.dart
index 76d945e2d..e73a4a477 100644
--- a/lib/pages_desktop_specific/home/desktop_menu_item.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu_item.dart
@@ -2,7 +2,14 @@ import 'package:flutter/material.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
-class DesktopMenuItem<T> extends StatelessWidget {
+class DMIController {
+  VoidCallback? toggle;
+  void dispose() {
+    toggle = null;
+  }
+}
+
+class DesktopMenuItem<T> extends StatefulWidget {
   const DesktopMenuItem({
     Key? key,
     required this.icon,
@@ -10,7 +17,9 @@ class DesktopMenuItem<T> extends StatelessWidget {
     required this.value,
     required this.group,
     required this.onChanged,
-    required this.iconOnly,
+    required this.duration,
+    this.labelLength = 125,
+    this.controller,
   }) : super(key: key);
 
   final Widget icon;
@@ -18,7 +27,67 @@ class DesktopMenuItem<T> extends StatelessWidget {
   final T value;
   final T group;
   final void Function(T) onChanged;
-  final bool iconOnly;
+  final Duration duration;
+  final double labelLength;
+  final DMIController? controller;
+
+  @override
+  State<DesktopMenuItem<T>> createState() => _DesktopMenuItemState<T>();
+}
+
+class _DesktopMenuItemState<T> extends State<DesktopMenuItem<T>>
+    with SingleTickerProviderStateMixin {
+  late final Widget icon;
+  late final String label;
+  late final T value;
+  late final T group;
+  late final void Function(T) onChanged;
+  late final Duration duration;
+  late final double labelLength;
+
+  late final DMIController? controller;
+
+  late final AnimationController animationController;
+
+  bool _iconOnly = false;
+
+  void toggle() {
+    setState(() {
+      _iconOnly = !_iconOnly;
+    });
+    if (_iconOnly) {
+      animationController.reverse();
+    } else {
+      animationController.forward();
+    }
+  }
+
+  @override
+  void initState() {
+    icon = widget.icon;
+    label = widget.label;
+    value = widget.value;
+    group = widget.group;
+    onChanged = widget.onChanged;
+    duration = widget.duration;
+    labelLength = widget.labelLength;
+    controller = widget.controller;
+
+    controller?.toggle = toggle;
+    animationController = AnimationController(
+      vsync: this,
+      duration: duration,
+    );
+
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    controller?.dispose();
+    animationController.dispose();
+    super.dispose();
+  }
 
   @override
   Widget build(BuildContext context) {
@@ -34,26 +103,42 @@ class DesktopMenuItem<T> extends StatelessWidget {
         onChanged(value);
       },
       child: Padding(
-        padding: EdgeInsets.symmetric(
+        padding: const EdgeInsets.symmetric(
           vertical: 16,
-          horizontal: iconOnly ? 0 : 16,
         ),
         child: Row(
-          mainAxisAlignment:
-              iconOnly ? MainAxisAlignment.center : MainAxisAlignment.start,
+          mainAxisAlignment: MainAxisAlignment.center,
           children: [
+            AnimatedContainer(
+              duration: duration,
+              width: _iconOnly ? 0 : 16,
+            ),
             icon,
-            if (!iconOnly)
-              const SizedBox(
-                width: 12,
-              ),
-            if (!iconOnly)
-              Text(
-                label,
-                style: value == group
-                    ? STextStyles.desktopMenuItemSelected(context)
-                    : STextStyles.desktopMenuItem(context),
+            AnimatedOpacity(
+              duration: duration,
+              opacity: _iconOnly ? 0 : 1.0,
+              child: SizeTransition(
+                sizeFactor: animationController,
+                axis: Axis.horizontal,
+                axisAlignment: -1,
+                child: SizedBox(
+                  width: labelLength,
+                  child: Row(
+                    children: [
+                      const SizedBox(
+                        width: 12,
+                      ),
+                      Text(
+                        label,
+                        style: value == group
+                            ? STextStyles.desktopMenuItemSelected(context)
+                            : STextStyles.desktopMenuItem(context),
+                      ),
+                    ],
+                  ),
+                ),
               ),
+            )
           ],
         ),
       ),

From 6bbabcd729aa50d74e9351a3bb2948d740437b3a Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 28 Nov 2022 13:06:02 -0700
Subject: [PATCH 416/426] MyStackView tab after a restore backup

---
 .../sub_views/stack_restore_progress_view.dart  | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
index c7f53378d..92e7742e1 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/stack_restore_progress_view.dart
@@ -25,6 +25,9 @@ import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 
+import '../../../../../pages_desktop_specific/home/desktop_home_view.dart';
+import '../../../../../pages_desktop_specific/home/desktop_menu.dart';
+import '../../../../../providers/desktop/current_desktop_menu_item.dart';
 import '../../../../../widgets/desktop/primary_button.dart';
 
 class StackRestoreProgressView extends ConsumerStatefulWidget {
@@ -685,7 +688,19 @@ class _StackRestoreProgressViewState
                                   enabled: true,
                                   label: "Done",
                                   onPressed: () async {
-                                    Navigator.of(context).pop();
+                                    DesktopMenuItemId keyID =
+                                        DesktopMenuItemId.myStack;
+
+                                    ref
+                                        .read(currentDesktopMenuItemProvider
+                                            .state)
+                                        .state = keyID;
+
+                                    Navigator.of(context, rootNavigator: true)
+                                        .popUntil(
+                                      ModalRoute.withName(
+                                          DesktopHomeView.routeName),
+                                    );
                                   },
                                 )
                               : SecondaryButton(

From c3921b01de78978a13874b8c3457a4837bc8846a Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 28 Nov 2022 14:25:49 -0600
Subject: [PATCH 417/426] animated desktop stack icon

---
 .../home/desktop_menu.dart                    |  6 +--
 .../home/desktop_menu_item.dart               |  2 +-
 lib/widgets/desktop/living_stack_icon.dart    | 54 +++++++++++++++++++
 3 files changed, 58 insertions(+), 4 deletions(-)
 create mode 100644 lib/widgets/desktop/living_stack_icon.dart

diff --git a/lib/pages_desktop_specific/home/desktop_menu.dart b/lib/pages_desktop_specific/home/desktop_menu.dart
index 6ae4b91a1..8af307e7b 100644
--- a/lib/pages_desktop_specific/home/desktop_menu.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu.dart
@@ -9,6 +9,7 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/desktop/living_stack_icon.dart';
 
 enum DesktopMenuItemId {
   myStack,
@@ -103,9 +104,8 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
             AnimatedContainer(
               duration: duration,
               width: _width == expandedWidth ? 70 : 32,
-              height: 70, //_width == expandedWidth ? 70 : 32,
-              child: SvgPicture.asset(
-                Assets.svg.stackIcon(context),
+              child: LivingStackIcon(
+                onPressed: toggleMinimize,
               ),
             ),
             const SizedBox(
diff --git a/lib/pages_desktop_specific/home/desktop_menu_item.dart b/lib/pages_desktop_specific/home/desktop_menu_item.dart
index e73a4a477..1fb39213b 100644
--- a/lib/pages_desktop_specific/home/desktop_menu_item.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu_item.dart
@@ -77,7 +77,7 @@ class _DesktopMenuItemState<T> extends State<DesktopMenuItem<T>>
     animationController = AnimationController(
       vsync: this,
       duration: duration,
-    );
+    )..forward();
 
     super.initState();
   }
diff --git a/lib/widgets/desktop/living_stack_icon.dart b/lib/widgets/desktop/living_stack_icon.dart
new file mode 100644
index 000000000..7afc8f8d2
--- /dev/null
+++ b/lib/widgets/desktop/living_stack_icon.dart
@@ -0,0 +1,54 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:stackwallet/utilities/assets.dart';
+
+class LivingStackIcon extends StatefulWidget {
+  const LivingStackIcon({Key? key, this.onPressed,}) : super(key: key);
+
+  final VoidCallback? onPressed;
+
+  @override
+  State<LivingStackIcon> createState() => _LivingStackIconState();
+}
+
+class _LivingStackIconState extends State<LivingStackIcon> {
+  bool _hovering = false;
+
+  late final VoidCallback? onPressed;
+
+  @override
+  void initState() {
+    onPressed = widget.onPressed;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return SizedBox(
+      height: 76,
+      child: MouseRegion(
+        cursor: SystemMouseCursors.click,
+        onEnter: (_) {
+          setState(() {
+            _hovering = true;
+          });
+        },
+        onExit: (_) {
+          setState(() {
+            _hovering = false;
+          });
+        },
+        child: GestureDetector(
+          onTap: () => onPressed?.call(),
+          child: AnimatedScale(
+            duration: const Duration(milliseconds: 200),
+            scale: _hovering ? 1.2 : 1,
+            child: SvgPicture.asset(
+              Assets.svg.stackIcon(context),
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+}

From b4cbf078c7a1a6105fc76bd92715b97447802d9e Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 28 Nov 2022 13:50:55 -0700
Subject: [PATCH 418/426] flutter_rounded_date_picker files from picker lib

---
 .../flutter_rounded_date_picker_dialog.dart   | 332 ++++++++++++++++++
 .../flutter_rounded_date_picker_widget.dart   | 216 ++++++++++++
 2 files changed, 548 insertions(+)
 create mode 100644 lib/widgets/rounded_date_picker/flutter_rounded_date_picker_dialog.dart
 create mode 100644 lib/widgets/rounded_date_picker/flutter_rounded_date_picker_widget.dart

diff --git a/lib/widgets/rounded_date_picker/flutter_rounded_date_picker_dialog.dart b/lib/widgets/rounded_date_picker/flutter_rounded_date_picker_dialog.dart
new file mode 100644
index 000000000..6d7f775cd
--- /dev/null
+++ b/lib/widgets/rounded_date_picker/flutter_rounded_date_picker_dialog.dart
@@ -0,0 +1,332 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/semantics.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_rounded_date_picker/flutter_rounded_date_picker.dart';
+import 'package:flutter_rounded_date_picker/src/flutter_rounded_button_action.dart';
+import 'package:flutter_rounded_date_picker/src/material_rounded_date_picker_style.dart';
+import 'package:flutter_rounded_date_picker/src/material_rounded_year_picker_style.dart';
+import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_date_picker_header.dart';
+import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_day_picker.dart';
+import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_month_picker.dart';
+import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_year_picker.dart';
+import 'package:stackwallet/utilities/util.dart';
+
+///
+/// This file uses code taken from https://github.com/benznest/flutter_rounded_date_picker
+///
+
+class FlutterRoundedDatePickerDialog extends StatefulWidget {
+  const FlutterRoundedDatePickerDialog(
+      {Key? key,
+      this.height,
+      required this.initialDate,
+      required this.firstDate,
+      required this.lastDate,
+      this.selectableDayPredicate,
+      required this.initialDatePickerMode,
+      required this.era,
+      this.locale,
+      required this.borderRadius,
+      this.imageHeader,
+      this.description = "",
+      this.fontFamily,
+      this.textNegativeButton,
+      this.textPositiveButton,
+      this.textActionButton,
+      this.onTapActionButton,
+      this.styleDatePicker,
+      this.styleYearPicker,
+      this.customWeekDays,
+      this.builderDay,
+      this.listDateDisabled,
+      this.onTapDay,
+      this.onMonthChange})
+      : super(key: key);
+
+  final DateTime initialDate;
+  final DateTime firstDate;
+  final DateTime lastDate;
+  final SelectableDayPredicate? selectableDayPredicate;
+  final DatePickerMode initialDatePickerMode;
+
+  /// double height.
+  final double? height;
+
+  /// Custom era year.
+  final EraMode era;
+  final Locale? locale;
+
+  /// Border
+  final double borderRadius;
+
+  ///  Header;
+  final ImageProvider? imageHeader;
+  final String description;
+
+  /// Font
+  final String? fontFamily;
+
+  /// Button
+  final String? textNegativeButton;
+  final String? textPositiveButton;
+  final String? textActionButton;
+
+  final VoidCallback? onTapActionButton;
+
+  /// Style
+  final MaterialRoundedDatePickerStyle? styleDatePicker;
+  final MaterialRoundedYearPickerStyle? styleYearPicker;
+
+  /// Custom Weekday
+  final List<String>? customWeekDays;
+
+  final BuilderDayOfDatePicker? builderDay;
+
+  final List<DateTime>? listDateDisabled;
+  final OnTapDay? onTapDay;
+
+  final Function? onMonthChange;
+
+  @override
+  _FlutterRoundedDatePickerDialogState createState() =>
+      _FlutterRoundedDatePickerDialogState();
+}
+
+class _FlutterRoundedDatePickerDialogState
+    extends State<FlutterRoundedDatePickerDialog> {
+  @override
+  void initState() {
+    super.initState();
+    _selectedDate = widget.initialDate;
+    _mode = widget.initialDatePickerMode;
+  }
+
+  bool _announcedInitialDate = false;
+
+  late MaterialLocalizations localizations;
+  late TextDirection textDirection;
+
+  @override
+  void didChangeDependencies() {
+    super.didChangeDependencies();
+    localizations = MaterialLocalizations.of(context);
+    textDirection = Directionality.of(context);
+    if (!_announcedInitialDate) {
+      _announcedInitialDate = true;
+      SemanticsService.announce(
+        localizations.formatFullDate(_selectedDate),
+        textDirection,
+      );
+    }
+  }
+
+  late DateTime _selectedDate;
+  late DatePickerMode _mode;
+  final GlobalKey _pickerKey = GlobalKey();
+
+  void _vibrate() {
+    switch (Theme.of(context).platform) {
+      case TargetPlatform.android:
+      case TargetPlatform.fuchsia:
+        HapticFeedback.vibrate();
+        break;
+      case TargetPlatform.iOS:
+      default:
+        break;
+    }
+  }
+
+  void _handleModeChanged(DatePickerMode mode) {
+    _vibrate();
+    setState(() {
+      _mode = mode;
+      if (_mode == DatePickerMode.day) {
+        SemanticsService.announce(
+          localizations.formatMonthYear(_selectedDate),
+          textDirection,
+        );
+      } else {
+        SemanticsService.announce(
+          localizations.formatYear(_selectedDate),
+          textDirection,
+        );
+      }
+    });
+  }
+
+  Future<void> _handleYearChanged(DateTime value) async {
+    if (value.isBefore(widget.firstDate)) {
+      value = widget.firstDate;
+    } else if (value.isAfter(widget.lastDate)) {
+      value = widget.lastDate;
+    }
+    if (value == _selectedDate) return;
+
+    if (widget.onMonthChange != null) await widget.onMonthChange!(value);
+
+    _vibrate();
+    setState(() {
+      _mode = DatePickerMode.day;
+      _selectedDate = value;
+    });
+  }
+
+  void _handleDayChanged(DateTime value) {
+    _vibrate();
+    setState(() {
+      _selectedDate = value;
+    });
+  }
+
+  void _handleCancel() {
+    Navigator.of(context).pop();
+  }
+
+  void _handleOk() {
+    Navigator.of(context).pop(_selectedDate);
+  }
+
+  Widget _buildPicker() {
+    switch (_mode) {
+      case DatePickerMode.year:
+        return FlutterRoundedYearPicker(
+          key: _pickerKey,
+          selectedDate: _selectedDate,
+          onChanged: (DateTime date) async => await _handleYearChanged(date),
+          firstDate: widget.firstDate,
+          lastDate: widget.lastDate,
+          era: widget.era,
+          fontFamily: widget.fontFamily,
+          style: widget.styleYearPicker,
+        );
+      case DatePickerMode.day:
+      default:
+        return FlutterRoundedMonthPicker(
+            key: _pickerKey,
+            selectedDate: _selectedDate,
+            onChanged: _handleDayChanged,
+            firstDate: widget.firstDate,
+            lastDate: widget.lastDate,
+            era: widget.era,
+            locale: widget.locale,
+            selectableDayPredicate: widget.selectableDayPredicate,
+            fontFamily: widget.fontFamily,
+            style: widget.styleDatePicker,
+            borderRadius: widget.borderRadius,
+            customWeekDays: widget.customWeekDays,
+            builderDay: widget.builderDay,
+            listDateDisabled: widget.listDateDisabled,
+            onTapDay: widget.onTapDay,
+            onMonthChange: widget.onMonthChange);
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final ThemeData theme = Theme.of(context);
+    final Widget picker = _buildPicker();
+    final isDesktop = Util.isDesktop;
+
+    final Widget actions = FlutterRoundedButtonAction(
+      textButtonNegative: widget.textNegativeButton,
+      textButtonPositive: widget.textPositiveButton,
+      onTapButtonNegative: _handleCancel,
+      onTapButtonPositive: _handleOk,
+      textActionButton: widget.textActionButton,
+      onTapButtonAction: widget.onTapActionButton,
+      localizations: localizations,
+      textStyleButtonNegative: widget.styleDatePicker?.textStyleButtonNegative,
+      textStyleButtonPositive: widget.styleDatePicker?.textStyleButtonPositive,
+      textStyleButtonAction: widget.styleDatePicker?.textStyleButtonAction,
+      borderRadius: widget.borderRadius,
+      paddingActionBar: widget.styleDatePicker?.paddingActionBar,
+      background: widget.styleDatePicker?.backgroundActionBar,
+    );
+
+    Color backgroundPicker = theme.dialogBackgroundColor;
+    if (_mode == DatePickerMode.day) {
+      backgroundPicker = widget.styleDatePicker?.backgroundPicker ??
+          theme.dialogBackgroundColor;
+    } else {
+      backgroundPicker = widget.styleYearPicker?.backgroundPicker ??
+          theme.dialogBackgroundColor;
+    }
+
+    final Dialog dialog = Dialog(
+      child: OrientationBuilder(
+          builder: (BuildContext context, Orientation orientation) {
+        final Widget header = FlutterRoundedDatePickerHeader(
+            selectedDate: _selectedDate,
+            mode: _mode,
+            onModeChanged: _handleModeChanged,
+            orientation: orientation,
+            era: widget.era,
+            borderRadius: widget.borderRadius,
+            imageHeader: widget.imageHeader,
+            description: widget.description,
+            fontFamily: widget.fontFamily,
+            style: widget.styleDatePicker);
+        switch (orientation) {
+          case Orientation.landscape:
+            return Container(
+              height: isDesktop ? 600 : null,
+              width: isDesktop ? 700 : null,
+              decoration: BoxDecoration(
+                color: backgroundPicker,
+                borderRadius: BorderRadius.circular(widget.borderRadius),
+              ),
+              child: Row(
+                mainAxisSize: MainAxisSize.min,
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: <Widget>[
+                  Flexible(flex: 1, child: header),
+                  Flexible(
+                    flex: 2, // have the picker take up 2/3 of the dialog width
+                    child: Column(
+                      mainAxisSize: MainAxisSize.min,
+                      crossAxisAlignment: CrossAxisAlignment.stretch,
+                      children: <Widget>[
+                        SizedBox(
+                            height: isDesktop ? 530 : null,
+                            width: isDesktop ? 700 : null,
+                            child: picker),
+                        actions,
+                      ],
+                    ),
+                  ),
+                ],
+              ),
+            );
+          case Orientation.portrait:
+          default:
+            return Container(
+              decoration: BoxDecoration(
+                color: backgroundPicker,
+                borderRadius: BorderRadius.circular(widget.borderRadius),
+              ),
+              child: Column(
+                mainAxisSize: MainAxisSize.min,
+                crossAxisAlignment: CrossAxisAlignment.stretch,
+                children: <Widget>[
+                  header,
+                  if (widget.height == null)
+                    Flexible(child: picker)
+                  else
+                    SizedBox(
+                      height: widget.height,
+                      child: picker,
+                    ),
+                  actions,
+                ],
+              ),
+            );
+        }
+      }),
+    );
+
+    return Theme(
+      data: theme.copyWith(dialogBackgroundColor: Colors.transparent),
+      child: dialog,
+    );
+  }
+}
diff --git a/lib/widgets/rounded_date_picker/flutter_rounded_date_picker_widget.dart b/lib/widgets/rounded_date_picker/flutter_rounded_date_picker_widget.dart
new file mode 100644
index 000000000..5f576f480
--- /dev/null
+++ b/lib/widgets/rounded_date_picker/flutter_rounded_date_picker_widget.dart
@@ -0,0 +1,216 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart';
+import 'package:flutter/widgets.dart';
+// import 'package:flutter_rounded_date_picker/src/dialogs/flutter_rounded_date_picker_dialog.dart';
+import 'package:flutter_rounded_date_picker/src/era_mode.dart';
+import 'package:flutter_rounded_date_picker/src/material_rounded_date_picker_style.dart';
+import 'package:flutter_rounded_date_picker/src/material_rounded_year_picker_style.dart';
+import 'package:flutter_rounded_date_picker/src/widgets/flutter_rounded_day_picker.dart';
+import 'package:stackwallet/widgets/rounded_date_picker/flutter_rounded_date_picker_dialog.dart';
+
+///
+/// This file uses code taken from https://github.com/benznest/flutter_rounded_date_picker
+///
+
+// Examples can assume:
+// BuildContext context;
+
+/// Initial display mode of the date picker dialog.
+///
+/// Date picker UI mode for either showing a list of available years or a
+/// monthly calendar initially in the dialog shown by calling [showDatePicker].
+///
+
+// Shows the selected date in large font and toggles between year and day mode
+
+/// Signature for predicating dates for enabled date selections.
+///
+/// See [showDatePicker].
+typedef SelectableDayPredicate = bool Function(DateTime day);
+
+/// Shows a dialog containing a material design date picker.
+///
+/// The returned [Future] resolves to the date selected by the user when the
+/// user closes the dialog. If the user cancels the dialog, null is returned.
+///
+/// An optional [selectableDayPredicate] function can be passed in to customize
+/// the days to enable for selection. If provided, only the days that
+/// [selectableDayPredicate] returned true for will be selectable.
+///
+/// An optional [initialDatePickerMode] argument can be used to display the
+/// date picker initially in the year or month+day picker mode. It defaults
+/// to month+day, and must not be null.
+///
+/// An optional [locale] argument can be used to set the locale for the date
+/// picker. It defaults to the ambient locale provided by [Localizations].
+///
+/// An optional [textDirection] argument can be used to set the text direction
+/// (RTL or LTR) for the date picker. It defaults to the ambient text direction
+/// provided by [Directionality]. If both [locale] and [textDirection] are not
+/// null, [textDirection] overrides the direction chosen for the [locale].
+///
+/// The [context] argument is passed to [showDialog], the documentation for
+/// which discusses how it is used.
+///
+/// The [builder] parameter can be used to wrap the dialog widget
+/// to add inherited widgets like [Theme].
+///
+/// {@tool sample}
+/// Show a date picker with the dark theme.
+///
+/// ```dart
+/// Future<DateTime> selectedDate = showDatePicker(
+///   context: context,
+///   initialDate: DateTime.now(),
+///   firstDate: DateTime(2018),
+///   lastDate: DateTime(2030),
+///   builder: (BuildContext context, Widget child) {
+///     return Theme(
+///       data: ThemeData.dark(),
+///       child: child,
+///     );
+///   },
+/// );
+/// ```
+/// {@end-tool}
+///
+/// The [context], [initialDate], [firstDate], and [lastDate] parameters must
+/// not be null.
+///
+/// See also:
+///
+///  * [showTimePicker], which shows a dialog that contains a material design
+///    time picker.
+///  * [DayPicker], which displays the days of a given month and allows
+///    choosing a day.
+///  * [MonthPicker], which displays a scrollable list of months to allow
+///    picking a month.
+///  * [YearPicker], which displays a scrollable list of years to allow picking
+///    a year.
+///
+
+Future<DateTime?> showRoundedDatePicker(
+    {required BuildContext context,
+    double? height,
+    DateTime? initialDate,
+    DateTime? firstDate,
+    DateTime? lastDate,
+    SelectableDayPredicate? selectableDayPredicate,
+    DatePickerMode initialDatePickerMode = DatePickerMode.day,
+    Locale? locale,
+    TextDirection? textDirection,
+    ThemeData? theme,
+    double borderRadius = 16,
+    EraMode era = EraMode.CHRIST_YEAR,
+    ImageProvider? imageHeader,
+    String description = "",
+    String? fontFamily,
+    bool barrierDismissible = false,
+    Color background = Colors.transparent,
+    String? textNegativeButton,
+    String? textPositiveButton,
+    String? textActionButton,
+    VoidCallback? onTapActionButton,
+    MaterialRoundedDatePickerStyle? styleDatePicker,
+    MaterialRoundedYearPickerStyle? styleYearPicker,
+    List<String>? customWeekDays,
+    BuilderDayOfDatePicker? builderDay,
+    List<DateTime>? listDateDisabled,
+    OnTapDay? onTapDay,
+    Function? onMonthChange}) async {
+  initialDate ??= DateTime.now();
+  firstDate ??= DateTime(initialDate.year - 1);
+  lastDate ??= DateTime(initialDate.year + 1);
+  theme ??= ThemeData();
+
+  assert(
+    !initialDate.isBefore(firstDate),
+    'initialDate must be on or after firstDate',
+  );
+  assert(
+    !initialDate.isAfter(lastDate),
+    'initialDate must be on or before lastDate',
+  );
+  assert(
+    !firstDate.isAfter(lastDate),
+    'lastDate must be on or after firstDate',
+  );
+  assert(
+    selectableDayPredicate == null || selectableDayPredicate(initialDate),
+    'Provided initialDate must satisfy provided selectableDayPredicate',
+  );
+  assert(
+    (onTapActionButton != null && textActionButton != null) ||
+        onTapActionButton == null,
+    "If you provide onLeftBtn, you must provide leftBtn",
+  );
+  assert(debugCheckHasMaterialLocalizations(context));
+
+  Widget child = GestureDetector(
+    onTap: () {
+      if (!barrierDismissible) {
+        Navigator.pop(context);
+      }
+    },
+    child: Container(
+      color: background,
+      child: GestureDetector(
+        onTap: () {
+          //
+        },
+        child: FlutterRoundedDatePickerDialog(
+          height: height,
+          initialDate: initialDate,
+          firstDate: firstDate,
+          lastDate: lastDate,
+          selectableDayPredicate: selectableDayPredicate,
+          initialDatePickerMode: initialDatePickerMode,
+          era: era,
+          locale: locale,
+          borderRadius: borderRadius,
+          imageHeader: imageHeader,
+          description: description,
+          fontFamily: fontFamily,
+          textNegativeButton: textNegativeButton,
+          textPositiveButton: textPositiveButton,
+          textActionButton: textActionButton,
+          onTapActionButton: onTapActionButton,
+          styleDatePicker: styleDatePicker,
+          styleYearPicker: styleYearPicker,
+          customWeekDays: customWeekDays,
+          builderDay: builderDay,
+          listDateDisabled: listDateDisabled,
+          onTapDay: onTapDay,
+          onMonthChange: onMonthChange,
+        ),
+      ),
+    ),
+  );
+
+  if (textDirection != null) {
+    child = Directionality(
+      textDirection: textDirection,
+      child: child,
+    );
+  }
+
+  if (locale != null) {
+    child = Localizations.override(
+      context: context,
+      locale: locale,
+      child: child,
+    );
+  }
+
+  return await showDialog<DateTime>(
+    context: context,
+    barrierDismissible: barrierDismissible,
+    builder: (_) => Theme(data: theme!, child: child),
+  );
+}

From 3fef1ee67461e4ca3fd9078f3908679f9522953d Mon Sep 17 00:00:00 2001
From: ryleedavis <rylee@cypherstack.com>
Date: Mon, 28 Nov 2022 14:10:44 -0700
Subject: [PATCH 419/426] desktop restore calendar resize

---
 .../restore_options_view/restore_options_view.dart            | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
index 1ce5d713a..a66af63fc 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
@@ -23,6 +23,8 @@ import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
+import 'package:stackwallet/widgets/rounded_date_picker/flutter_rounded_date_picker_widget.dart'
+    as datePicker;
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:tuple/tuple.dart';
 
@@ -152,7 +154,7 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
       await Future<void>.delayed(const Duration(milliseconds: 125));
     }
 
-    final date = await showRoundedDatePicker(
+    final date = await datePicker.showRoundedDatePicker(
       context: context,
       initialDate: DateTime.now(),
       height: height * 0.5,

From d7cd5cb8a9c556a29f6ef8e273a3f72503b523e3 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 28 Nov 2022 15:21:18 -0600
Subject: [PATCH 420/426] desktop wallets table hover effects

---
 .../my_stack_view/coin_wallets_table.dart     |  87 ++++++++++++--
 lib/widgets/table_view/table_view_row.dart    | 106 ++++++++++++++----
 .../wallet_info_row/wallet_info_row.dart      |  95 ++++++++--------
 3 files changed, 209 insertions(+), 79 deletions(-)

diff --git a/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart b/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart
index b16a9bc58..4ed8765ae 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart';
 
 class CoinWalletsTable extends ConsumerWidget {
@@ -24,8 +25,10 @@ class CoinWalletsTable extends ConsumerWidget {
       ),
       child: Padding(
         padding: const EdgeInsets.symmetric(
-          horizontal: 20,
-          vertical: 16,
+          // horizontal: 20,
+          // vertical: 16,
+          horizontal: 6,
+          vertical: 6,
         ),
         child: Column(
           children: [
@@ -36,14 +39,26 @@ class CoinWalletsTable extends ConsumerWidget {
                     const SizedBox(
                       height: 32,
                     ),
-                  WalletInfoRow(
-                    walletId: walletIds[i],
-                    onPressed: () async {
-                      await Navigator.of(context).pushNamed(
-                        DesktopWalletView.routeName,
-                        arguments: walletIds[i],
-                      );
-                    },
+                  Stack(
+                    children: [
+                      WalletInfoRow(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 14,
+                          vertical: 10,
+                        ),
+                        walletId: walletIds[i],
+                      ),
+                      Positioned.fill(
+                        child: WalletRowHoverOverlay(
+                          onPressed: () async {
+                            await Navigator.of(context).pushNamed(
+                              DesktopWalletView.routeName,
+                              arguments: walletIds[i],
+                            );
+                          },
+                        ),
+                      ),
+                    ],
                   ),
                 ],
               ),
@@ -53,3 +68,55 @@ class CoinWalletsTable extends ConsumerWidget {
     );
   }
 }
+
+class WalletRowHoverOverlay extends StatefulWidget {
+  const WalletRowHoverOverlay({
+    Key? key,
+    required this.onPressed,
+  }) : super(key: key);
+
+  final VoidCallback onPressed;
+
+  @override
+  State<WalletRowHoverOverlay> createState() => _WalletRowHoverOverlayState();
+}
+
+class _WalletRowHoverOverlayState extends State<WalletRowHoverOverlay> {
+  late final VoidCallback onPressed;
+
+  bool _hovering = false;
+
+  @override
+  void initState() {
+    onPressed = widget.onPressed;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return MouseRegion(
+      cursor: SystemMouseCursors.click,
+      onEnter: (_) {
+        setState(() {
+          _hovering = true;
+        });
+      },
+      onExit: (_) {
+        setState(() {
+          _hovering = false;
+        });
+      },
+      child: GestureDetector(
+        onTap: onPressed,
+        child: AnimatedOpacity(
+          duration: const Duration(milliseconds: 100),
+          opacity: _hovering ? 0.1 : 0,
+          child: RoundedContainer(
+            color:
+                Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
+          ),
+        ),
+      ),
+    );
+  }
+}
diff --git a/lib/widgets/table_view/table_view_row.dart b/lib/widgets/table_view/table_view_row.dart
index e95eb68bd..9c3175efe 100644
--- a/lib/widgets/table_view/table_view_row.dart
+++ b/lib/widgets/table_view/table_view_row.dart
@@ -3,7 +3,7 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/expandable.dart';
 import 'package:stackwallet/widgets/table_view/table_view_cell.dart';
 
-class TableViewRow extends StatelessWidget {
+class TableViewRow extends StatefulWidget {
   const TableViewRow({
     Key? key,
     required this.cells,
@@ -17,40 +17,66 @@ class TableViewRow extends StatelessWidget {
 
   final List<TableViewCell> cells;
   final Widget? expandingChild;
-  final Decoration? decoration;
+  final BoxDecoration? decoration;
   final void Function(ExpandableState)? onExpandChanged;
   final EdgeInsetsGeometry padding;
   final double spacing;
   final CrossAxisAlignment crossAxisAlignment;
 
+  @override
+  State<TableViewRow> createState() => _TableViewRowState();
+}
+
+class _TableViewRowState extends State<TableViewRow> {
+  late final List<TableViewCell> cells;
+  late final Widget? expandingChild;
+  late final BoxDecoration? decoration;
+  late final void Function(ExpandableState)? onExpandChanged;
+  late final EdgeInsetsGeometry padding;
+  late final double spacing;
+  late final CrossAxisAlignment crossAxisAlignment;
+
+  bool _hovering = false;
+
+  @override
+  void initState() {
+    cells = widget.cells;
+    expandingChild = widget.expandingChild;
+    decoration = widget.decoration;
+    onExpandChanged = widget.onExpandChanged;
+    padding = widget.padding;
+    spacing = widget.spacing;
+    crossAxisAlignment = widget.crossAxisAlignment;
+    super.initState();
+  }
+
   @override
   Widget build(BuildContext context) {
     return Container(
-      decoration: decoration,
+      decoration: !_hovering
+          ? decoration
+          : decoration?.copyWith(
+              boxShadow: [
+                Theme.of(context).extension<StackColors>()!.standardBoxShadow,
+                Theme.of(context).extension<StackColors>()!.standardBoxShadow,
+              ],
+            ),
       child: expandingChild == null
-          ? Padding(
-              padding: padding,
-              child: Row(
-                crossAxisAlignment: crossAxisAlignment,
-                children: [
-                  for (int i = 0; i < cells.length; i++) ...[
-                    if (i != 0 && i != cells.length)
-                      SizedBox(
-                        width: spacing,
-                      ),
-                    Expanded(
-                      flex: cells[i].flex,
-                      child: cells[i],
-                    ),
-                  ],
-                ],
-              ),
-            )
-          : Expandable(
-              onExpandChanged: onExpandChanged,
-              header: Padding(
+          ? MouseRegion(
+              onEnter: (_) {
+                setState(() {
+                  _hovering = true;
+                });
+              },
+              onExit: (_) {
+                setState(() {
+                  _hovering = false;
+                });
+              },
+              child: Padding(
                 padding: padding,
                 child: Row(
+                  crossAxisAlignment: crossAxisAlignment,
                   children: [
                     for (int i = 0; i < cells.length; i++) ...[
                       if (i != 0 && i != cells.length)
@@ -65,6 +91,38 @@ class TableViewRow extends StatelessWidget {
                   ],
                 ),
               ),
+            )
+          : Expandable(
+              onExpandChanged: onExpandChanged,
+              header: MouseRegion(
+                onEnter: (_) {
+                  setState(() {
+                    _hovering = true;
+                  });
+                },
+                onExit: (_) {
+                  setState(() {
+                    _hovering = false;
+                  });
+                },
+                child: Padding(
+                  padding: padding,
+                  child: Row(
+                    children: [
+                      for (int i = 0; i < cells.length; i++) ...[
+                        if (i != 0 && i != cells.length)
+                          SizedBox(
+                            width: spacing,
+                          ),
+                        Expanded(
+                          flex: cells[i].flex,
+                          child: cells[i],
+                        ),
+                      ],
+                    ],
+                  ),
+                ),
+              ),
               body: Column(
                 children: [
                   Container(
diff --git a/lib/widgets/wallet_info_row/wallet_info_row.dart b/lib/widgets/wallet_info_row/wallet_info_row.dart
index fe006a67b..5bb51e2e6 100644
--- a/lib/widgets/wallet_info_row/wallet_info_row.dart
+++ b/lib/widgets/wallet_info_row/wallet_info_row.dart
@@ -14,10 +14,12 @@ class WalletInfoRow extends ConsumerWidget {
     Key? key,
     required this.walletId,
     this.onPressed,
+    this.padding = const EdgeInsets.all(0),
   }) : super(key: key);
 
   final String walletId;
   final VoidCallback? onPressed;
+  final EdgeInsets padding;
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
@@ -30,53 +32,56 @@ class WalletInfoRow extends ConsumerWidget {
         cursor: SystemMouseCursors.click,
         child: GestureDetector(
           onTap: onPressed,
-          child: Container(
-            color: Colors.transparent,
-            child: Row(
-              children: [
-                Expanded(
-                  flex: 4,
-                  child: Row(
-                    children: [
-                      WalletInfoCoinIcon(coin: manager.coin),
-                      const SizedBox(
-                        width: 12,
-                      ),
-                      Text(
-                        manager.walletName,
-                        style:
-                            STextStyles.desktopTextExtraSmall(context).copyWith(
+          child: Padding(
+            padding: padding,
+            child: Container(
+              color: Colors.transparent,
+              child: Row(
+                children: [
+                  Expanded(
+                    flex: 4,
+                    child: Row(
+                      children: [
+                        WalletInfoCoinIcon(coin: manager.coin),
+                        const SizedBox(
+                          width: 12,
+                        ),
+                        Text(
+                          manager.walletName,
+                          style: STextStyles.desktopTextExtraSmall(context)
+                              .copyWith(
+                            color: Theme.of(context)
+                                .extension<StackColors>()!
+                                .textDark,
+                          ),
+                        ),
+                      ],
+                    ),
+                  ),
+                  Expanded(
+                    flex: 4,
+                    child: WalletInfoRowBalanceFuture(
+                      walletId: walletId,
+                    ),
+                  ),
+                  Expanded(
+                    flex: 6,
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.end,
+                      children: [
+                        SvgPicture.asset(
+                          Assets.svg.chevronRight,
+                          width: 20,
+                          height: 20,
                           color: Theme.of(context)
                               .extension<StackColors>()!
-                              .textDark,
-                        ),
-                      ),
-                    ],
-                  ),
-                ),
-                Expanded(
-                  flex: 4,
-                  child: WalletInfoRowBalanceFuture(
-                    walletId: walletId,
-                  ),
-                ),
-                Expanded(
-                  flex: 6,
-                  child: Row(
-                    mainAxisAlignment: MainAxisAlignment.end,
-                    children: [
-                      SvgPicture.asset(
-                        Assets.svg.chevronRight,
-                        width: 20,
-                        height: 20,
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .textSubtitle1,
-                      )
-                    ],
-                  ),
-                )
-              ],
+                              .textSubtitle1,
+                        )
+                      ],
+                    ),
+                  )
+                ],
+              ),
             ),
           ),
         ),

From 345a077e0611d3e294325bfd74529938f0c93e14 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 28 Nov 2022 15:37:18 -0600
Subject: [PATCH 421/426] desktop fav card hover effect

---
 .../sub_widgets/favorite_card.dart            | 45 ++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/lib/pages/wallets_view/sub_widgets/favorite_card.dart b/lib/pages/wallets_view/sub_widgets/favorite_card.dart
index 7749f264d..24b1e021a 100644
--- a/lib/pages/wallets_view/sub_widgets/favorite_card.dart
+++ b/lib/pages/wallets_view/sub_widgets/favorite_card.dart
@@ -49,6 +49,8 @@ class _FavoriteCardState extends ConsumerState<FavoriteCard> {
     super.initState();
   }
 
+  bool _hovering = false;
+
   @override
   Widget build(BuildContext context) {
     final coin = ref.watch(managerProvider.select((value) => value.coin));
@@ -59,7 +61,48 @@ class _FavoriteCardState extends ConsumerState<FavoriteCard> {
       condition: Util.isDesktop,
       builder: (child) => MouseRegion(
         cursor: SystemMouseCursors.click,
-        child: child,
+        onEnter: (_) {
+          setState(() {
+            _hovering = true;
+          });
+        },
+        onExit: (_) {
+          setState(() {
+            _hovering = false;
+          });
+        },
+        child: AnimatedScale(
+          duration: const Duration(milliseconds: 200),
+          scale: _hovering ? 1.05 : 1,
+          child: AnimatedContainer(
+            duration: const Duration(milliseconds: 200),
+            decoration: _hovering
+                ? BoxDecoration(
+                    color: Colors.transparent,
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
+                    boxShadow: [
+                      Theme.of(context)
+                          .extension<StackColors>()!
+                          .standardBoxShadow,
+                      Theme.of(context)
+                          .extension<StackColors>()!
+                          .standardBoxShadow,
+                      Theme.of(context)
+                          .extension<StackColors>()!
+                          .standardBoxShadow,
+                    ],
+                  )
+                : BoxDecoration(
+                    color: Colors.transparent,
+                    borderRadius: BorderRadius.circular(
+                      Constants.size.circularBorderRadius,
+                    ),
+                  ),
+            child: child,
+          ),
+        ),
       ),
       child: GestureDetector(
         onTap: () {

From 178565a19025d0348e04beded423db91110ba5b4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 28 Nov 2022 15:43:35 -0600
Subject: [PATCH 422/426] date picker file license added

---
 lib/widgets/rounded_date_picker/LICENSE | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 lib/widgets/rounded_date_picker/LICENSE

diff --git a/lib/widgets/rounded_date_picker/LICENSE b/lib/widgets/rounded_date_picker/LICENSE
new file mode 100644
index 000000000..58665fbd2
--- /dev/null
+++ b/lib/widgets/rounded_date_picker/LICENSE
@@ -0,0 +1,5 @@
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
\ No newline at end of file

From 18da658a652863c7599e2602ba4b8472bfaab6f4 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Sat, 26 Nov 2022 13:39:52 -0600
Subject: [PATCH 423/426] persist active wallet on desktop

---
 .../home/desktop_home_view.dart               | 71 +++++++++++++++++--
 .../my_stack_view/coin_wallets_table.dart     |  4 ++
 .../wallet_view/desktop_wallet_view.dart      |  2 +-
 3 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_home_view.dart b/lib/pages_desktop_specific/home/desktop_home_view.dart
index 54c74fe88..3e0b9311b 100644
--- a/lib/pages_desktop_specific/home/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_home_view.dart
@@ -9,12 +9,19 @@ import 'package:stackwallet/pages_desktop_specific/home/notifications/desktop_no
 import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_about_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/support_and_about_view/desktop_support_view.dart';
 import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart';
+import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
 import 'package:stackwallet/providers/global/notifications_provider.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
 import 'package:stackwallet/providers/ui/unread_notifications_provider.dart';
 import 'package:stackwallet/route_generator.dart';
+import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 import 'package:stackwallet/widgets/background.dart';
 
+final currentWalletIdProvider = StateProvider<String?>((_) => null);
+
 class DesktopHomeView extends ConsumerStatefulWidget {
   const DesktopHomeView({Key? key}) : super(key: key);
 
@@ -25,12 +32,25 @@ class DesktopHomeView extends ConsumerStatefulWidget {
 }
 
 class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
-  final Map<DesktopMenuItemId, Widget> contentViews = {
-    DesktopMenuItemId.myStack: const Navigator(
-      key: Key("desktopStackHomeKey"),
+  final GlobalKey key = GlobalKey<NavigatorState>();
+  late final Navigator myStackViewNav;
+
+  @override
+  void initState() {
+    myStackViewNav = Navigator(
+      key: key,
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: MyStackView.routeName,
-    ),
+    );
+    super.initState();
+  }
+
+  final Map<DesktopMenuItemId, Widget> contentViews = {
+    DesktopMenuItemId.myStack: Container(
+        // key: Key("desktopStackHomeKey"),
+        // onGenerateRoute: RouteGenerator.generateRoute,
+        // initialRoute: MyStackView.routeName,
+        ),
     DesktopMenuItemId.exchange: const Navigator(
       key: Key("desktopExchangeHomeKey"),
       onGenerateRoute: RouteGenerator.generateRoute,
@@ -63,7 +83,30 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
     ),
   };
 
+  DesktopMenuItemId prev = DesktopMenuItemId.myStack;
+
   void onMenuSelectionWillChange(DesktopMenuItemId newKey) {
+    if (prev == DesktopMenuItemId.myStack && prev == newKey) {
+      Navigator.of(key.currentContext!)
+          .popUntil(ModalRoute.withName(MyStackView.routeName));
+      if (ref.read(currentWalletIdProvider.state).state != null) {
+        final managerProvider = ref
+            .read(walletsChangeNotifierProvider)
+            .getManagerProvider(ref.read(currentWalletIdProvider.state).state!);
+        if (ref.read(managerProvider).shouldAutoSync) {
+          ref.read(managerProvider).shouldAutoSync = false;
+        }
+        ref.read(transactionFilterProvider.state).state = null;
+        if (ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled &&
+            ref.read(prefsChangeNotifierProvider).backupFrequencyType ==
+                BackupFrequencyType.afterClosingAWallet) {
+          ref.read(autoSWBServiceProvider).doBackup();
+        }
+        ref.read(managerProvider.notifier).isActiveWallet = false;
+      }
+    }
+    prev = newKey;
+
     // check for unread notifications and refresh provider before
     // showing notifications view
     if (newKey == DesktopMenuItemId.notifications) {
@@ -111,9 +154,25 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
               color: Theme.of(context).extension<StackColors>()!.background,
             ),
             Expanded(
-              child: contentViews[
-                  ref.watch(currentDesktopMenuItemProvider.state).state]!,
+              child: IndexedStack(
+                index: ref
+                            .watch(currentDesktopMenuItemProvider.state)
+                            .state
+                            .index >
+                        0
+                    ? 1
+                    : 0,
+                children: [
+                  myStackViewNav,
+                  contentViews[
+                      ref.watch(currentDesktopMenuItemProvider.state).state]!,
+                ],
+              ),
             ),
+            // Expanded(
+            //   child: contentViews[
+            //       ref.watch(currentDesktopMenuItemProvider.state).state]!,
+            // ),
           ],
         ),
       ),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart b/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart
index 4ed8765ae..1edb93e06 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/coin_wallets_table.dart
@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
 import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -51,6 +52,9 @@ class CoinWalletsTable extends ConsumerWidget {
                       Positioned.fill(
                         child: WalletRowHoverOverlay(
                           onPressed: () async {
+                            ref.read(currentWalletIdProvider.state).state =
+                                walletIds[i];
+
                             await Navigator.of(context).pushNamed(
                               DesktopWalletView.routeName,
                               arguments: walletIds[i],
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
index 5996597b5..d870835f1 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart
@@ -81,13 +81,13 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
       // disable auto sync if it was enabled only when loading wallet
       ref.read(managerProvider).shouldAutoSync = false;
     }
-    ref.read(managerProvider.notifier).isActiveWallet = false;
     ref.read(transactionFilterProvider.state).state = null;
     if (ref.read(prefsChangeNotifierProvider).isAutoBackupEnabled &&
         ref.read(prefsChangeNotifierProvider).backupFrequencyType ==
             BackupFrequencyType.afterClosingAWallet) {
       unawaited(ref.read(autoSWBServiceProvider).doBackup());
     }
+    ref.read(managerProvider.notifier).isActiveWallet = false;
   }
 
   void _loadCNData() {

From c9a91e10ac3d260a14714394c154bca7f7df591e Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 28 Nov 2022 16:11:02 -0600
Subject: [PATCH 424/426] clean up theme init

---
 lib/main.dart | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/lib/main.dart b/lib/main.dart
index a49bcab82..8136965db 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -318,17 +318,17 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
     final colorScheme = DB.instance
         .get<dynamic>(boxName: DB.boxNameTheme, key: "colorScheme") as String?;
 
-    ThemeType themeType;
+    StackColorTheme colorTheme;
     switch (colorScheme) {
       case "dark":
-        themeType = ThemeType.dark;
+        colorTheme = DarkColors();
         break;
       case "oceanBreeze":
-        themeType = ThemeType.oceanBreeze;
+        colorTheme = OceanBreezeColors();
         break;
       case "light":
       default:
-        themeType = ThemeType.light;
+        colorTheme = LightColors();
     }
     loadingCompleter = Completer();
     WidgetsBinding.instance.addObserver(this);
@@ -339,11 +339,7 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
 
     WidgetsBinding.instance.addPostFrameCallback((_) async {
       ref.read(colorThemeProvider.state).state =
-          StackColors.fromStackColorTheme(themeType == ThemeType.dark
-              ? DarkColors()
-              : (themeType == ThemeType.light
-                  ? LightColors()
-                  : OceanBreezeColors()));
+          StackColors.fromStackColorTheme(colorTheme);
 
       if (Platform.isAndroid) {
         // fetch open file if it exists

From 1aca715397a4146059c53ca446eea229a868d73e Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Mon, 28 Nov 2022 16:17:33 -0600
Subject: [PATCH 425/426] animated desktop menu fix

---
 .../home/desktop_menu.dart                       | 16 ----------------
 .../home/desktop_menu_item.dart                  | 14 +++++++-------
 2 files changed, 7 insertions(+), 23 deletions(-)

diff --git a/lib/pages_desktop_specific/home/desktop_menu.dart b/lib/pages_desktop_specific/home/desktop_menu.dart
index 8af307e7b..fd404db94 100644
--- a/lib/pages_desktop_specific/home/desktop_menu.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu.dart
@@ -157,8 +157,6 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "My Stack",
                       value: DesktopMenuItemId.myStack,
-                      group:
-                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       controller: controllers[0],
                     ),
@@ -185,8 +183,6 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Exchange",
                       value: DesktopMenuItemId.exchange,
-                      group:
-                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       controller: controllers[1],
                     ),
@@ -220,8 +216,6 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Notifications",
                       value: DesktopMenuItemId.notifications,
-                      group:
-                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       controller: controllers[2],
                     ),
@@ -248,8 +242,6 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Address Book",
                       value: DesktopMenuItemId.addressBook,
-                      group:
-                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       controller: controllers[3],
                     ),
@@ -276,8 +268,6 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Settings",
                       value: DesktopMenuItemId.settings,
-                      group:
-                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       controller: controllers[4],
                     ),
@@ -304,8 +294,6 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Support",
                       value: DesktopMenuItemId.support,
-                      group:
-                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       controller: controllers[5],
                     ),
@@ -332,8 +320,6 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "About",
                       value: DesktopMenuItemId.about,
-                      group:
-                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: updateSelectedMenuItem,
                       controller: controllers[6],
                     ),
@@ -352,8 +338,6 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
                       ),
                       label: "Exit",
                       value: 7,
-                      group:
-                          ref.watch(currentDesktopMenuItemProvider.state).state,
                       onChanged: (_) {
                         // todo: save stuff/ notify before exit?
                         exit(0);
diff --git a/lib/pages_desktop_specific/home/desktop_menu_item.dart b/lib/pages_desktop_specific/home/desktop_menu_item.dart
index 1fb39213b..78dcde79b 100644
--- a/lib/pages_desktop_specific/home/desktop_menu_item.dart
+++ b/lib/pages_desktop_specific/home/desktop_menu_item.dart
@@ -1,4 +1,6 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/theme/stack_colors.dart';
 
@@ -9,13 +11,12 @@ class DMIController {
   }
 }
 
-class DesktopMenuItem<T> extends StatefulWidget {
+class DesktopMenuItem<T> extends ConsumerStatefulWidget {
   const DesktopMenuItem({
     Key? key,
     required this.icon,
     required this.label,
     required this.value,
-    required this.group,
     required this.onChanged,
     required this.duration,
     this.labelLength = 125,
@@ -25,22 +26,20 @@ class DesktopMenuItem<T> extends StatefulWidget {
   final Widget icon;
   final String label;
   final T value;
-  final T group;
   final void Function(T) onChanged;
   final Duration duration;
   final double labelLength;
   final DMIController? controller;
 
   @override
-  State<DesktopMenuItem<T>> createState() => _DesktopMenuItemState<T>();
+  ConsumerState<DesktopMenuItem<T>> createState() => _DesktopMenuItemState<T>();
 }
 
-class _DesktopMenuItemState<T> extends State<DesktopMenuItem<T>>
+class _DesktopMenuItemState<T> extends ConsumerState<DesktopMenuItem<T>>
     with SingleTickerProviderStateMixin {
   late final Widget icon;
   late final String label;
   late final T value;
-  late final T group;
   late final void Function(T) onChanged;
   late final Duration duration;
   late final double labelLength;
@@ -67,7 +66,6 @@ class _DesktopMenuItemState<T> extends State<DesktopMenuItem<T>>
     icon = widget.icon;
     label = widget.label;
     value = widget.value;
-    group = widget.group;
     onChanged = widget.onChanged;
     duration = widget.duration;
     labelLength = widget.labelLength;
@@ -91,6 +89,8 @@ class _DesktopMenuItemState<T> extends State<DesktopMenuItem<T>>
 
   @override
   Widget build(BuildContext context) {
+    final group = ref.watch(currentDesktopMenuItemProvider.state).state;
+    debugPrint("============ value:$value ============ group:$group");
     return TextButton(
       style: value == group
           ? Theme.of(context)

From df4592214930849b033e921fb8e6bf275e3ce475 Mon Sep 17 00:00:00 2001
From: Diego Salazar <diego@cypherstack.com>
Date: Mon, 28 Nov 2022 17:02:26 -0700
Subject: [PATCH 426/426] Bump version. 1.5.21, build 93.

---
 pubspec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index ef1b495a5..8cfce39cb 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.20+92
+version: 1.5.21+93
 
 environment:
   sdk: ">=2.17.0 <3.0.0"