diff --git a/.gitignore b/.gitignore
index e58a9412f..b7924307d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,8 +57,3 @@ libepic_cash_wallet.dll
 libmobileliblelantus.dll
 libtor_ffi.dll
 /libisar.so
-libtor_ffi.so
-
-tor_logs.txt
-
-torrc
diff --git a/assets/gif/stacy_onion.gif b/assets/gif/stacy_onion.gif
new file mode 100644
index 000000000..3486058e5
Binary files /dev/null and b/assets/gif/stacy_onion.gif differ
diff --git a/lib/db/hive/db.dart b/lib/db/hive/db.dart
index f2f5bc630..00fdc13f7 100644
--- a/lib/db/hive/db.dart
+++ b/lib/db/hive/db.dart
@@ -46,6 +46,7 @@ class DB {
   // in use (keep for now)
   static const String boxNameDBInfo = "dbInfo";
   static const String boxNamePrefs = "prefs";
+  static const String boxNameOneTimeDialogsShown = "oneTimeDialogsShown";
 
   String _boxNameTxCache({required Coin coin}) => "${coin.name}_txCache";
 
diff --git a/lib/electrumx_rpc/rpc.dart b/lib/electrumx_rpc/rpc.dart
index 3d2d499a6..a4185e104 100644
--- a/lib/electrumx_rpc/rpc.dart
+++ b/lib/electrumx_rpc/rpc.dart
@@ -15,9 +15,9 @@ import 'dart:io';
 import 'package:flutter/foundation.dart';
 import 'package:mutex/mutex.dart';
 import 'package:stackwallet/exceptions/json_rpc/json_rpc_exception.dart';
-import 'package:stackwallet/networking/socks_socket.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:tor_ffi_plugin/socks_socket.dart';
 
 // Json RPC class to handle connecting to electrumx servers
 class JsonRPC {
@@ -247,6 +247,8 @@ class JsonRPC {
         cancelOnError: true,
       );
     }
+
+    return;
   }
 }
 
diff --git a/lib/networking/socks_socket.dart b/lib/networking/socks_socket.dart
deleted file mode 100644
index 03dc60945..000000000
--- a/lib/networking/socks_socket.dart
+++ /dev/null
@@ -1,343 +0,0 @@
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-/// A SOCKS5 socket.
-///
-/// This class is a wrapper around a Socket that connects to a SOCKS5 proxy
-/// server and sends all data through the proxy.
-///
-/// This class is used to connect to the Tor proxy server.
-///
-/// Attributes:
-///  - [proxyHost]: The host of the SOCKS5 proxy server.
-///  - [proxyPort]: The port of the SOCKS5 proxy server.
-///  - [_socksSocket]: The underlying [Socket] that connects to the SOCKS5 proxy
-///  server.
-///  - [_responseController]: A [StreamController] that listens to the
-///  [_socksSocket] and broadcasts the response.
-///
-/// Methods:
-/// - connect: Connects to the SOCKS5 proxy server.
-/// - connectTo: Connects to the specified [domain] and [port] through the
-/// SOCKS5 proxy server.
-/// - write: Converts [object] to a String by invoking [Object.toString] and
-/// sends the encoding of the result to the socket.
-/// - sendServerFeaturesCommand: Sends the server.features command to the
-/// proxy server.
-/// - close: Closes the connection to the Tor proxy.
-///
-/// Usage:
-/// ```dart
-/// // Instantiate a socks socket at localhost and on the port selected by the
-/// // tor service.
-/// var socksSocket = await SOCKSSocket.create(
-///  proxyHost: InternetAddress.loopbackIPv4.address,
-///  proxyPort: tor.port,
-///  // sslEnabled: true, // For SSL connections.
-///  );
-///
-/// // Connect to the socks instantiated above.
-/// await socksSocket.connect();
-///
-/// // Connect to bitcoincash.stackwallet.com on port 50001 via socks socket.
-/// await socksSocket.connectTo(
-/// 'bitcoincash.stackwallet.com', 50001);
-///
-/// // Send a server features command to the connected socket, see method for
-/// // more specific usage example..
-/// await socksSocket.sendServerFeaturesCommand();
-/// await socksSocket.close();
-/// ```
-///
-/// See also:
-/// - SOCKS5 protocol(https://www.ietf.org/rfc/rfc1928.txt)
-class SOCKSSocket {
-  /// The host of the SOCKS5 proxy server.
-  final String proxyHost;
-
-  /// The port of the SOCKS5 proxy server.
-  final int proxyPort;
-
-  /// The underlying Socket that connects to the SOCKS5 proxy server.
-  late final Socket _socksSocket;
-
-  /// Getter for the underlying Socket that connects to the SOCKS5 proxy server.
-  Socket get socket => sslEnabled ? _secureSocksSocket : _socksSocket;
-
-  /// A wrapper around the _socksSocket that enables SSL connections.
-  late final Socket _secureSocksSocket;
-
-  /// A StreamController that listens to the _socksSocket and broadcasts.
-  final StreamController<List<int>> _responseController =
-      StreamController.broadcast();
-
-  /// A StreamController that listens to the _secureSocksSocket and broadcasts.
-  final StreamController<List<int>> _secureResponseController =
-      StreamController.broadcast();
-
-  /// Getter for the StreamController that listens to the _socksSocket and
-  /// broadcasts, or the _secureSocksSocket and broadcasts if SSL is enabled.
-  StreamController<List<int>> get responseController =>
-      sslEnabled ? _secureResponseController : _responseController;
-
-  /// A StreamSubscription that listens to the _socksSocket or the
-  /// _secureSocksSocket if SSL is enabled.
-  StreamSubscription<List<int>>? _subscription;
-
-  /// Getter for the StreamSubscription that listens to the _socksSocket or the
-  /// _secureSocksSocket if SSL is enabled.
-  StreamSubscription<List<int>>? get subscription => _subscription;
-
-  /// Is SSL enabled?
-  final bool sslEnabled;
-
-  /// Private constructor.
-  SOCKSSocket._(this.proxyHost, this.proxyPort, this.sslEnabled);
-
-  /// Creates a SOCKS5 socket to the specified [proxyHost] and [proxyPort].
-  ///
-  /// This method is a factory constructor that returns a Future that resolves
-  /// to a SOCKSSocket instance.
-  ///
-  /// Parameters:
-  /// - [proxyHost]: The host of the SOCKS5 proxy server.
-  /// - [proxyPort]: The port of the SOCKS5 proxy server.
-  ///
-  /// Returns:
-  ///  A Future that resolves to a SOCKSSocket instance.
-  static Future<SOCKSSocket> create(
-      {required String proxyHost,
-      required int proxyPort,
-      bool sslEnabled = false}) async {
-    // Create a SOCKS socket instance.
-    var instance = SOCKSSocket._(proxyHost, proxyPort, sslEnabled);
-
-    // Initialize the SOCKS socket.
-    await instance._init();
-
-    // Return the SOCKS socket instance.
-    return instance;
-  }
-
-  /// Constructor.
-  SOCKSSocket(
-      {required this.proxyHost,
-      required this.proxyPort,
-      required this.sslEnabled}) {
-    _init();
-  }
-
-  /// Initializes the SOCKS socket.
-  ///
-  /// This method is a private method that is called by the constructor.
-  ///
-  /// Returns:
-  ///   A Future that resolves to void.
-  Future<void> _init() async {
-    // Connect to the SOCKS proxy server.
-    _socksSocket = await Socket.connect(
-      proxyHost,
-      proxyPort,
-    );
-
-    // Listen to the socket.
-    _subscription = _socksSocket.listen(
-      (data) {
-        // Add the data to the response controller.
-        _responseController.add(data);
-      },
-      onError: (e) {
-        // Handle errors.
-        if (e is Object) {
-          _responseController.addError(e);
-        }
-
-        // If the error is not an object, send the error as a string.
-        _responseController.addError("$e");
-        // TODO make sure sending error as string is acceptable.
-      },
-      onDone: () {
-        // Close the response controller when the socket is closed.
-        _responseController.close();
-      },
-    );
-  }
-
-  /// Connects to the SOCKS socket.
-  ///
-  /// Returns:
-  ///  A Future that resolves to void.
-  Future<void> connect() async {
-    // Greeting and method selection.
-    _socksSocket.add([0x05, 0x01, 0x00]);
-
-    // Wait for server response.
-    var response = await _responseController.stream.first;
-
-    // Check if the connection was successful.
-    if (response[1] != 0x00) {
-      throw Exception(
-          'socks_socket.connect(): Failed to connect to SOCKS5 proxy.');
-    }
-  }
-
-  /// Connects to the specified [domain] and [port] through the SOCKS socket.
-  ///
-  /// Parameters:
-  /// - [domain]: The domain to connect to.
-  /// - [port]: The port to connect to.
-  ///
-  /// Returns:
-  ///   A Future that resolves to void.
-  Future<void> connectTo(String domain, int port) async {
-    // Connect command.
-    var request = [
-      0x05, // SOCKS version.
-      0x01, // Connect command.
-      0x00, // Reserved.
-      0x03, // Domain name.
-      domain.length,
-      ...domain.codeUnits,
-      (port >> 8) & 0xFF,
-      port & 0xFF
-    ];
-
-    // Send the connect command to the SOCKS proxy server.
-    _socksSocket.add(request);
-
-    // Wait for server response.
-    var response = await _responseController.stream.first;
-
-    // Check if the connection was successful.
-    if (response[1] != 0x00) {
-      throw Exception(
-          'socks_socket.connectTo(): Failed to connect to target through SOCKS5 proxy.');
-    }
-
-    // Upgrade to SSL if needed
-    if (sslEnabled) {
-      // Upgrade to SSL.
-      _secureSocksSocket = await SecureSocket.secure(
-        _socksSocket,
-        host: domain,
-        // onBadCertificate: (_) => true, // Uncomment this to bypass certificate validation (NOT recommended for production).
-      );
-
-      // Listen to the secure socket.
-      _subscription = _secureSocksSocket.listen(
-        (data) {
-          // Add the data to the response controller.
-          _secureResponseController.add(data);
-        },
-        onError: (e) {
-          // Handle errors.
-          if (e is Object) {
-            _secureResponseController.addError(e);
-          }
-
-          // If the error is not an object, send the error as a string.
-          _secureResponseController.addError("$e");
-          // TODO make sure sending error as string is acceptable.
-        },
-        onDone: () {
-          // Close the response controller when the socket is closed.
-          _secureResponseController.close();
-        },
-      );
-    }
-
-    return;
-  }
-
-  /// Converts [object] to a String by invoking [Object.toString] and
-  /// sends the encoding of the result to the socket.
-  ///
-  /// Parameters:
-  /// - [object]: The object to write to the socket.
-  ///
-  /// Returns:
-  ///  A Future that resolves to void.
-  void write(Object? object) {
-    // Don't write null.
-    if (object == null) return;
-
-    // Write the data to the socket.
-    List<int> data = utf8.encode(object.toString());
-    if (sslEnabled) {
-      _secureSocksSocket.add(data);
-    } else {
-      _socksSocket.add(data);
-    }
-  }
-
-  /// Sends the server.features command to the proxy server.
-  ///
-  /// This method is used to send the server.features command to the proxy
-  /// server. This command is used to request the features of the proxy server.
-  /// It serves as a demonstration of how to send commands to the proxy server.
-  ///
-  /// Returns:
-  ///   A Future that resolves to void.
-  Future<void> sendServerFeaturesCommand() async {
-    // The server.features command.
-    const String command =
-        '{"jsonrpc":"2.0","id":"0","method":"server.features","params":[]}';
-
-    if (!sslEnabled) {
-      // Send the command to the proxy server.
-      _socksSocket.writeln(command);
-
-      // Wait for the response from the proxy server.
-      var responseData = await _responseController.stream.first;
-      print("responseData: ${utf8.decode(responseData)}");
-    } else {
-      // Send the command to the proxy server.
-      _secureSocksSocket.writeln(command);
-
-      // Wait for the response from the proxy server.
-      var responseData = await _secureResponseController.stream.first;
-      print("secure responseData: ${utf8.decode(responseData)}");
-    }
-
-    return;
-  }
-
-  /// Closes the connection to the Tor proxy.
-  ///
-  /// Returns:
-  ///  A Future that resolves to void.
-  Future<void> close() async {
-    // Ensure all data is sent before closing.
-    //
-    // TODO test this.
-    if (sslEnabled) {
-      await _socksSocket.flush();
-      await _secureResponseController.close();
-    }
-    await _socksSocket.flush();
-    await _responseController.close();
-    return await _socksSocket.close();
-  }
-
-  StreamSubscription<List<int>> listen(
-    void Function(List<int> data)? onData, {
-    Function? onError,
-    void Function()? onDone,
-    bool? cancelOnError,
-  }) {
-    return sslEnabled
-        ? _secureResponseController.stream.listen(
-            onData,
-            onError: onError,
-            onDone: onDone,
-            cancelOnError: cancelOnError,
-          )
-        : _responseController.stream.listen(
-            onData,
-            onError: onError,
-            onDone: onDone,
-            cancelOnError: cancelOnError,
-          );
-  }
-}
diff --git a/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart b/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart
index ada195455..78afc54c0 100644
--- a/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart
+++ b/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart
@@ -18,6 +18,7 @@ import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
 import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
 import 'package:stackwallet/pages/buy_view/sub_widgets/crypto_selection_view.dart';
 import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
+import 'package:stackwallet/services/exchange/exchange.dart';
 import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
 import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
@@ -40,8 +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 '../../../services/exchange/exchange.dart';
-
 class ExchangeCurrencySelectionView extends StatefulWidget {
   const ExchangeCurrencySelectionView({
     Key? key,
diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index a81f758a6..a233a35c7 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -36,14 +36,12 @@ import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart
 import 'package:stackwallet/services/exchange/exchange_response.dart';
 import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
 import 'package:stackwallet/services/exchange/trocador/trocador_exchange.dart';
-import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount_unit.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
-import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
@@ -80,11 +78,17 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
   late final Coin? coin;
   late final bool walletInitiated;
 
-  var exchanges = [
-    MajesticBankExchange.instance,
-    ChangeNowExchange.instance,
-    TrocadorExchange.instance,
-  ];
+  List<Exchange> get usableExchanges {
+    if (ref.read(prefsChangeNotifierProvider).useTor) {
+      return Exchange.exchangesWithTorSupport;
+    } else {
+      return [
+        MajesticBankExchange.instance,
+        ChangeNowExchange.instance,
+        TrocadorExchange.instance,
+      ];
+    }
+  }
 
   late final TextEditingController _sendController;
   late final TextEditingController _receiveController;
@@ -623,7 +627,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
     final uuid = const Uuid().v1();
     _latestUuid = uuid;
     _addUpdate(uuid);
-    for (final exchange in exchanges) {
+    for (final exchange in usableExchanges) {
       ref.read(efEstimatesListProvider(exchange.name).notifier).state = null;
     }
 
@@ -644,7 +648,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
     final Map<String, Tuple2<ExchangeResponse<List<Estimate>>, Range?>>
         results = {};
 
-    for (final exchange in exchanges) {
+    for (final exchange in usableExchanges) {
       final sendCurrency = pair.send?.forExchange(exchange.name);
       final receiveCurrency = pair.receive?.forExchange(exchange.name);
 
@@ -674,7 +678,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
       }
     }
 
-    for (final exchange in exchanges) {
+    for (final exchange in usableExchanges) {
       if (uuid == _latestUuid) {
         ref.read(efEstimatesListProvider(exchange.name).notifier).state =
             results[exchange.name];
@@ -775,14 +779,6 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
       });
     }
 
-    // Instantiate the Tor service.
-    torService = TorService.sharedInstance;
-
-    // Filter exchanges based on Tor support.
-    if (Prefs.instance.useTor) {
-      exchanges = Exchange.exchangesWithTorSupport;
-    }
-
     super.initState();
   }
 
@@ -1017,7 +1013,4 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
       ],
     );
   }
-
-  // TorService instance.
-  late TorService torService;
 }
