feat: CakeTorSocks respect SOCKS_SERVER (#2444)
cyan committed
Aug 12, 2025 at 18:00 UTC
b8a9863a216286b9fbcb14b5d2d79a71c45a1592
8 files changed
+82
-7
cw_core/lib/utils/proxy_wrapper.dart
+1
-1
@@ -100,7 +100,7 @@ class ProxyWrapper {
100
try {
101
switch (method) {
102
case RequestMethod.get:
103
- resp = await client. get(
103
+ resp = await client.get(
104
uri,
105
headers: headers,
106
);
cw_core/lib/utils/tor/abstract.dart
+26
-2
@@ -3,7 +3,7 @@ import 'dart:io';
3
import 'package:cw_core/utils/print_verbose.dart';
4
import 'package:cw_core/utils/tor/android.dart';
5
import 'package:cw_core/utils/tor/disabled.dart';
6
-import 'package:cw_core/utils/tor/tails.dart';
6
+import 'package:cw_core/utils/tor/socks.dart';
7
8
abstract class CakeTorInstance {
9
bool get started;
@@ -23,11 +23,24 @@ abstract class CakeTorInstance {
23
}
24
if (Platform.isLinux) {
25
try {
26
+ String? socksServer;
27
+ if (Platform.environment["SOCKS_SERVER"] != null) {
28
+ socksServer = Platform.environment["SOCKS_SERVER"]!;
29
+ }
30
+ if (Platform.environment["SOCKS_PROXY"] != null) {
31
+ socksServer = Platform.environment["SOCKS_PROXY"]!;
32
+ }
33
+ if (socksServer != null) {
34
+ final uri = Uri.tryParse(socksServer);
35
+ if (uri != null) {
36
+ return CakeTorSocks(uri.port);
37
+ }
38
+ }
39
final os = File("/etc/os-release").readAsLinesSync();
40
for (var line in os) {
41
if (!line.startsWith("ID=")) continue;
42
if (!line.contains("tails")) continue;
30
- return CakeTorTails();
43
+ return CakeTorSocks(9150);
44
}
45
} catch (e) {
46
printV("Failed to identify linux version - /etc/os-release missing");
@@ -35,4 +48,15 @@ abstract class CakeTorInstance {
48
}
49
return CakeTorDisabled();
50
}
51
+
52
+ String toString() {
53
+ return """
54
+CakeTorInstance(
55
+ port: $port,
56
+ started: $started,
57
+ bootstrapped: $bootstrapped,
58
+ enabled: $enabled,
59
+)
60
+""";
61
+ }
62
}
\ No newline at end of file
cw_core/lib/utils/tor/android.dart
+13
@@ -70,4 +70,17 @@ DataDirectory ${p.join(dir.path, "tor-data")}
70
_proc?.stdout.transform(utf8.decoder).forEach(printV);
71
_proc?.stderr.transform(utf8.decoder).forEach(printV);
72
}
73
+
74
+ @override
75
+ String toString() {
76
+ return """
77
+CakeTorAndroid(
78
+ port: $port,
79
+ started: $started,
80
+ bootstrapped: $bootstrapped,
81
+ enabled: $enabled,
82
+ proc: $_proc,
83
+)
84
+""";
85
+ }
86
}
\ No newline at end of file
cw_core/lib/utils/tor/disabled.dart
+12
@@ -18,4 +18,16 @@ class CakeTorDisabled implements CakeTorInstance {
18
19
@override
20
Future<void> stop() => throw UnimplementedError();
21
+
22
+ @override
23
+ String toString() {
24
+ return """
25
+CakeTorDisabled(
26
+ port: $port,
27
+ started: $started,
28
+ bootstrapped: $bootstrapped,
29
+ enabled: $enabled,
30
+)
31
+""";
32
+ }
33
}
\ No newline at end of file
cw_core/lib/utils/tor/socks.dart
renamed
+15
-2
@@ -1,6 +1,7 @@
1
import 'package:cw_core/utils/tor/abstract.dart';
2
3
-class CakeTorTails implements CakeTorInstance {
3
+class CakeTorSocks implements CakeTorInstance {
4
+ CakeTorSocks(this.port);
5
@override
6
bool get bootstrapped => true;
7
@@ -8,7 +9,7 @@ class CakeTorTails implements CakeTorInstance {
9
bool get enabled => true;
10
11
@override
11
- int get port => 9150;
12
+ int port;
13
14
@override
15
Future<void> start() async {}
@@ -18,4 +19,16 @@ class CakeTorTails implements CakeTorInstance {
19
20
@override
21
Future<void> stop() async {}
22
+
23
+ @override
24
+ String toString() {
25
+ return """
26
+CakeTorSocks(
27
+ port: $port,
28
+ started: $started,
29
+ bootstrapped: $bootstrapped,
30
+ enabled: $enabled,
31
+)
32
+""";
33
+ }
34
}
\ No newline at end of file
lib/src/screens/dev/network_requests.dart
+11
@@ -5,8 +5,11 @@ import 'package:cake_wallet/src/screens/base_page.dart';
5
import 'package:cake_wallet/view_model/dev/network_requests_view_model.dart';
6
import 'package:cw_core/utils/proxy_logger/abstract.dart';
7
import 'package:cw_core/utils/proxy_logger/memory_proxy_logger.dart';
8
+import 'package:cw_core/utils/proxy_wrapper.dart';
9
+import 'package:cw_core/utils/tor/abstract.dart';
10
import 'package:flutter/material.dart';
11
import 'package:flutter_mobx/flutter_mobx.dart';
12
+import 'package:on_chain/solana/solana.dart';
13
14
class DevNetworkRequests extends BasePage {
15
final NetworkRequestsViewModel viewModel = NetworkRequestsViewModel();
@@ -120,6 +123,14 @@ class DevRequestDetails extends BasePage {
123
_sectionTitle("Network"),
124
SelectableText(req.network.toString()),
125
126
+ if (req.network == RequestNetwork.tor)
127
+ ...[
128
+ _sectionTitle("Tor socks server"),
129
+ SelectableText(CakeTor.instance.runtimeType.toString()),
130
+ _sectionTitle("Tor socks details"),
131
+ SelectableText(CakeTor.instance.toString()),
132
+ ],
133
+
134
_sectionTitle("Body (as UTF-8)"),
135
SelectableText(_tryDecodeBody(req.body)),
136
lib/utils/feature_flag.dart
+3
-2
@@ -1,12 +1,13 @@
1
+import 'package:cw_core/utils/proxy_wrapper.dart';
2
+import 'package:cw_core/utils/tor/disabled.dart';
3
import 'package:flutter/foundation.dart';
2
-import 'dart:io';
4
5
class FeatureFlag {
6
static const bool isCakePayEnabled = false;
7
static const bool isCakePayRedemptionFlowEnabled = false;
8
static const bool isExolixEnabled = true;
9
static const bool isBackgroundSyncEnabled = true;
9
- static final bool isInAppTorEnabled = (Platform.isAndroid);
10
+ static final bool isInAppTorEnabled = CakeTor.instance is! CakeTorDisabled;
11
static const int verificationWordsCount = kDebugMode ? 0 : 2;
12
static const bool hasDevOptions = bool.fromEnvironment('hasDevOptions', defaultValue: kDebugMode);
13
static const bool hasBitcoinViewOnly = true;
lib/utils/tor.dart
+1
@@ -1,4 +1,5 @@
1
import 'dart:async';
2
+import 'dart:io';
3
4
import 'package:cw_core/utils/proxy_wrapper.dart';
5
import 'package:cw_core/utils/print_verbose.dart';