feat: use better embedded Tor (#2453)

* feat: use better embedded Tor

* update docs [skip ci]

* fix: update torch properly add minimum os version for iOS

* fix: use of invalid thread api on iOS

* fix: disable use of lzma and zstd system libraries

* fix: update torch_dart to work on linux
This commit is contained in:
cyan
2025-09-05 23:07:26 +03:00
committed by GitHub
parent f0ca065a48
commit 2dc95b2bf0
42 changed files with 294 additions and 192 deletions
+6
View File
@@ -47,6 +47,7 @@ import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/utils/proxy_logger/memory_proxy_logger.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_core/utils/tor/abstract.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart';
@@ -85,6 +86,11 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {
return true;
};
await FlutterDaemon().unmarkBackgroundSync();
try {
CakeTor.instance = await CakeTorInstance.getInstance();
} catch (e) {
printV("Failed to initialize tor: $e");
}
await initializeAppAtRoot();
if (kDebugMode) {
@@ -155,7 +155,7 @@ class WCCDetailsWidget extends BasePage {
backgroundImage: (pairing.peerMetadata!.icons.isNotEmpty
? NetworkImage(pairing.peerMetadata!.icons[0])
: AssetImage(
CakeTor.instance.enabled
CakeTor.instance!.enabled
? 'assets/images/tor_logo.svg'
: 'assets/images/app_logo.png')) as ImageProvider<Object>,
),
+1 -1
View File
@@ -267,7 +267,7 @@ class Badge extends StatelessWidget {
Widget getImage(String imagePath, {double? height, double? width, Color? imageColor}) {
bool isNetworkImage = imagePath.startsWith('http') || imagePath.startsWith('https');
if (CakeTor.instance.enabled && isNetworkImage) {
if (CakeTor.instance!.enabled && isNetworkImage) {
imagePath = "assets/images/tor_logo.svg";
isNetworkImage = false;
}
+1 -1
View File
@@ -8,7 +8,7 @@ class FeatureFlag {
static const bool isCakePayRedemptionFlowEnabled = false;
static const bool isExolixEnabled = true;
static const bool isBackgroundSyncEnabled = true;
static final bool isInAppTorEnabled = CakeTor.instance is! CakeTorDisabled;
static bool get isInAppTorEnabled => CakeTor.instance is! CakeTorDisabled;
static const int verificationWordsCount = kDebugMode ? 0 : 2;
static const bool hasDevOptions = bool.fromEnvironment('hasDevOptions', defaultValue: kDebugMode);
static const bool hasBitcoinViewOnly = true;
+1 -1
View File
@@ -13,7 +13,7 @@ class ImageUtil {
}) {
bool isNetworkImage = imagePath.startsWith('http') || imagePath.startsWith('https');
if (CakeTor.instance.enabled && isNetworkImage) {
if (CakeTor.instance!.enabled && isNetworkImage) {
imagePath = "assets/images/tor_logo.svg";
isNetworkImage = false;
}
+6 -6
View File
@@ -15,7 +15,7 @@ Future<void> ensureTorStopped({required BuildContext? context}) async {
if (context != null) dialogContext = await showFullscreenDialog(context);
didTorStart = false;
printV("Stopping tor");
await CakeTor.instance.stop();
await CakeTor.instance!.stop();
printV("Tor stopped");
if (context != null) dismissFullscreenDialog(dialogContext!);
}
@@ -32,20 +32,20 @@ Future<void> ensureTorStarted({required BuildContext? context}) async {
// var rootToken = RootIsolateToken.instance!;
// await Isolate.run(() async {
// BackgroundIsolateBinaryMessenger.ensureInitialized(rootToken);
// await CakeTor.instance.start();
// await CakeTor.instance!.start();
// });
// second start is fast but populates the values on current thread
await CakeTor.instance.start();
await CakeTor.instance!.start();
printV("Tor started");
while (!CakeTor.instance.started) {
while (!CakeTor.instance!.started) {
printV("Waiting for tor to start (part 1)");
await Future.delayed(const Duration(seconds: 1));
}
while (CakeTor.instance.port == -1) {
while (CakeTor.instance!.port == -1) {
printV("Waiting for tor to start (listening on port)");
await Future.delayed(const Duration(seconds: 1));
}
printV("Tor started on port ${CakeTor.instance.port}");
printV("Tor started on port ${CakeTor.instance!.port}");
if (context != null) dismissFullscreenDialog(dialogContext!);
}
@@ -399,7 +399,7 @@ abstract class DashboardViewModelBase with Store {
String get address => wallet.walletAddresses.address;
@computed
bool get isTorEnabled => CakeTor.instance.enabled;
bool get isTorEnabled => CakeTor.instance!.enabled;
@computed
SyncStatus get status => wallet.syncStatus;
@@ -64,7 +64,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
bool useSocksProxy;
@computed
bool get usesEmbeddedProxy => CakeTor.instance.started;
bool get usesEmbeddedProxy => CakeTor.instance!.started;
@observable
String socksProxyAddress;
@@ -39,7 +39,7 @@ abstract class NodeListViewModelBase with Store {
String getAlertContent(String uri) =>
S.current.change_current_node(uri) +
'${uri.endsWith('.onion') || uri.contains('.onion:') ? '\n' + (CakeTor.instance.enabled ? '' : S.current.orbot_running_alert) : ''}';
'${uri.endsWith('.onion') || uri.contains('.onion:') ? '\n' + (CakeTor.instance!.enabled ? '' : S.current.orbot_running_alert) : ''}';
@computed
bool get enableAutomaticNodeSwitching => settingsStore.enableAutomaticNodeSwitching;
@@ -39,7 +39,7 @@ abstract class PowNodeListViewModelBase with Store {
String getAlertContent(String uri) =>
S.current.change_current_node(uri) +
'${uri.endsWith('.onion') || uri.contains('.onion:') ? '\n' + (CakeTor.instance.enabled ? '' : S.current.orbot_running_alert) : ''}';
'${uri.endsWith('.onion') || uri.contains('.onion:') ? '\n' + (CakeTor.instance!.enabled ? '' : S.current.orbot_running_alert) : ''}';
@computed
bool get enableAutomaticNodeSwitching => settingsStore.enableAutomaticNodeSwitching;
+1 -1
View File
@@ -59,7 +59,7 @@ abstract class StartTorViewModelBase with Store {
await ensureTorStarted(context: null);
while (true) {
await Future.delayed(Duration(milliseconds: 250));
if (CakeTor.instance.port != -1 && CakeTor.instance.started) {
if (CakeTor.instance!.port != -1 && CakeTor.instance!.started) {
break;
}
}