diff --git a/lib/pages/home_view/home_view.dart b/lib/pages/home_view/home_view.dart
index 2303333e1..b99d8cd1c 100644
--- a/lib/pages/home_view/home_view.dart
+++ b/lib/pages/home_view/home_view.dart
@@ -33,6 +33,7 @@ import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/animated_widgets/rotate_icon.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/onetime_popups/tor_has_been_add_dialog.dart';
 import 'package:stackwallet/widgets/small_tor_icon.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
@@ -129,19 +130,9 @@ class _HomeViewState extends ConsumerState<HomeView> {
 
     ref.read(notificationsProvider).startCheckingWatchedNotifications();
 
-    /// todo change to watch tor network
-    // 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;
-    //   }
-    // }
+    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
+      showOneTimeTorHasBeenAddedDialogIfRequired(context);
+    });
 
     super.initState();
   }
diff --git a/lib/pages/ordinals/ordinal_details_view.dart b/lib/pages/ordinals/ordinal_details_view.dart
index b0e478535..4154618c9 100644
--- a/lib/pages/ordinals/ordinal_details_view.dart
+++ b/lib/pages/ordinals/ordinal_details_view.dart
@@ -242,7 +242,8 @@ class _OrdinalImageGroup extends ConsumerWidget {
     );
 
     if (response.code != 200) {
-      throw Exception("statusCode=${response.code} body=${response.bodyBytes}");
+      throw Exception(
+          "OrdinalDetailsView _savePngToFile statusCode=${response.code} body=${response.bodyBytes}");
     }
 
     final bytes = response.bodyBytes;
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 52a523f22..924524de7 100644
--- a/lib/pages/settings_views/global_settings_view/hidden_settings.dart
+++ b/lib/pages/settings_views/global_settings_view/hidden_settings.dart
@@ -12,13 +12,20 @@ import 'dart:async';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:hive_flutter/hive_flutter.dart';
+import 'package:stackwallet/db/hive/db.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/themes/stack_colors.dart';
+import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.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/onetime_popups/tor_has_been_add_dialog.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class HiddenSettings extends StatelessWidget {
@@ -32,9 +39,29 @@ class HiddenSettings extends StatelessWidget {
       child: Scaffold(
         backgroundColor: Theme.of(context).extension<StackColors>()!.background,
         appBar: AppBar(
-          leading: Container(),
+          leading: Util.isDesktop
+              ? Padding(
+                  padding: const EdgeInsets.all(8.0),
+                  child: 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,
+                  ),
+                )
+              : Container(),
           title: Text(
-            "Not so secret anymore",
+            "Dev options",
             style: STextStyles.navBarTitle(context),
           ),
         ),
@@ -146,6 +173,48 @@ class HiddenSettings extends StatelessWidget {
                             ),
                           );
                         }),
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        Consumer(builder: (_, ref, __) {
+                          return GestureDetector(
+                            onTap: () async {
+                              await showOneTimeTorHasBeenAddedDialogIfRequired(
+                                context,
+                              );
+                            },
+                            child: RoundedWhiteContainer(
+                              child: Text(
+                                "Test tor stacy popup",
+                                style: STextStyles.button(context).copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark),
+                              ),
+                            ),
+                          );
+                        }),
+                        const SizedBox(
+                          height: 12,
+                        ),
+                        Consumer(builder: (_, ref, __) {
+                          return GestureDetector(
+                            onTap: () async {
+                              final box = await Hive.openBox<bool>(
+                                  DB.boxNameOneTimeDialogsShown);
+                              await box.clear();
+                            },
+                            child: RoundedWhiteContainer(
+                              child: Text(
+                                "Reset tor stacy popup",
+                                style: STextStyles.button(context).copyWith(
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark),
+                              ),
+                            ),
+                          );
+                        }),
                         // const SizedBox(
                         //   height: 12,
                         // ),
