mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 12:29:51 +00:00
CW-519 Enable built-in Tor (#1950)
* tor wip * Enable tor on iOS * Prevent app lag when node is exceptionally slow (usually over tor) * fix: logic in daemonBlockchainHeight refresh fix: storing tor state * Pin ledger_flutter_plus dependency to fix builds * bump arti version * wip * add single httpclient * route everything I was able to catch trough the built-in tor node * Enable proxy for http.Client [run tests] * add tor proxy support to cw_evm, cw_tron and cw_polygon [run tests] * remove log pollution, cleanup [skip slack] * fix tests not working in latest main [skip slack] [run tests] * remove cw_wownero import * fix build issues * migrate all remaining calls to use ProxyWrapper add a CI action to enforce using ProxyWrapper instead of http/http.dart to prevent leaks * fix tor background sync (will work on test builds after #2142 is merged and this PR is rebased on top) * wip [skip ci] * relicense to GPLv3 add socks5 license, build fixes * use ProxyWrapper instead of http in robinhood * Revert "relicense to GPLv3" * feat(cw_bitcoin): support socks proxy and CakeTor * fix(tor): migrate OCP and EVM over to ProxyWrapper() * chore: cleanup fix: show tor loading screen when app is starting * fix: tor switch properly dismisses fullscreen loading dialog fix: connectToNode after tor startup on app start * fix(tor): status check for xmr/wow/zano * fix(tor): onramper request fix * 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 fix(cw_bitcoin): migrate payjoin to use ProxyWrapper * [skip ci] remove print * address comments from review * fix: derusting tor implementation Instead of rust-based Arti I've moved back to the OG C++ tor implementation. This fixed all issues we had with Tor. - onion services now work - all requests are going through without random errors - we don't have to navigate a maze of multiple forks of multiple packages - fully working `torrc` config file (probably will be needed for Tari). - logging for Tor client - and so on. feat: network logging tab feat: use built-in proxy on Tails - this should resolve all issues for Tails users (needs testing though) * fix conflicts with main bump https to fix build issue relax store() call * fix(cw_wownero): tor connection fix(tor): connection issues * fix(cw_evm): add missing chainId fix(cw_core): solana rpc fix * feat: mark tor as experimental fix: drop anonpay onion authority fix: drop fiatapi onion authority fix: drop trocador onion authority fix: disable networkimage when tor is enabled fix: handle cakepay errors gracefully * fix re-formatting [skip ci] * changes from review * Delete android/.kotlin/sessions/kotlin-compiler-2468481326039681181.salive * fix missing imports * Update pubspec_base.yaml --------- Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
parent
18c2ba9366
commit
5082dc20f3
139 changed files with 2754 additions and 878 deletions
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/di.dart';
|
|||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/feature_flag.dart';
|
||||
import 'package:cake_wallet/utils/tor.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
|
@ -15,6 +16,7 @@ import 'package:cw_core/utils/print_verbose.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class BackgroundSync {
|
||||
final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();
|
||||
|
@ -90,6 +92,11 @@ class BackgroundSync {
|
|||
}
|
||||
|
||||
Future<void> sync() async {
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
if (settingsStore.currentBuiltinTor) {
|
||||
printV("Starting Tor");
|
||||
await ensureTorStarted(context: null);
|
||||
}
|
||||
printV("Background sync started");
|
||||
await _syncWallets();
|
||||
printV("Background sync completed");
|
||||
|
@ -100,7 +107,6 @@ class BackgroundSync {
|
|||
final walletListViewModel = getIt.get<WalletListViewModel>();
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
|
||||
|
||||
final List<WalletListItem> moneroWallets = walletListViewModel.wallets
|
||||
.where((element) => !element.isHardware)
|
||||
.where((element) => ![WalletType.haven, WalletType.decred].contains(element.type))
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
|
||||
const _fiatApiClearNetAuthority = 'fiat-api.cakewallet.com';
|
||||
const _fiatApiOnionAuthority = 'n4z7bdcmwk2oyddxvzaap3x2peqcplh3pzdy7tpkk5ejz5n4mhfvoxqd.onion';
|
||||
// const _fiatApiOnionAuthority = 'n4z7bdcmwk2oyddxvzaap3x2peqcplh3pzdy7tpkk5ejz5n4mhfvoxqd.onion';
|
||||
const _fiatApiOnionAuthority = _fiatApiClearNetAuthority;
|
||||
const _fiatApiPath = '/v2/rates';
|
||||
|
||||
Future<double> _fetchPrice(Map<String, dynamic> args) async {
|
||||
final crypto = args['crypto'] as String;
|
||||
final fiat = args['fiat'] as String;
|
||||
final torOnly = args['torOnly'] as bool;
|
||||
Future<double> _fetchPrice(String crypto, String fiat, bool torOnly) async {
|
||||
|
||||
final Map<String, String> queryParams = {
|
||||
'interval_count': '1',
|
||||
|
@ -24,14 +21,14 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
|
|||
num price = 0.0;
|
||||
|
||||
try {
|
||||
late final Uri uri;
|
||||
if (torOnly) {
|
||||
uri = Uri.http(_fiatApiOnionAuthority, _fiatApiPath, queryParams);
|
||||
} else {
|
||||
uri = Uri.https(_fiatApiClearNetAuthority, _fiatApiPath, queryParams);
|
||||
}
|
||||
final onionUri = Uri.http(_fiatApiOnionAuthority, _fiatApiPath, queryParams);
|
||||
final clearnetUri = Uri.https(_fiatApiClearNetAuthority, _fiatApiPath, queryParams);
|
||||
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(
|
||||
onionUri: onionUri,
|
||||
clearnetUri: torOnly ? onionUri : clearnetUri,
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
return 0.0;
|
||||
|
@ -50,18 +47,11 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
|
|||
}
|
||||
}
|
||||
|
||||
Future<double> _fetchPriceAsync(CryptoCurrency crypto, FiatCurrency fiat, bool torOnly) async =>
|
||||
compute(_fetchPrice, {
|
||||
'fiat': fiat.toString(),
|
||||
'crypto': crypto.toString(),
|
||||
'torOnly': torOnly,
|
||||
});
|
||||
|
||||
class FiatConversionService {
|
||||
static Future<double> fetchPrice({
|
||||
required CryptoCurrency crypto,
|
||||
required FiatCurrency fiat,
|
||||
required bool torOnly,
|
||||
}) async =>
|
||||
await _fetchPriceAsync(crypto, fiat, torOnly);
|
||||
await _fetchPrice(crypto.toString(), fiat.toString(), torOnly);
|
||||
}
|
||||
|
|
|
@ -5,15 +5,13 @@ import 'package:cake_wallet/core/open_crypto_pay/exceptions.dart';
|
|||
import 'package:cake_wallet/core/open_crypto_pay/lnurl.dart';
|
||||
import 'package:cake_wallet/core/open_crypto_pay/models.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
|
||||
class OpenCryptoPayService {
|
||||
static bool isOpenCryptoPayQR(String value) =>
|
||||
value.toLowerCase().contains("lightning=lnurl") ||
|
||||
value.toLowerCase().startsWith("lnurl");
|
||||
|
||||
final Client _httpClient = Client();
|
||||
|
||||
Future<String> commitOpenCryptoPayRequest(
|
||||
String txHex, {
|
||||
required String txId,
|
||||
|
@ -31,7 +29,8 @@ class OpenCryptoPayService {
|
|||
queryParams['tx'] = txId;
|
||||
|
||||
final response =
|
||||
await _httpClient.get(Uri.https(uri.authority, uri.path, queryParams));
|
||||
await ProxyWrapper().get(clearnetUri: Uri.https(uri.authority, uri.path, queryParams));
|
||||
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final body = jsonDecode(response.body) as Map;
|
||||
|
@ -40,13 +39,13 @@ class OpenCryptoPayService {
|
|||
throw OpenCryptoPayException(body.toString());
|
||||
}
|
||||
throw OpenCryptoPayException(
|
||||
"Unexpected status code ${response.statusCode} ${response.body}");
|
||||
"Unexpected status code ${response.statusCode} ${response}");
|
||||
}
|
||||
|
||||
Future<void> cancelOpenCryptoPayRequest(OpenCryptoPayRequest request) async {
|
||||
final uri = Uri.parse(request.callbackUrl.replaceAll("/cb/", "/cancel/"));
|
||||
|
||||
await _httpClient.delete(uri);
|
||||
await ProxyWrapper().delete(clearnetUri: uri);
|
||||
}
|
||||
|
||||
Future<OpenCryptoPayRequest> getOpenCryptoPayInvoice(String lnUrl) async {
|
||||
|
@ -73,7 +72,8 @@ class OpenCryptoPayService {
|
|||
|
||||
Future<(_OpenCryptoPayQuote, Map<String, List<OpenCryptoPayQuoteAsset>>)>
|
||||
_getOpenCryptoPayParams(Uri uri) async {
|
||||
final response = await _httpClient.get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseBody = jsonDecode(response.body) as Map;
|
||||
|
@ -119,8 +119,8 @@ class OpenCryptoPayService {
|
|||
queryParams['asset'] = asset.title;
|
||||
queryParams['method'] = _getMethod(asset);
|
||||
|
||||
final response =
|
||||
await _httpClient.get(Uri.https(uri.authority, uri.path, queryParams));
|
||||
final response = await ProxyWrapper().get(clearnetUri: Uri.https(uri.authority, uri.path, queryParams));
|
||||
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseBody = jsonDecode(response.body) as Map;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cake_wallet/entities/yat_record.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
|
||||
class YatService {
|
||||
static bool isDevMode = false;
|
||||
|
@ -33,7 +33,8 @@ class YatService {
|
|||
final yatRecords = <YatRecord>[];
|
||||
|
||||
try {
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
final resBody = json.decode(response.body) as Map<String, dynamic>;
|
||||
final results = resBody["result"] as Map<dynamic, dynamic>;
|
||||
// Favour a subaddress over a standard address.
|
||||
|
@ -42,7 +43,7 @@ class YatService {
|
|||
results[MONERO_STD_ADDRESS] ??
|
||||
results[tag]) as Map<String, dynamic>;
|
||||
|
||||
if (yatRecord != null) {
|
||||
if (yatRecord.isNotEmpty) {
|
||||
yatRecords.add(YatRecord.fromJson(yatRecord));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue