Skip to content

Commit 75f9291

Browse files
committed
fix(api): ServicesResponse is now being cached and doesn't fetch data everytime DashboardViewModel is being rebuilt
fix(tor): do not fallback to clearnet when tor failed. fix(tor): do not leak connections during app startup chore: refactor bootstrap() function to be separated into bootstrapOffline and bootstrapOnline
1 parent c9fa8f3 commit 75f9291

File tree

8 files changed

+87
-46
lines changed

8 files changed

+87
-46
lines changed

cw_core/lib/utils/proxy_wrapper.dart

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:async';
22
import 'dart:convert';
33
import 'dart:io';
4+
import 'package:cw_core/utils/print_verbose.dart';
45
import 'package:cw_core/utils/proxy_socket/abstract.dart';
56
import 'package:socks5_proxy/socks_client.dart';
67
import 'package:tor/tor.dart';
@@ -29,6 +30,8 @@ class ProxyWrapper {
2930
password: null,
3031
),
3132
]);
33+
} else {
34+
printV("+++++++ TOR NOT STARTED");
3235
}
3336

3437
return client;
@@ -124,16 +127,20 @@ class ProxyWrapper {
124127
if (torEnabled) {
125128
try {
126129
torClient = await getProxyHttpClient(portOverride: portOverride);
127-
} catch (_) {}
130+
} catch (_) {
131+
rethrow;
132+
}
128133

129134
if (onionUri != null) {
130135
try {
131136
return await makeGet(
132-
client: torClient!,
137+
client: torClient,
133138
uri: onionUri,
134139
headers: headers,
135140
);
136-
} catch (_) {}
141+
} catch (_) {
142+
rethrow;
143+
}
137144
}
138145

139146
if (clearnetUri != null) {
@@ -143,7 +150,9 @@ class ProxyWrapper {
143150
uri: clearnetUri,
144151
headers: headers,
145152
);
146-
} catch (_) {}
153+
} catch (_) {
154+
rethrow;
155+
}
147156
}
148157
}
149158

@@ -157,7 +166,7 @@ class ProxyWrapper {
157166
headers: headers,
158167
);
159168
},
160-
createHttpClient: NullOverrides().createHttpClient,
169+
// createHttpClient: NullOverrides().createHttpClient,
161170
);
162171
} catch (_) {
163172
// we weren't able to get a response:
@@ -190,31 +199,37 @@ class ProxyWrapper {
190199
if (torEnabled) {
191200
try {
192201
torClient = await getProxyHttpClient(portOverride: portOverride);
193-
} catch (_) {}
202+
} catch (_) {
203+
rethrow;
204+
}
194205
if (allowMitmMoneroBypassSSLCheck) {
195-
torClient!.badCertificateCallback =
206+
torClient.badCertificateCallback =
196207
((X509Certificate cert, String host, int port) => true);
197208
}
198209
if (onionUri != null) {
199210
try {
200211
return await makePost(
201-
client: torClient!,
212+
client: torClient,
202213
uri: onionUri,
203214
headers: headers,
204215
body: body,
205216
);
206-
} catch (_) {}
217+
} catch (_) {
218+
rethrow;
219+
}
207220
}
208221

209222
if (clearnetUri != null) {
210223
try {
211224
return await makePost(
212-
client: torClient!,
225+
client: torClient,
213226
uri: clearnetUri,
214227
headers: headers,
215228
body: body,
216229
);
217-
} catch (_) {}
230+
} catch (_) {
231+
rethrow;
232+
}
218233
}
219234
}
220235

@@ -229,10 +244,9 @@ class ProxyWrapper {
229244
body: body,
230245
);
231246
},
232-
createHttpClient: NullOverrides().createHttpClient,
247+
// createHttpClient: NullOverrides().createHttpClient,
233248
);
234249
} catch (_) {
235-
// we weren't able to get a response:
236250
rethrow;
237251
}
238252
}
@@ -263,7 +277,9 @@ class ProxyWrapper {
263277
headers: headers,
264278
body: body,
265279
);
266-
} catch (_) {}
280+
} catch (_) {
281+
rethrow;
282+
}
267283
}
268284

269285
if (clearnetUri != null) {
@@ -274,7 +290,9 @@ class ProxyWrapper {
274290
headers: headers,
275291
body: body,
276292
);
277-
} catch (_) {}
293+
} catch (_) {
294+
rethrow;
295+
}
278296
}
279297
}
280298

@@ -289,7 +307,7 @@ class ProxyWrapper {
289307
body: body,
290308
);
291309
},
292-
createHttpClient: NullOverrides().createHttpClient,
310+
// createHttpClient: NullOverrides().createHttpClient,
293311
);
294312
} catch (_) {
295313
// we weren't able to get a response:

lib/core/fiat_conversion_service.dart

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,13 @@ import 'package:cw_core/utils/proxy_wrapper.dart';
22
import 'package:cw_core/crypto_currency.dart';
33
import 'package:cake_wallet/entities/fiat_currency.dart';
44
import 'dart:convert';
5-
import 'package:flutter/foundation.dart';
65
import 'package:cake_wallet/.secrets.g.dart' as secrets;
76

87
const _fiatApiClearNetAuthority = 'fiat-api.cakewallet.com';
98
const _fiatApiOnionAuthority = 'n4z7bdcmwk2oyddxvzaap3x2peqcplh3pzdy7tpkk5ejz5n4mhfvoxqd.onion';
109
const _fiatApiPath = '/v2/rates';
1110

12-
Future<double> _fetchPrice(Map<String, dynamic> args) async {
13-
final crypto = args['crypto'] as String;
14-
final fiat = args['fiat'] as String;
15-
final torOnly = args['torOnly'] as bool;
11+
Future<double> _fetchPrice(String crypto, String fiat, bool torOnly) async {
1612

1713
final Map<String, String> queryParams = {
1814
'interval_count': '1',
@@ -24,15 +20,12 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
2420
num price = 0.0;
2521

2622
try {
27-
late final Uri uri;
28-
if (torOnly) {
29-
uri = Uri.http(_fiatApiOnionAuthority, _fiatApiPath, queryParams);
30-
} else {
31-
uri = Uri.https(_fiatApiClearNetAuthority, _fiatApiPath, queryParams);
32-
}
23+
final onionUri = Uri.http(_fiatApiOnionAuthority, _fiatApiPath, queryParams);
24+
final clearnetUri = Uri.https(_fiatApiClearNetAuthority, _fiatApiPath, queryParams);
3325

3426
final response = await ProxyWrapper().get(
35-
clearnetUri: uri,
27+
onionUri: onionUri,
28+
clearnetUri: torOnly ? onionUri : clearnetUri,
3629
);
3730
final responseString = await response.transform(utf8.decoder).join();
3831

@@ -53,18 +46,11 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
5346
}
5447
}
5548

56-
Future<double> _fetchPriceAsync(CryptoCurrency crypto, FiatCurrency fiat, bool torOnly) async =>
57-
compute(_fetchPrice, {
58-
'fiat': fiat.toString(),
59-
'crypto': crypto.toString(),
60-
'torOnly': torOnly,
61-
});
62-
6349
class FiatConversionService {
6450
static Future<double> fetchPrice({
6551
required CryptoCurrency crypto,
6652
required FiatCurrency fiat,
6753
required bool torOnly,
6854
}) async =>
69-
await _fetchPriceAsync(crypto, fiat, torOnly);
55+
await _fetchPrice(crypto.toString(), fiat.toString(), torOnly);
7056
}

lib/main.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import 'package:cake_wallet/routes.dart';
2525
import 'package:cake_wallet/src/screens/root/root.dart';
2626
import 'package:cake_wallet/store/app_store.dart';
2727
import 'package:cake_wallet/store/authentication_store.dart';
28+
import 'package:cake_wallet/store/settings_store.dart';
2829
import 'package:cake_wallet/themes/theme_base.dart';
2930
import 'package:cake_wallet/utils/device_info.dart';
3031
import 'package:cake_wallet/utils/exception_handler.dart';
@@ -278,7 +279,11 @@ Future<void> initialSetup(
278279
navigatorKey: navigatorKey,
279280
secureStorage: secureStorage,
280281
);
281-
await bootstrap(navigatorKey, loadWallet: loadWallet);
282+
await bootstrapOffline();
283+
final settingsStore = getIt<SettingsStore>();
284+
if (!settingsStore.currentBuiltinTor) {
285+
bootstrapOnline(navigatorKey, loadWallet: loadWallet);
286+
}
282287
}
283288

284289
class App extends StatefulWidget {

lib/reactions/bootstrap.dart

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,29 @@ import 'package:cake_wallet/store/settings_store.dart';
1515
import 'package:cake_wallet/store/authentication_store.dart';
1616
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
1717

18-
Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey, {required bool loadWallet}) async {
19-
final appStore = getIt.get<AppStore>();
18+
Future<void> bootstrapOffline() async {
2019
final authenticationStore = getIt.get<AuthenticationStore>();
21-
final settingsStore = getIt.get<SettingsStore>();
22-
final fiatConversionStore = getIt.get<FiatConversionStore>();
2320

2421
final currentWalletName =
2522
getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName);
2623
if (currentWalletName != null) {
2724
authenticationStore.installed();
2825
}
26+
}
27+
28+
void bootstrapOnline(GlobalKey<NavigatorState> navigatorKey, {required bool loadWallet}) {
29+
final appStore = getIt.get<AppStore>();
30+
final authenticationStore = getIt.get<AuthenticationStore>();
31+
final settingsStore = getIt.get<SettingsStore>();
32+
final fiatConversionStore = getIt.get<FiatConversionStore>();
2933

3034
if (loadWallet) {
3135
startAuthenticationStateChange(authenticationStore, navigatorKey);
3236
}
37+
3338
startCurrentWalletChangeReaction(appStore, settingsStore, fiatConversionStore);
3439
startCurrentFiatChangeReaction(appStore, settingsStore, fiatConversionStore);
3540
startCurrentFiatApiModeChangeReaction(appStore, settingsStore, fiatConversionStore);
3641
startOnCurrentNodeChangeReaction(appStore);
3742
startFiatRateUpdate(appStore, settingsStore, fiatConversionStore);
38-
}
43+
}

lib/utils/tor.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ Future<void> ensureTorStarted({required BuildContext? context}) async {
4141
// second start is fast but populates the values on current thread
4242
await CakeTor.instance.start();
4343
printV("Tor started");
44+
while (!CakeTor.instance.started) {
45+
printV("Waiting for tor to start (part 1)");
46+
await Future.delayed(const Duration(seconds: 1));
47+
}
4448
while (CakeTor.instance.port == -1) {
45-
printV("Waiting for tor to start");
49+
printV("Waiting for tor to start (listening on port)");
4650
await Future.delayed(const Duration(seconds: 1));
4751
}
4852
printV("Tor started on port ${CakeTor.instance.port}");

lib/view_model/dashboard/dashboard_view_model.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,17 @@ abstract class DashboardViewModelBase with Store {
10751075
}
10761076
}
10771077

1078+
static ServicesResponse? cachedServicesResponse;
1079+
10781080
Future<ServicesResponse> getServicesStatus() async {
1081+
if (cachedServicesResponse != null) {
1082+
return cachedServicesResponse!;
1083+
}
1084+
cachedServicesResponse = await _getServicesStatus();
1085+
return cachedServicesResponse!;
1086+
}
1087+
1088+
Future<ServicesResponse> _getServicesStatus() async {
10791089
try {
10801090
if (isEnabledBulletinAction) {
10811091
final uri = Uri.https(

lib/view_model/start_tor_view_model.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import 'dart:async';
22

33
import 'package:cake_wallet/di.dart';
4+
import 'package:cake_wallet/main.dart';
5+
import 'package:cake_wallet/reactions/bootstrap.dart';
46
import 'package:cake_wallet/routes.dart';
57
import 'package:cake_wallet/store/app_store.dart';
68
import 'package:cake_wallet/store/settings_store.dart';
79
import 'package:cake_wallet/utils/tor.dart';
10+
import 'package:cw_core/utils/proxy_wrapper.dart';
811
import 'package:flutter/material.dart';
912
import 'package:mobx/mobx.dart';
1013

@@ -54,8 +57,15 @@ abstract class StartTorViewModelBase with Store {
5457
return;
5558
}
5659
await ensureTorStarted(context: null);
60+
while (true) {
61+
await Future.delayed(Duration(milliseconds: 250));
62+
if (CakeTor.instance.port != -1 && CakeTor.instance.started) {
63+
break;
64+
}
65+
}
5766
didStartTor = true;
5867
final appStore = getIt.get<AppStore>();
68+
bootstrapOnline(navigatorKey, loadWallet: true);
5969
appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
6070
Navigator.pushReplacementNamed(context, Routes.login);
6171
}

pubspec_base.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ dependencies:
100100
# git:
101101
# url: https://github.com/cake-tech/tor.git
102102
# ref: main
103-
socks5_proxy: any
103+
socks5_proxy:
104+
git:
105+
url: https://github.com/LacticWhale/socks_dart.git
106+
ref: 27ad7c2efae8d7460325c74b90f660085cbd0685
104107
flutter_svg: ^2.0.9
105108
polyseed: ^0.0.7
106109
nostr_tools:
@@ -178,8 +181,8 @@ dependency_overrides:
178181
ref: c2e341d8038f1108690ad6f80f7b4b7156aacc76
179182
socks5_proxy:
180183
git:
181-
url: https://github.com/cake-tech/socks_dart.git
182-
ref: d304fcfcc97cb7212bcd347aeb5d96792c128ff3
184+
url: https://github.com/LacticWhale/socks_dart.git
185+
ref: 27ad7c2efae8d7460325c74b90f660085cbd0685
183186

184187
flutter_icons:
185188
image_path: "assets/images/app_logo.png"

0 commit comments

Comments
 (0)