diff --git a/lib/pages/settings_views/global_settings_view/tor_settings/tor_settings_view.dart b/lib/pages/settings_views/global_settings_view/tor_settings/tor_settings_view.dart
index a395d3897..f0a944cb5 100644
--- a/lib/pages/settings_views/global_settings_view/tor_settings/tor_settings_view.dart
+++ b/lib/pages/settings_views/global_settings_view/tor_settings/tor_settings_view.dart
@@ -225,11 +225,11 @@ class _TorAnimatedButtonState extends ConsumerState<TorAnimatedButton>
       // Connect or disconnect when the user taps the status.
       switch (_status) {
         case TorConnectionStatus.disconnected:
-          await _connectTor(ref, context);
+          await connectTor(ref, context);
           break;
 
         case TorConnectionStatus.connected:
-          await _disconnectTor(ref, context);
+          await disconnectTor(ref, context);
 
           break;
 
@@ -435,11 +435,11 @@ class _TorButtonState extends ConsumerState<TorButton> {
       // Connect or disconnect when the user taps the status.
       switch (_status) {
         case TorConnectionStatus.disconnected:
-          await _connectTor(ref, context);
+          await connectTor(ref, context);
           break;
 
         case TorConnectionStatus.connected:
-          await _disconnectTor(ref, context);
+          await disconnectTor(ref, context);
 
           break;
 
@@ -583,7 +583,7 @@ class _UpperCaseTorTextState extends ConsumerState<UpperCaseTorText> {
 /// Throws an exception if the Tor service fails to start.
 ///
 /// Returns a Future that completes when the Tor service has started.
-Future<void> _connectTor(WidgetRef ref, BuildContext context) async {
+Future<void> connectTor(WidgetRef ref, BuildContext context) async {
   try {
     // Init the Tor service if it hasn't already been.
     final torDir = await StackFileSystem.applicationTorDirectory();
@@ -600,8 +600,6 @@ Future<void> _connectTor(WidgetRef ref, BuildContext context) async {
     );
     // TODO: show dialog with error message
   }
-
-  return;
 }
 
 /// Disconnect from the Tor network.
@@ -611,7 +609,7 @@ Future<void> _connectTor(WidgetRef ref, BuildContext context) async {
 /// Throws an exception if the Tor service fails to stop.
 ///
 /// Returns a Future that completes when the Tor service has stopped.
-Future<void> _disconnectTor(WidgetRef ref, BuildContext context) async {
+Future<void> disconnectTor(WidgetRef ref, BuildContext context) async {
   // Stop the Tor service.
   try {
     await ref.read(pTorService).disable();
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 ad91b3b07..8ae18a581 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart
@@ -16,6 +16,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/add_edit_node_view.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/tor_settings/tor_settings_view.dart';
 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';
@@ -35,8 +36,6 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
-import 'package:stackwallet/utilities/logger.dart';
-import 'package:stackwallet/utilities/stack_file_system.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/animated_text.dart';
@@ -100,6 +99,26 @@ class _WalletNetworkSettingsViewState
   /// The current status of the Tor connection.
   late TorConnectionStatus _torConnectionStatus;
 
+  bool _buttonLockTor = false;
+  Future<void> onTorTapped() async {
+    if (_buttonLockTor) {
+      return;
+    }
+    _buttonLockTor = true;
+    try {
+      if (ref.read(prefsChangeNotifierProvider).useTor) {
+        await disconnectTor(ref, context);
+      } else {
+        await connectTor(ref, context);
+      }
+    } catch (_) {
+      // Nothing. Just using finally to ensure button lock is reset in case
+      // some unexpected error happens
+    } finally {
+      _buttonLockTor = false;
+    }
+  }
+
   Future<void> _attemptRescan() async {
     if (!Platform.isLinux) await Wakelock.enable();
 
@@ -477,17 +496,14 @@ class _WalletNetworkSettingsViewState
                     ? STextStyles.desktopTextExtraExtraSmall(context)
                     : STextStyles.smallMed12(context),
               ),
-              GestureDetector(
+              CustomTextButton(
+                text: "Resync",
                 onTap: () {
                   ref
                       .read(walletsChangeNotifierProvider)
                       .getManager(widget.walletId)
                       .refresh();
                 },
-                child: Text(
-                  "Resync",
-                  style: STextStyles.link2(context),
-                ),
               ),
             ],
           ),
@@ -769,55 +785,13 @@ class _WalletNetworkSettingsViewState
                     ? STextStyles.desktopTextExtraExtraSmall(context)
                     : STextStyles.smallMed12(context),
               ),
-              if (ref.watch(
-                  prefsChangeNotifierProvider.select((value) => value.useTor)))
-                GestureDetector(
-                  onTap: () async {
-                    // Stop the Tor service.
-                    try {
-                      await ref.read(pTorService).disable();
-
-                      // Toggle the useTor preference on success.
-                      ref.read(prefsChangeNotifierProvider).useTor = false;
-                    } catch (e, s) {
-                      Logging.instance.log(
-                        "Error stopping tor: $e\n$s",
-                        level: LogLevel.Error,
-                      );
-                    }
-                  },
-                  child: Text(
-                    "Disconnect",
-                    style: STextStyles.link2(context),
-                  ),
-                ),
-              if (!ref.watch(
-                  prefsChangeNotifierProvider.select((value) => value.useTor)))
-                GestureDetector(
-                  onTap: () async {
-                    try {
-                      // Init the Tor service if it hasn't already been.
-                      final torDir =
-                          await StackFileSystem.applicationTorDirectory();
-                      ref.read(pTorService).init(torDataDirPath: torDir.path);
-                      // Start the Tor service.
-                      await ref.read(pTorService).start();
-
-                      // Toggle the useTor preference on success.
-                      ref.read(prefsChangeNotifierProvider).useTor = true;
-                    } catch (e, s) {
-                      Logging.instance.log(
-                        "Error starting tor: $e\n$s",
-                        level: LogLevel.Error,
-                      );
-                      // TODO: show dialog with error message
-                    }
-                  },
-                  child: Text(
-                    "Connect",
-                    style: STextStyles.link2(context),
-                  ),
-                ),
+              CustomTextButton(
+                text: ref.watch(prefsChangeNotifierProvider
+                        .select((value) => value.useTor))
+                    ? "Disconnect"
+                    : "Connect",
+                onTap: onTorTapped,
+              ),
             ],
           ),
           SizedBox(
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 fcacc60d4..6b7e57bef 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
@@ -13,6 +13,7 @@ import 'dart:async';
 import 'package:event_bus/event_bus.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/db/hive/db.dart';
 import 'package:stackwallet/models/epicbox_config_model.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
@@ -36,11 +37,14 @@ import 'package:stackwallet/services/event_bus/global_event_bus.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_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:tuple/tuple.dart';
 
 /// [eventBus] should only be set during testing
@@ -306,6 +310,61 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
                                       );
                                     },
                                   ),
+                                if (coin == Coin.firo)
+                                  const SizedBox(
+                                    height: 8,
+                                  ),
+                                if (coin == Coin.firo)
+                                  Consumer(
+                                    builder: (_, ref, __) {
+                                      return SettingsListButton(
+                                        iconAssetName: Assets.svg.eye,
+                                        title: "Clear electrumx cache",
+                                        onPressed: () async {
+                                          String? result;
+                                          await showDialog<void>(
+                                            useSafeArea: false,
+                                            barrierDismissible: true,
+                                            context: context,
+                                            builder: (_) => StackOkDialog(
+                                              title:
+                                                  "Are you sure you want to clear "
+                                                  "${coin.prettyName} electrumx cache?",
+                                              onOkPressed: (value) {
+                                                result = value;
+                                              },
+                                              leftButton: SecondaryButton(
+                                                label: "Cancel",
+                                                onPressed: () {
+                                                  Navigator.of(context).pop();
+                                                },
+                                              ),
+                                            ),
+                                          );
+
+                                          if (result == "OK" && mounted) {
+                                            await showLoading(
+                                              whileFuture: Future.wait<void>(
+                                                [
+                                                  Future.delayed(
+                                                    const Duration(
+                                                      milliseconds: 1500,
+                                                    ),
+                                                  ),
+                                                  DB.instance
+                                                      .clearSharedTransactionCache(
+                                                    coin: coin,
+                                                  ),
+                                                ],
+                                              ),
+                                              context: context,
+                                              message: "Clearing cache...",
+                                            );
+                                          }
+                                        },
+                                      );
+                                    },
+                                  ),
                                 if (coin == Coin.nano || coin == Coin.banano)
                                   const SizedBox(
                                     height: 8,
diff --git a/lib/pages/wallet_view/sub_widgets/tx_icon.dart b/lib/pages/wallet_view/sub_widgets/tx_icon.dart
index d86ad6e8d..bcf7c3780 100644
--- a/lib/pages/wallet_view/sub_widgets/tx_icon.dart
+++ b/lib/pages/wallet_view/sub_widgets/tx_icon.dart
@@ -47,7 +47,7 @@ class TxIcon extends ConsumerWidget {
 
     if (isReceived) {
       if (isCancelled) {
-        return assets.receive;
+        return assets.receiveCancelled;
       }
       if (isPending) {
         return assets.receivePending;
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 f358aef5e..54b528245 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -358,8 +358,6 @@ class _TransactionDetailsViewState
     final currentHeight = ref.watch(walletsChangeNotifierProvider
         .select((value) => value.getManager(walletId).currentHeight));
 
-    print("THIS TRANSACTION IS $_transaction");
-
     return ConditionalParent(
       condition: !isDesktop,
       builder: (child) => Background(
diff --git a/lib/pages_desktop_specific/desktop_home_view.dart b/lib/pages_desktop_specific/desktop_home_view.dart
index 37fbd9693..1d0755b8f 100644
--- a/lib/pages_desktop_specific/desktop_home_view.dart
+++ b/lib/pages_desktop_specific/desktop_home_view.dart
@@ -30,6 +30,7 @@ import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
 import 'package:stackwallet/widgets/background.dart';
+import 'package:stackwallet/widgets/onetime_popups/tor_has_been_add_dialog.dart';
 
 final currentWalletIdProvider = StateProvider<String?>((_) => null);
 
@@ -53,6 +54,11 @@ class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
       onGenerateRoute: RouteGenerator.generateRoute,
       initialRoute: MyStackView.routeName,
     );
+
+    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
+      showOneTimeTorHasBeenAddedDialogIfRequired(context);
+    });
+
     super.initState();
   }
 
diff --git a/lib/pages_desktop_specific/my_stack_view/my_stack_view.dart b/lib/pages_desktop_specific/my_stack_view/my_stack_view.dart
index 819ec2a90..f510b8289 100644
--- a/lib/pages_desktop_specific/my_stack_view/my_stack_view.dart
+++ b/lib/pages_desktop_specific/my_stack_view/my_stack_view.dart
@@ -13,11 +13,13 @@ import 'dart:io';
 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/hidden_settings.dart';
 import 'package:stackwallet/pages/wallets_view/sub_widgets/empty_wallets.dart';
 import 'package:stackwallet/pages_desktop_specific/my_stack_view/my_wallets.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/animated_widgets/rotate_icon.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
 
@@ -52,27 +54,77 @@ class _MyStackViewState extends ConsumerState<MyStackView> {
   }
 }
 
-class DesktopMyStackTitle extends ConsumerWidget {
-  const DesktopMyStackTitle({Key? key}) : super(key: key);
+class DesktopMyStackTitle extends ConsumerStatefulWidget {
+  const DesktopMyStackTitle({super.key});
 
   @override
-  Widget build(BuildContext context, WidgetRef ref) {
+  ConsumerState<DesktopMyStackTitle> createState() =>
+      _DesktopMyStackTitleState();
+}
+
+class _DesktopMyStackTitleState extends ConsumerState<DesktopMyStackTitle> {
+  late final RotateIconController _rotateIconController;
+
+  DateTime _hiddenTime = DateTime.now();
+  int _hiddenCount = 0;
+
+  void _hiddenOptions() {
+    _rotateIconController.reset?.call();
+    _rotateIconController.forward?.call();
+    if (_hiddenCount == 5) {
+      Navigator.of(context).pushNamed(HiddenSettings.routeName);
+    }
+    final now = DateTime.now();
+    const timeout = Duration(seconds: 1);
+    if (now.difference(_hiddenTime) < timeout) {
+      _hiddenCount++;
+    } else {
+      _hiddenCount = 0;
+    }
+    _hiddenTime = now;
+  }
+
+  @override
+  void initState() {
+    _rotateIconController = RotateIconController();
+
+    super.initState();
+  }
+
+  @override
+  dispose() {
+    _rotateIconController.forward = null;
+    _rotateIconController.reverse = null;
+    _rotateIconController.reset = null;
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
     return Row(
       children: [
         const SizedBox(
           width: 24,
         ),
-        SizedBox(
-          width: 32,
-          height: 32,
-          child: SvgPicture.file(
-            File(
-              ref.watch(
-                themeProvider.select(
-                  (value) => value.assets.stackIcon,
+        GestureDetector(
+          onTap: _hiddenOptions,
+          child: RotateIcon(
+            icon: SizedBox(
+              width: 32,
+              height: 32,
+              child: SvgPicture.file(
+                File(
+                  ref.watch(
+                    themeProvider.select(
+                      (value) => value.assets.stackIcon,
+                    ),
+                  ),
                 ),
               ),
             ),
+            curve: Curves.easeInOutCubic,
+            rotationPercent: 1.0,
+            controller: _rotateIconController,
           ),
         ),
         const SizedBox(
diff --git a/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart b/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart
index 44135c3b2..0b778031c 100644
--- a/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart
+++ b/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart
@@ -62,7 +62,8 @@ class _DesktopOrdinalDetailsViewState
     );
 
     if (response.code != 200) {
-      throw Exception("statusCode=${response.code} body=${response.bodyBytes}");
+      throw Exception(
+          "DesktopOrdinalDetailsView _savePngToFile statusCode=${response.code} body=${response.bodyBytes}");
     }
 
     final bytes = response.bodyBytes;
diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart
index 2dacb1639..bdf803e4b 100644
--- a/lib/services/coins/epiccash/epiccash_wallet.dart
+++ b/lib/services/coins/epiccash/epiccash_wallet.dart
@@ -457,7 +457,6 @@ class EpicCashWallet extends CoinServiceAPI
 
       // TODO determine whether it is worth sending change to a change address.
       dynamic message;
-      print("THIS TX DATA IS $txData");
 
       String receiverAddress = txData['addresss'] as String;
 
diff --git a/lib/services/exchange/exchange_data_loading_service.dart b/lib/services/exchange/exchange_data_loading_service.dart
index eecb80462..6b34fd438 100644
--- a/lib/services/exchange/exchange_data_loading_service.dart
+++ b/lib/services/exchange/exchange_data_loading_service.dart
@@ -162,18 +162,21 @@ class ExchangeDataLoadingService {
         // await _loadChangeNowEstimatedRatePairs();
          */
 
+        // Exchanges which support Tor just get treated normally.
+        final futures = [
+          loadMajesticBankCurrencies(),
+          loadTrocadorCurrencies(),
+        ];
+
         // If using Tor, don't load data for exchanges which don't support Tor.
         //
         // Add to this list when adding an exchange which doesn't supports Tor.
         if (!Prefs.instance.useTor) {
-          await _loadChangeNowCurrencies();
+          futures.add(_loadChangeNowCurrencies());
         }
 
-        // Exchanges which support Tor just get treated normally.
-        await Future.wait([
-          loadMajesticBankCurrencies(),
-          loadTrocadorCurrencies(),
-        ]);
+        // wait for all loading futures to complete
+        await Future.wait(futures);
 
         Logging.instance.log(
           "ExchangeDataLoadingService.loadAll finished in ${DateTime.now().difference(start).inSeconds} seconds",
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index f6a454b7f..c664849b3 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -21,6 +21,7 @@ abstract class Assets {
   static const socials = _SOCIALS();
   static const exchange = _EXCHANGE();
   static const buy = _BUY();
+  static const gif = _GIF();
 }
 
 class _SOCIALS {
@@ -260,3 +261,9 @@ class _ANIMATIONS {
   String get arrowRotate => "assets/lottie/arrow_rotate.json";
   String get onionTor => "assets/lottie/onion_animation.json";
 }
+
+class _GIF {
+  const _GIF();
+
+  String get stacyOnion => "assets/gif/stacy_onion.gif";
+}
diff --git a/lib/widgets/desktop/desktop_tor_status_button.dart b/lib/widgets/desktop/desktop_tor_status_button.dart
index 8b7e96ec2..da429e9ec 100644
--- a/lib/widgets/desktop/desktop_tor_status_button.dart
+++ b/lib/widgets/desktop/desktop_tor_status_button.dart
@@ -120,50 +120,56 @@ class _DesktopTorStatusButtonState extends ConsumerState<DesktopTorStatusButton>
           .extension<StackColors>()!
           .getDesktopMenuButtonStyle(context),
       onPressed: widget.onPressed,
-      child: Padding(
-        padding: const EdgeInsets.symmetric(
-          vertical: 16,
-        ),
-        child: Row(
-          mainAxisAlignment: MainAxisAlignment.center,
-          children: [
-            AnimatedContainer(
-              duration: widget.transitionDuration,
-              width: _iconOnly ? 0 : 16,
+      child: Row(
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: [
+          Padding(
+            padding: const EdgeInsets.symmetric(
+              vertical: 16,
             ),
-            SvgPicture.asset(
-              Assets.svg.tor,
-              color: _color(_torConnectionStatus),
-              width: 20,
-              height: 20,
-            ),
-            AnimatedOpacity(
-              duration: widget.transitionDuration,
-              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(
-                        _torConnectionStatus.name.capitalize(),
-                        style: STextStyles.smallMed12(context).copyWith(
-                          color: _color(_torConnectionStatus),
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                AnimatedContainer(
+                  duration: widget.transitionDuration,
+                  width: _iconOnly ? 0 : 16,
+                ),
+                SvgPicture.asset(
+                  Assets.svg.tor,
+                  color: _color(_torConnectionStatus),
+                  width: 20,
+                  height: 20,
+                ),
+                AnimatedOpacity(
+                  duration: widget.transitionDuration,
+                  opacity: _iconOnly ? 0 : 1.0,
+                  child: SizeTransition(
+                    sizeFactor: animationController,
+                    axis: Axis.horizontal,
+                    axisAlignment: -1,
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.center,
+                      children: [
+                        const SizedBox(
+                          width: 12,
                         ),
-                      ),
-                    ],
+                        Text(
+                          _torConnectionStatus.name.capitalize(),
+                          style: STextStyles.smallMed12(context).copyWith(
+                            color: _color(_torConnectionStatus),
+                          ),
+                        ),
+                        const SizedBox(
+                          width: 21,
+                        ),
+                      ],
+                    ),
                   ),
                 ),
-              ),
+              ],
             ),
-          ],
-        ),
+          ),
+        ],
       ),
     );
   }
diff --git a/lib/widgets/onetime_popups/tor_has_been_add_dialog.dart b/lib/widgets/onetime_popups/tor_has_been_add_dialog.dart
new file mode 100644
index 000000000..8f316c012
--- /dev/null
+++ b/lib/widgets/onetime_popups/tor_has_been_add_dialog.dart
@@ -0,0 +1,167 @@
+import 'package:flutter/material.dart';
+import 'package:hive_flutter/hive_flutter.dart';
+import 'package:stackwallet/db/hive/db.dart';
+import 'package:stackwallet/utilities/assets.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/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/stack_dialog.dart';
+
+const _kOneTimeTorHasBeenAddedDialogWasShown =
+    "oneTimeTorHasBeenAddedDialogWasShown";
+
+Future<void> showOneTimeTorHasBeenAddedDialogIfRequired(
+    BuildContext context) async {
+  final box = await Hive.openBox<bool>(DB.boxNameOneTimeDialogsShown);
+
+  if (!box.get(
+        _kOneTimeTorHasBeenAddedDialogWasShown,
+        defaultValue: false,
+      )! &&
+      context.mounted) {
+    await showDialog<void>(
+      context: context,
+      barrierDismissible: false,
+      builder: (_) => const _TorHasBeenAddedDialog(),
+    );
+  }
+}
+
+class _TorHasBeenAddedDialog extends StatefulWidget {
+  const _TorHasBeenAddedDialog({super.key});
+
+  @override
+  State<_TorHasBeenAddedDialog> createState() => _TorHasBeenAddedDialogState();
+}
+
+class _TorHasBeenAddedDialogState extends State<_TorHasBeenAddedDialog> {
+  bool _lock = false;
+
+  void setDoNotShowAgain() async {
+    if (_lock) {
+      return;
+    }
+    _lock = true;
+    try {
+      final box = await Hive.openBox<bool>(DB.boxNameOneTimeDialogsShown);
+      await box.put(_kOneTimeTorHasBeenAddedDialogWasShown, true);
+    } catch (_) {
+      //
+    } finally {
+      _lock = false;
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return ConditionalParent(
+      condition: Util.isDesktop,
+      builder: (child) => DesktopDialog(
+        maxHeight: double.infinity,
+        maxWidth: 450,
+        child: Column(
+          children: [
+            Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Padding(
+                  padding: const EdgeInsets.only(left: 32),
+                  child: Text(
+                    "",
+                    style: STextStyles.desktopH3(context),
+                  ),
+                ),
+                DesktopDialogCloseButton(
+                  onPressedOverride: () {
+                    setDoNotShowAgain();
+                    Navigator.of(context).pop();
+                  },
+                ),
+              ],
+            ),
+            Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 32),
+              child: child,
+            ),
+            Padding(
+              padding: const EdgeInsets.all(32),
+              child: Row(
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: [
+                  PrimaryButton(
+                    buttonHeight: ButtonHeight.l,
+                    width: 180,
+                    label: "Ok",
+                    onPressed: () {
+                      setDoNotShowAgain();
+                      Navigator.of(context).pop();
+                    },
+                  ),
+                ],
+              ),
+            )
+          ],
+        ),
+      ),
+      child: ConditionalParent(
+        condition: !Util.isDesktop,
+        builder: (child) => StackDialogBase(
+          child: Column(
+            children: [
+              child,
+              const SizedBox(
+                height: 28,
+              ),
+              Row(
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: [
+                  SizedBox(
+                    width: MediaQuery.of(context).size.width / 2,
+                    child: PrimaryButton(
+                      label: "Ok",
+                      onPressed: () {
+                        setDoNotShowAgain();
+                        Navigator.of(context).pop();
+                      },
+                    ),
+                  ),
+                ],
+              ),
+            ],
+          ),
+        ),
+        child: Column(
+          children: [
+            const StacyOnion(),
+            SizedBox(
+              height: Util.isDesktop ? 24 : 16,
+            ),
+            Text(
+              "Tor has been added to help keep your connections private and secure!",
+              style: Util.isDesktop
+                  ? STextStyles.desktopTextMedium(context)
+                  : STextStyles.smallMed14(context),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class StacyOnion extends StatelessWidget {
+  const StacyOnion({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Image(
+      height: 200,
+      image: AssetImage(
+        Assets.gif.stacyOnion,
+      ),
+    );
+  }
+}
diff --git a/pubspec.lock b/pubspec.lock
index 934394e2a..5bfe671b9 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -37,10 +37,10 @@ packages:
     dependency: "direct main"
     description:
       name: archive
-      sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
+      sha256: e0902a06f0e00414e4e3438a084580161279f137aeb862274710f29ec10cf01e
       url: "https://pub.dev"
     source: hosted
-    version: "3.3.7"
+    version: "3.3.9"
   args:
     dependency: transitive
     description:
@@ -53,10 +53,10 @@ packages:
     dependency: transitive
     description:
       name: asn1lib
-      sha256: b74e3842a52c61f8819a1ec8444b4de5419b41a7465e69d4aa681445377398b0
+      sha256: "21afe4333076c02877d14f4a89df111e658a6d466cbfc802eb705eb91bd5adfd"
       url: "https://pub.dev"
     source: hosted
-    version: "1.4.1"
+    version: "1.5.0"
   async:
     dependency: "direct main"
     description:
@@ -178,10 +178,10 @@ packages:
     dependency: transitive
     description:
       name: build_resolvers
-      sha256: "6c4dd11d05d056e76320b828a1db0fc01ccd376922526f8e9d6c796a5adbac20"
+      sha256: d912852cce27c9e80a93603db721c267716894462e7033165178b91138587972
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.1"
+    version: "2.3.2"
   build_runner:
     dependency: "direct dev"
     description:
@@ -210,10 +210,10 @@ packages:
     dependency: transitive
     description:
       name: built_value
-      sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166"
+      sha256: ff627b645b28fb8bdb69e645f910c2458fd6b65f6585c3a53e0626024897dedf
       url: "https://pub.dev"
     source: hosted
-    version: "8.6.1"
+    version: "8.6.2"
   characters:
     dependency: transitive
     description:
@@ -250,10 +250,10 @@ packages:
     dependency: transitive
     description:
       name: code_builder
-      sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189"
+      sha256: "315a598c7fbe77f22de1c9da7cfd6fd21816312f16ffa124453b4fc679e540f1"
       url: "https://pub.dev"
     source: hosted
-    version: "4.5.0"
+    version: "4.6.0"
   coinlib:
     dependency: "direct main"
     description:
@@ -274,10 +274,10 @@ packages:
     dependency: "direct main"
     description:
       name: connectivity_plus
-      sha256: "8599ae9edca5ff96163fca3e36f8e481ea917d1e71cdad912c084b5579913f34"
+      sha256: "77a180d6938f78ca7d2382d2240eb626c0f6a735d0bfdce227d8ffb80f95c48b"
       url: "https://pub.dev"
     source: hosted
-    version: "4.0.1"
+    version: "4.0.2"
   connectivity_plus_platform_interface:
     dependency: transitive
     description:
@@ -306,10 +306,10 @@ packages:
     dependency: transitive
     description:
       name: cross_file
-      sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9"
+      sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb
       url: "https://pub.dev"
     source: hosted
-    version: "0.3.3+4"
+    version: "0.3.3+5"
   crypto:
     dependency: "direct main"
     description:
@@ -398,10 +398,10 @@ packages:
     dependency: transitive
     description:
       name: dart_style
-      sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55"
+      sha256: abd7625e16f51f554ea244d090292945ec4d4be7bfbaf2ec8cccea568919d334
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.2"
+    version: "2.3.3"
   dartx:
     dependency: transitive
     description:
@@ -438,18 +438,18 @@ packages:
     dependency: "direct main"
     description:
       name: desktop_drop
-      sha256: "4ca4d960f4b11c032e9adfd2a0a8ac615bc3fddb4cbe73dcf840dd8077582186"
+      sha256: ebba9c9cb0b54385998a977d741cc06fd8324878c08d5a36e9da61cd56b04cc6
       url: "https://pub.dev"
     source: hosted
-    version: "0.4.1"
+    version: "0.4.3"
   device_info_plus:
     dependency: "direct main"
     description:
       name: device_info_plus
-      sha256: "2c35b6d1682b028e42d07b3aee4b98fa62996c10bc12cb651ec856a80d6a761b"
+      sha256: "86add5ef97215562d2e090535b0a16f197902b10c369c558a100e74ea06e8659"
       url: "https://pub.dev"
     source: hosted
-    version: "9.0.2"
+    version: "9.0.3"
   device_info_plus_platform_interface:
     dependency: transitive
     description:
@@ -478,10 +478,10 @@ packages:
     dependency: "direct main"
     description:
       name: dropdown_button2
-      sha256: "83c54a5022f898d63e3abe21240b64b937e676103207287e6705d3f9bb04d654"
+      sha256: b0fe8d49a030315e9eef6c7ac84ca964250155a6224d491c1365061bc974a9e1
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.6"
+    version: "2.3.9"
   eip1559:
     dependency: transitive
     description:
@@ -510,10 +510,10 @@ packages:
     dependency: transitive
     description:
       name: encrypt
-      sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
+      sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
       url: "https://pub.dev"
     source: hosted
-    version: "5.0.1"
+    version: "5.0.3"
   equatable:
     dependency: "direct main"
     description:
@@ -631,10 +631,10 @@ packages:
     dependency: "direct dev"
     description:
       name: flutter_lints
-      sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4"
+      sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.2"
+    version: "2.0.3"
   flutter_local_notifications:
     dependency: "direct main"
     description:
@@ -671,18 +671,18 @@ packages:
     dependency: "direct main"
     description:
       name: flutter_native_splash
-      sha256: ba45d8cfbd778478a74696b012f33ffb6b1760c9bc531b21e2964444a4870dae
+      sha256: ecff62b3b893f2f665de7e4ad3de89f738941fcfcaaba8ee601e749efafa4698
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.1"
+    version: "2.3.2"
   flutter_plugin_android_lifecycle:
     dependency: transitive
     description:
       name: flutter_plugin_android_lifecycle
-      sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360"
+      sha256: f185ac890306b5779ecbd611f52502d8d4d63d27703ef73161ca0407e815f02c
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.15"
+    version: "2.0.16"
   flutter_riverpod:
     dependency: "direct main"
     description:
@@ -703,50 +703,50 @@ packages:
     dependency: "direct main"
     description:
       name: flutter_secure_storage
-      sha256: "98352186ee7ad3639ccc77ad7924b773ff6883076ab952437d20f18a61f0a7c5"
+      sha256: "22dbf16f23a4bcf9d35e51be1c84ad5bb6f627750565edd70dab70f3ff5fff8f"
       url: "https://pub.dev"
     source: hosted
-    version: "8.0.0"
+    version: "8.1.0"
   flutter_secure_storage_linux:
     dependency: transitive
     description:
       name: flutter_secure_storage_linux
-      sha256: "0912ae29a572230ad52d8a4697e5518d7f0f429052fd51df7e5a7952c7efe2a3"
+      sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e"
       url: "https://pub.dev"
     source: hosted
-    version: "1.1.3"
+    version: "1.2.0"
   flutter_secure_storage_macos:
     dependency: transitive
     description:
       name: flutter_secure_storage_macos
-      sha256: "083add01847fc1c80a07a08e1ed6927e9acd9618a35e330239d4422cd2a58c50"
+      sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.0"
+    version: "3.0.1"
   flutter_secure_storage_platform_interface:
     dependency: transitive
     description:
       name: flutter_secure_storage_platform_interface
-      sha256: b3773190e385a3c8a382007893d678ae95462b3c2279e987b55d140d3b0cb81b
+      sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e"
       url: "https://pub.dev"
     source: hosted
-    version: "1.0.1"
+    version: "1.0.2"
   flutter_secure_storage_web:
     dependency: transitive
     description:
       name: flutter_secure_storage_web
-      sha256: "42938e70d4b872e856e678c423cc0e9065d7d294f45bc41fc1981a4eb4beaffe"
+      sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20"
       url: "https://pub.dev"
     source: hosted
-    version: "1.1.1"
+    version: "1.1.2"
   flutter_secure_storage_windows:
     dependency: transitive
     description:
       name: flutter_secure_storage_windows
-      sha256: fc2910ec9b28d60598216c29ea763b3a96c401f0ce1d13cdf69ccb0e5c93c3ee
+      sha256: "38f9501c7cb6f38961ef0e1eacacee2b2d4715c63cc83fe56449c4d3d0b47255"
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.0"
+    version: "2.1.1"
   flutter_svg:
     dependency: "direct main"
     description:
@@ -830,10 +830,10 @@ packages:
     dependency: "direct dev"
     description:
       name: hive_generator
-      sha256: "65998cc4d2cd9680a3d9709d893d2f6bb15e6c1f92626c3f1fa650b4b3281521"
+      sha256: "06cb8f58ace74de61f63500564931f9505368f45f98958bd7a6c35ba24159db4"
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.0"
+    version: "2.0.1"
   hive_test:
     dependency: "direct dev"
     description:
@@ -1010,10 +1010,10 @@ packages:
     dependency: "direct main"
     description:
       name: lottie
-      sha256: "0793a5866062e5cc8a8b24892fa94c3095953ea914a7fdf790f550dd7537fe60"
+      sha256: b8bdd54b488c54068c57d41ae85d02808da09e2bee8b8dd1f59f441e7efa60cd
       url: "https://pub.dev"
     source: hosted
-    version: "2.5.0"
+    version: "2.6.0"
   matcher:
     dependency: transitive
     description:
@@ -1130,10 +1130,10 @@ packages:
     dependency: "direct main"
     description:
       name: package_info_plus
-      sha256: ceb027f6bc6a60674a233b4a90a7658af1aebdea833da0b5b53c1e9821a78c7b
+      sha256: "6ff267fcd9d48cb61c8df74a82680e8b82e940231bb5f68356672fde0397334a"
       url: "https://pub.dev"
     source: hosted
-    version: "4.0.2"
+    version: "4.1.0"
   package_info_plus_platform_interface:
     dependency: transitive
     description:
@@ -1218,10 +1218,10 @@ packages:
     dependency: transitive
     description:
       name: permission_handler_android
-      sha256: "6901d50f4d4b9a27e1749dbd4adbf06aa00d90a21a2db563405d5ce27ee120ac"
+      sha256: f23cfe9af0d49c6b9fd8a8b09f7b3301ca7e346204939b5afef4404d36d2608f
       url: "https://pub.dev"
     source: hosted
-    version: "11.0.0"
+    version: "11.0.1"
   permission_handler_apple:
     dependency: transitive
     description:
@@ -1274,10 +1274,10 @@ packages:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd"
+      sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.5"
+    version: "2.1.6"
   pointycastle:
     dependency: "direct main"
     description:
@@ -1402,18 +1402,18 @@ packages:
     dependency: "direct main"
     description:
       name: share_plus
-      sha256: ed3fcea4f789ed95913328e629c0c53e69e80e08b6c24542f1b3576046c614e8
+      sha256: "6cec740fa0943a826951223e76218df002804adb588235a8910dc3d6b0654e11"
       url: "https://pub.dev"
     source: hosted
-    version: "7.0.2"
+    version: "7.1.0"
   share_plus_platform_interface:
     dependency: transitive
     description:
       name: share_plus_platform_interface
-      sha256: "0c6e61471bd71b04a138b8b588fa388e66d8b005e6f2deda63371c5c505a0981"
+      sha256: "357412af4178d8e11d14f41723f80f12caea54cf0d5cd29af9dcdab85d58aea7"
       url: "https://pub.dev"
     source: hosted
-    version: "3.2.1"
+    version: "3.3.0"
   shelf:
     dependency: transitive
     description:
@@ -1656,8 +1656,8 @@ packages:
     dependency: "direct main"
     description:
       path: "."
-      ref: "8a26a160bdc4dcac2ba5a0350a151a345d1dead9"
-      resolved-ref: "8a26a160bdc4dcac2ba5a0350a151a345d1dead9"
+      ref: "7123505a9e5f702dba1c0c9aa12b289b5dfbb3bf"
+      resolved-ref: "7123505a9e5f702dba1c0c9aa12b289b5dfbb3bf"
       url: "https://github.com/cypherstack/tor.git"
     source: git
     version: "0.0.1"
@@ -1697,66 +1697,66 @@ packages:
     dependency: "direct main"
     description:
       name: url_launcher
-      sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e"
+      sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27"
       url: "https://pub.dev"
     source: hosted
-    version: "6.1.12"
+    version: "6.1.14"
   url_launcher_android:
     dependency: transitive
     description:
       name: url_launcher_android
-      sha256: "78cb6dea3e93148615109e58e42c35d1ffbf5ef66c44add673d0ab75f12ff3af"
+      sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330
       url: "https://pub.dev"
     source: hosted
-    version: "6.0.37"
+    version: "6.1.0"
   url_launcher_ios:
     dependency: transitive
     description:
       name: url_launcher_ios
-      sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
+      sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f"
       url: "https://pub.dev"
     source: hosted
-    version: "6.1.4"
+    version: "6.1.5"
   url_launcher_linux:
     dependency: transitive
     description:
       name: url_launcher_linux
-      sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5"
+      sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.5"
+    version: "3.0.6"
   url_launcher_macos:
     dependency: transitive
     description:
       name: url_launcher_macos
-      sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1"
+      sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.6"
+    version: "3.0.7"
   url_launcher_platform_interface:
     dependency: transitive
     description:
       name: url_launcher_platform_interface
-      sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea
+      sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.3"
+    version: "2.1.5"
   url_launcher_web:
     dependency: transitive
     description:
       name: url_launcher_web
-      sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4
+      sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.18"
+    version: "2.0.19"
   url_launcher_windows:
     dependency: transitive
     description:
       name: url_launcher_windows
-      sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422"
+      sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069"
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.7"
+    version: "3.0.8"
   uuid:
     dependency: "direct main"
     description:
@@ -1898,10 +1898,10 @@ packages:
     dependency: transitive
     description:
       name: webkit_inspection_protocol
-      sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d"
+      sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.0"
+    version: "1.2.1"
   websocket_universal:
     dependency: "direct main"
     description:
@@ -1914,10 +1914,10 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: dfdf0136e0aa7a1b474ea133e67cb0154a0acd2599c4f3ada3b49d38d38793ee
+      sha256: c97defd418eef4ec88c0d1652cdce84b9f7b63dd7198e266d06ac1710d527067
       url: "https://pub.dev"
     source: hosted
-    version: "5.0.5"
+    version: "5.0.8"
   win32_registry:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 5c3c50059..a87ba8824 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -60,7 +60,7 @@ dependencies:
   tor_ffi_plugin:
     git:
       url: https://github.com/cypherstack/tor.git
-      ref: 8a26a160bdc4dcac2ba5a0350a151a345d1dead9
+      ref: 7123505a9e5f702dba1c0c9aa12b289b5dfbb3bf
 
   # Utility plugins
   http: ^0.13.0
@@ -373,6 +373,9 @@ flutter:
     # buy
     - assets/svg/buy/
 
+    # gif
+    - assets/gif/
+
     # lottie animations
     # basic
     - assets/lottie/test2.json
diff --git a/scripts/android/build_all.sh b/scripts/android/build_all.sh
index 111fea934..19e2ec64c 100755
--- a/scripts/android/build_all.sh
+++ b/scripts/android/build_all.sh
@@ -1,5 +1,11 @@
 #!/bin/bash
 
+set -e
+
+# libepiccash requires old rust
+source ../rust_version.sh
+set_rust_to_1680
+
 mkdir build
 . ./config.sh
 ./install_ndk.sh
@@ -7,7 +13,10 @@ mkdir build
 (cd ../../crypto_plugins/flutter_liblelantus/scripts/android && ./build_all.sh ) &
 (cd ../../crypto_plugins/flutter_libepiccash/scripts/android && ./install_ndk.sh && ./build_all.sh )  &
 (cd ../../crypto_plugins/flutter_libmonero/scripts/android/ && ./build_all.sh  ) &
-(cd ../../crypto_plugins/tor/scripts/android && ./install_ndk.sh && ./build_all.sh )  &
 
 wait
 echo "Done building"
+
+# set rust (back) to a more recent stable release to allow stack wallet to build tor
+set_rust_to_1720
+
diff --git a/scripts/ios/build_all.sh b/scripts/ios/build_all.sh
index fa6f2ac93..5ff7cb2f4 100755
--- a/scripts/ios/build_all.sh
+++ b/scripts/ios/build_all.sh
@@ -1,8 +1,25 @@
 #!/bin/bash
 
+set -e
+
+# libepiccash requires old rust
+source ../rust_version.sh
+set_rust_to_1680
+
+# ensure ios rust triples are there
+rustup target add aarch64-apple-ios
+rustup target add x86_64-apple-ios
+
 (cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh ) &
 (cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh )  &
 (cd ../../crypto_plugins/flutter_libmonero/scripts/ios/ && ./build_all.sh  ) &
 
 wait
-echo "Done building"
\ No newline at end of file
+echo "Done building"
+
+# set rust (back) to a more recent stable release to allow stack wallet to build tor
+set_rust_to_1720
+
+# ensure ios rust triples are there
+rustup target add aarch64-apple-ios
+rustup target add x86_64-apple-ios
diff --git a/scripts/linux/build_all.sh b/scripts/linux/build_all.sh
index 9a119d0d6..9a6ee34d9 100755
--- a/scripts/linux/build_all.sh
+++ b/scripts/linux/build_all.sh
@@ -1,5 +1,11 @@
 #!/bin/bash
 
+set -e
+
+# libepiccash requires old rust
+source ../rust_version.sh
+set_rust_to_1680
+
 # for arm
 # flutter-elinux clean
 # flutter-elinux pub get
@@ -9,7 +15,10 @@ mkdir -p build
 (cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh ) &
 (cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh )  &
 (cd ../../crypto_plugins/flutter_libmonero/scripts/linux && ./build_monero_all.sh && ./build_sharedfile.sh ) &
-(cd ../../crypto_plugins/tor/scripts/linux && ./build_all.sh ) &
 
 wait
 echo "Done building"
+
+# set rust (back) to a more recent stable release to allow stack wallet to build tor
+set_rust_to_1720
+
diff --git a/scripts/macos/build_all.sh b/scripts/macos/build_all.sh
index 646274593..a91fb73b2 100755
--- a/scripts/macos/build_all.sh
+++ b/scripts/macos/build_all.sh
@@ -1,8 +1,17 @@
 #!/bin/bash
 
+set -e
+
+# libepiccash requires old rust
+source ../rust_version.sh
+set_rust_to_1680
+
 (cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh ) &
 (cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh )  &
 (cd ../../crypto_plugins/flutter_libmonero/scripts/macos/ && ./build_all.sh  ) &
 
 wait
-echo "Done building"
\ No newline at end of file
+echo "Done building"
+
+# set rust (back) to a more recent stable release to allow stack wallet to build tor
+set_rust_to_1720
diff --git a/scripts/rust_version.sh b/scripts/rust_version.sh
new file mode 100755
index 000000000..91ead188d
--- /dev/null
+++ b/scripts/rust_version.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+set_rust_to_1680() {
+  if rustup toolchain list | grep -q "1.68.0"; then
+    rustup default 1.68.0
+  else
+    echo "Rust version 1.68.0 is not installed. Please install it using 'rustup install 1.68.0'." >&2
+    exit 1
+  fi
+}
+
+set_rust_to_1720() {
+  if rustup toolchain list | grep -q "1.72.0"; then
+    rustup default 1.72.0
+  else
+    echo "Rust version 1.72.0 is not installed. Please install it using 'rustup install 1.72.0'." >&2
+    exit 1
+  fi
+}
\ No newline at end of file
diff --git a/scripts/windows/build_all.sh b/scripts/windows/build_all.sh
index a96271cc3..54d340b5e 100755
--- a/scripts/windows/build_all.sh
+++ b/scripts/windows/build_all.sh
@@ -1,9 +1,18 @@
 #!/bin/bash
 
+set -e
+
+# libepiccash requires old rust
+source ../rust_version.sh
+set_rust_to_1680
+
 mkdir -p build
 (cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh )  &
 (cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh ) &
-# (cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh) &
+(cd ../../crypto_plugins/flutter_libmonero/scripts/windows && ./build_all.sh) &
 
 wait
 echo "Done building"
+
+# set rust (back) to a more recent stable release to allow stack wallet to build tor
+set_rust_to_1720
diff --git a/windows/runner/CMakeLists.txt b/windows/runner/CMakeLists.txt
index b9e550fba..17411a8ab 100644
--- a/windows/runner/CMakeLists.txt
+++ b/windows/runner/CMakeLists.txt
@@ -20,6 +20,13 @@ add_executable(${BINARY_NAME} WIN32
 # that need different build settings.
 apply_standard_settings(${BINARY_NAME})
 
+# Add preprocessor definitions for the build version.
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
+target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
+
 # Disable Windows macros that collide with C++ standard library functions.
 target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
 
diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc
index 5fa3067e5..d23cd8ce6 100644
--- a/windows/runner/Runner.rc
+++ b/windows/runner/Runner.rc
@@ -60,14 +60,14 @@ IDI_APP_ICON            ICON                    "resources\\app_icon.ico"
 // Version
 //
 
-#ifdef FLUTTER_BUILD_NUMBER
-#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
+#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
+#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
 #else
-#define VERSION_AS_NUMBER 1,0,0
+#define VERSION_AS_NUMBER 1,0,0,0
 #endif
 
-#ifdef FLUTTER_BUILD_NAME
-#define VERSION_AS_STRING #FLUTTER_BUILD_NAME
+#if defined(FLUTTER_VERSION)
+#define VERSION_AS_STRING FLUTTER_VERSION
 #else
 #define VERSION_AS_STRING "1.0.0"
 #endif