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
|
@ -6,8 +6,8 @@ import 'package:cake_wallet/anonpay/anonpay_status_response.dart';
|
|||
import 'package:cake_wallet/core/fiat_conversion_service.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/exchange/limits.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
|
||||
|
@ -20,8 +20,9 @@ class AnonPayApi {
|
|||
final WalletBase wallet;
|
||||
|
||||
static const anonpayRef = secrets.anonPayReferralCode;
|
||||
static const onionApiAuthority = 'tqzngtf2hybjbexznel6dhgsvbynjzezoybvtv6iofomx7gchqfssgqd.onion';
|
||||
static const clearNetAuthority = 'trocador.app';
|
||||
// static const onionApiAuthority = 'tqzngtf2hybjbexznel6dhgsvbynjzezoybvtv6iofomx7gchqfssgqd.onion';
|
||||
static const onionApiAuthority = clearNetAuthority;
|
||||
static const markup = secrets.trocadorExchangeMarkup;
|
||||
static const anonPayPath = '/anonpay';
|
||||
static const anonPayStatus = '/anonpay/status';
|
||||
|
@ -29,8 +30,11 @@ class AnonPayApi {
|
|||
static const apiKey = secrets.trocadorApiKey;
|
||||
|
||||
Future<AnonpayStatusResponse> paymentStatus(String id) async {
|
||||
final authority = await _getAuthority();
|
||||
final response = await get(Uri.https(authority, "$anonPayStatus/$id"));
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: Uri.https(clearNetAuthority, "$anonPayStatus/$id"),
|
||||
onionUri: Uri.https(onionApiAuthority, "$anonPayStatus/$id"),
|
||||
);
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final status = responseJSON['Status'] as String;
|
||||
final fiatAmount = responseJSON['Fiat_Amount'] as double?;
|
||||
|
@ -69,10 +73,11 @@ class AnonPayApi {
|
|||
if (request.fiatEquivalent != null) {
|
||||
body['fiat_equiv'] = request.fiatEquivalent;
|
||||
}
|
||||
final authority = await _getAuthority();
|
||||
|
||||
final response = await get(Uri.https(authority, anonPayPath, body));
|
||||
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: Uri.https(clearNetAuthority, anonPayPath, body),
|
||||
onionUri: Uri.https(onionApiAuthority, anonPayPath, body),
|
||||
);
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final id = responseJSON['ID'] as String;
|
||||
final url = responseJSON['url'] as String;
|
||||
|
@ -146,17 +151,16 @@ class AnonPayApi {
|
|||
'name': cryptoCurrency.name,
|
||||
};
|
||||
|
||||
final String apiAuthority = await _getAuthority();
|
||||
final uri = Uri.https(apiAuthority, coinPath, params);
|
||||
|
||||
final response = await get(uri);
|
||||
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: Uri.https(clearNetAuthority, coinPath, params),
|
||||
onionUri: Uri.https(onionApiAuthority, coinPath, params),
|
||||
);
|
||||
|
||||
final responseJSON = json.decode(response.body) as List<dynamic>;
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
}
|
||||
|
||||
final responseJSON = json.decode(response.body) as List<dynamic>;
|
||||
|
||||
if (responseJSON.isEmpty) {
|
||||
throw Exception('No data');
|
||||
}
|
||||
|
@ -197,17 +201,4 @@ class AnonPayApi {
|
|||
return tag.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> _getAuthority() async {
|
||||
try {
|
||||
if (useTorOnly) {
|
||||
return onionApiAuthority;
|
||||
}
|
||||
final uri = Uri.https(onionApiAuthority, '/anonpay');
|
||||
await get(uri);
|
||||
return onionApiAuthority;
|
||||
} catch (e) {
|
||||
return clearNetAuthority;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:convert';
|
||||
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
|
||||
import 'package:cake_wallet/utils/exception_handler.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/anypay/any_pay_payment.dart';
|
||||
import 'package:cake_wallet/anypay/any_pay_trasnaction.dart';
|
||||
|
@ -53,8 +53,12 @@ class AnyPayApi {
|
|||
final body = <String, dynamic>{
|
||||
'chain': chainByScheme(scheme),
|
||||
'currency': currencyByScheme(scheme).title};
|
||||
final response = await post(url, headers: headers, body: utf8.encode(json.encode(body)));
|
||||
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: url,
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
await ExceptionHandler.onError(FlutterErrorDetails(exception: response));
|
||||
throw Exception('Unexpected response http code: ${response.statusCode}');
|
||||
|
@ -79,7 +83,12 @@ class AnyPayApi {
|
|||
'chain': chain,
|
||||
'currency': currency,
|
||||
'transactions': transactions.map((tx) => {'tx': tx.tx, 'tx_hash': tx.id, 'tx_key': tx.key}).toList()};
|
||||
final response = await post(Uri.parse(uri), headers: headers, body: utf8.encode(json.encode(body)));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: Uri.parse(uri),
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
if (response.statusCode == 400) {
|
||||
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
|
||||
throw Exception(decodedBody['message'] as String? ?? 'Unexpected response\nError code: 400');
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:cake_wallet/generated/i18n.dart';
|
|||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
@ -17,7 +18,6 @@ import 'package:cw_core/utils/print_verbose.dart';
|
|||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class DFXBuyProvider extends BuyProvider {
|
||||
|
@ -100,11 +100,12 @@ class DFXBuyProvider extends BuyProvider {
|
|||
});
|
||||
|
||||
final uri = Uri.https(_baseUrl, _authPath);
|
||||
var response = await http.post(
|
||||
uri,
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: requestBody,
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
final responseBody = jsonDecode(response.body);
|
||||
|
@ -137,8 +138,10 @@ class DFXBuyProvider extends BuyProvider {
|
|||
final url = Uri.https(_baseUrl, '/v1/fiat');
|
||||
|
||||
try {
|
||||
final response = await http.get(url, headers: {'accept': 'application/json'});
|
||||
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: url,
|
||||
headers: {'accept': 'application/json'});
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body) as List<dynamic>;
|
||||
for (final item in data) {
|
||||
|
@ -160,8 +163,8 @@ class DFXBuyProvider extends BuyProvider {
|
|||
final url = Uri.https(_baseUrl, '/v1/asset', {'blockchains': blockchain});
|
||||
|
||||
try {
|
||||
final response = await http.get(url, headers: {'accept': 'application/json'});
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: url, headers: {'accept': 'application/json'});
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseData = jsonDecode(response.body);
|
||||
|
||||
|
@ -271,7 +274,12 @@ class DFXBuyProvider extends BuyProvider {
|
|||
});
|
||||
|
||||
try {
|
||||
final response = await http.put(url, headers: headers, body: body);
|
||||
final response = await ProxyWrapper().put(
|
||||
clearnetUri: url,
|
||||
headers: headers,
|
||||
body: body,
|
||||
);
|
||||
|
||||
final responseData = jsonDecode(response.body);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
|
|
|
@ -9,10 +9,10 @@ import 'package:cake_wallet/entities/fiat_currency.dart';
|
|||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:developer';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class KryptonimBuyProvider extends BuyProvider {
|
||||
|
@ -74,9 +74,14 @@ class KryptonimBuyProvider extends BuyProvider {
|
|||
});
|
||||
|
||||
try {
|
||||
final response = await http.post(url, headers: headers, body: body);
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: url,
|
||||
headers: headers,
|
||||
body: body,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201 || response.statusCode == 401) {
|
||||
|
||||
return jsonDecode(response.body) as Map<String, dynamic>;
|
||||
} else {
|
||||
return {};
|
||||
|
|
|
@ -8,13 +8,13 @@ import 'package:cake_wallet/buy/payment_method.dart';
|
|||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:developer';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class MeldBuyProvider extends BuyProvider {
|
||||
|
@ -71,8 +71,8 @@ class MeldBuyProvider extends BuyProvider {
|
|||
final url = Uri.https(_baseUrl, path, params);
|
||||
|
||||
try {
|
||||
final response = await http.get(
|
||||
url,
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: url,
|
||||
headers: {
|
||||
'Authorization': _isProduction ? '' : _testApiKey,
|
||||
'Meld-Version': '2023-12-19',
|
||||
|
@ -80,6 +80,7 @@ class MeldBuyProvider extends BuyProvider {
|
|||
'content-type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body) as List<dynamic>;
|
||||
|
@ -130,7 +131,12 @@ class MeldBuyProvider extends BuyProvider {
|
|||
});
|
||||
|
||||
try {
|
||||
final response = await http.post(url, headers: headers, body: body);
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: url,
|
||||
headers: headers,
|
||||
body: body,
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
|
|
@ -16,12 +16,12 @@ import 'package:cake_wallet/palette.dart';
|
|||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/themes/core/material_base_theme.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class MoonPayProvider extends BuyProvider {
|
||||
|
@ -98,9 +98,12 @@ class MoonPayProvider extends BuyProvider {
|
|||
Future<String> getMoonpaySignature(String query) async {
|
||||
final uri = Uri.https(_cIdBaseUrl, "/api/moonpay");
|
||||
|
||||
final response = await post(uri,
|
||||
headers: {'Content-Type': 'application/json', 'x-api-key': _exchangeHelperApiKey},
|
||||
body: json.encode({'query': query}));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: {'Content-Type': 'application/json', 'x-api-key': _exchangeHelperApiKey},
|
||||
body: json.encode({'query': query}),
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return (jsonDecode(response.body) as Map<String, dynamic>)['signature'] as String;
|
||||
|
@ -120,7 +123,11 @@ class MoonPayProvider extends BuyProvider {
|
|||
final url = Uri.https(_baseUrl, path, params);
|
||||
|
||||
try {
|
||||
final response = await get(url, headers: {'accept': 'application/json'});
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: url,
|
||||
headers: {'accept': 'application/json'},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body) as Map<String, dynamic>;
|
||||
} else {
|
||||
|
@ -191,8 +198,8 @@ class MoonPayProvider extends BuyProvider {
|
|||
final path = '$_currenciesPath/$formattedCryptoCurrency$quotePath';
|
||||
final url = Uri.https(_baseUrl, path, params);
|
||||
try {
|
||||
final response = await get(url);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: url);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
||||
|
@ -306,7 +313,8 @@ class MoonPayProvider extends BuyProvider {
|
|||
Future<Order> findOrderById(String id) async {
|
||||
final url = _apiUrl + _transactionsSuffix + '/$id' + '?apiKey=' + _apiKey;
|
||||
final uri = Uri.parse(url);
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(title: providerDescription, content: 'Transaction $id is not found!');
|
||||
|
|
|
@ -9,11 +9,12 @@ import 'package:cake_wallet/buy/payment_method.dart';
|
|||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/themes/core/theme_store.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class OnRamperBuyProvider extends BuyProvider {
|
||||
|
@ -66,8 +67,10 @@ class OnRamperBuyProvider extends BuyProvider {
|
|||
final url = Uri.https(_baseApiUrl, '$supported$defaultsAll', params);
|
||||
|
||||
try {
|
||||
final response =
|
||||
await http.get(url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: url,
|
||||
headers: {'Authorization': _apiKey, 'accept': 'application/json'},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
@ -102,8 +105,8 @@ class OnRamperBuyProvider extends BuyProvider {
|
|||
|
||||
try {
|
||||
final response =
|
||||
await http.get(url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
|
||||
|
||||
await ProxyWrapper().get(clearnetUri: url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
final List<dynamic> message = data['message'] as List<dynamic>;
|
||||
|
@ -132,7 +135,8 @@ class OnRamperBuyProvider extends BuyProvider {
|
|||
|
||||
try {
|
||||
final response =
|
||||
await http.get(url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
|
||||
await ProxyWrapper().get(clearnetUri: url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
|
||||
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
@ -195,8 +199,8 @@ class OnRamperBuyProvider extends BuyProvider {
|
|||
final headers = {'Authorization': _apiKey, 'accept': 'application/json'};
|
||||
|
||||
try {
|
||||
final response = await http.get(url, headers: headers);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: url, headers: headers);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body) as List<dynamic>;
|
||||
if (data.isEmpty) return null;
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:cake_wallet/generated/i18n.dart';
|
|||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
@ -18,7 +19,6 @@ import 'package:cw_core/utils/print_verbose.dart';
|
|||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class RobinhoodBuyProvider extends BuyProvider {
|
||||
|
@ -69,7 +69,8 @@ class RobinhoodBuyProvider extends BuyProvider {
|
|||
final uri = Uri.https(_apiBaseUrl, '$_assetsPath', {'applicationId': _applicationId});
|
||||
|
||||
try {
|
||||
final response = await http.get(uri, headers: {'accept': 'application/json'});
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: {'accept': 'application/json'});
|
||||
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseData = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
@ -122,12 +123,14 @@ class RobinhoodBuyProvider extends BuyProvider {
|
|||
|
||||
final uri = Uri.https(_cIdBaseUrl, "/api/robinhood");
|
||||
|
||||
var response = await http.post(uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json
|
||||
.encode({'valid_until': valid_until, 'wallet': walletAddress, 'signature': signature}));
|
||||
var response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json.encode({'valid_until': valid_until, 'wallet': walletAddress, 'signature': signature}),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
|
||||
return (jsonDecode(response.body) as Map<String, dynamic>)['connectId'] as String;
|
||||
} else {
|
||||
throw Exception('Provider currently unavailable. Status: ${response.statusCode}');
|
||||
|
@ -219,7 +222,8 @@ class RobinhoodBuyProvider extends BuyProvider {
|
|||
Uri.https('api.robinhood.com', '/catpay/v1/${cryptoCurrency.title}/quote/', queryParams);
|
||||
|
||||
try {
|
||||
final response = await http.get(uri, headers: {'accept': 'application/json'});
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: {'accept': 'application/json'});
|
||||
|
||||
final responseData = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:cake_wallet/buy/buy_exception.dart';
|
|||
import 'package:cake_wallet/buy/pairs_utils.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cake_wallet/buy/buy_amount.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider_description.dart';
|
||||
|
@ -73,18 +73,21 @@ class WyreBuyProvider extends BuyProvider {
|
|||
'referrerAccountId': _accountId,
|
||||
'lockFields': ['amount', 'sourceCurrency', 'destCurrency', 'dest']
|
||||
};
|
||||
final response = await post(uri,
|
||||
headers: {
|
||||
'Authorization': 'Bearer $_secretKey',
|
||||
'Content-Type': 'application/json',
|
||||
'cache-control': 'no-cache'
|
||||
},
|
||||
body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: {
|
||||
'Authorization': 'Bearer $_secretKey',
|
||||
'Content-Type': 'application/json',
|
||||
'cache-control': 'no-cache'
|
||||
},
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(title: providerDescription, content: 'Url $url is not found!');
|
||||
}
|
||||
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final urlFromResponse = responseJSON['url'] as String;
|
||||
return urlFromResponse;
|
||||
|
@ -101,18 +104,21 @@ class WyreBuyProvider extends BuyProvider {
|
|||
'country': _countryCode
|
||||
};
|
||||
final uri = Uri.parse(quoteUrl);
|
||||
final response = await post(uri,
|
||||
headers: {
|
||||
'Authorization': 'Bearer $_secretKey',
|
||||
'Content-Type': 'application/json',
|
||||
'cache-control': 'no-cache'
|
||||
},
|
||||
body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: {
|
||||
'Authorization': 'Bearer $_secretKey',
|
||||
'Content-Type': 'application/json',
|
||||
'cache-control': 'no-cache'
|
||||
},
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(title: providerDescription, content: 'Quote is not found!');
|
||||
}
|
||||
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final sourceAmount = responseJSON['sourceAmount'] as double;
|
||||
final destAmount = responseJSON['destAmount'] as double;
|
||||
|
@ -125,8 +131,7 @@ class WyreBuyProvider extends BuyProvider {
|
|||
Future<Order> findOrderById(String id) async {
|
||||
final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
|
||||
final orderUri = Uri.parse(orderUrl);
|
||||
final orderResponse = await get(orderUri);
|
||||
|
||||
final orderResponse = await ProxyWrapper().get(clearnetUri: orderUri);
|
||||
if (orderResponse.statusCode != 200) {
|
||||
throw BuyException(title: providerDescription, content: 'Order $id is not found!');
|
||||
}
|
||||
|
@ -142,8 +147,7 @@ class WyreBuyProvider extends BuyProvider {
|
|||
|
||||
final transferUrl = baseApiUrl + _transferSuffix + transferId + _trackSuffix;
|
||||
final transferUri = Uri.parse(transferUrl);
|
||||
final transferResponse = await get(transferUri);
|
||||
|
||||
final transferResponse = await ProxyWrapper().get(clearnetUri: transferUri);
|
||||
if (transferResponse.statusCode != 200) {
|
||||
throw BuyException(title: providerDescription, content: 'Transfer $transferId is not found!');
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ import 'dart:convert';
|
|||
import 'package:cake_wallet/cake_pay/cake_pay_order.dart';
|
||||
import 'package:cake_wallet/cake_pay/cake_pay_user_credentials.dart';
|
||||
import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cake_wallet/entities/country.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class CakePayApi {
|
||||
static const testBaseUri = false;
|
||||
|
@ -32,12 +32,17 @@ class CakePayApi {
|
|||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Api-Key $apiKey',
|
||||
};
|
||||
final response = await http.post(uri, headers: headers, body: json.encode({'email': email}));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode({'email': email}),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
}
|
||||
|
||||
|
||||
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (bodyJson.containsKey('user') && bodyJson['user']['email'] != null) {
|
||||
|
@ -64,12 +69,17 @@ class CakePayApi {
|
|||
};
|
||||
final query = <String, String>{'email': email, 'otp': code};
|
||||
|
||||
final response = await http.post(uri, headers: headers, body: json.encode(query));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode(query),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
}
|
||||
|
||||
|
||||
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (bodyJson.containsKey('error')) {
|
||||
|
@ -116,9 +126,14 @@ class CakePayApi {
|
|||
};
|
||||
|
||||
try {
|
||||
final response = await http.post(uri, headers: headers, body: json.encode(query));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode(query),
|
||||
);
|
||||
|
||||
if (response.statusCode != 201) {
|
||||
|
||||
final responseBody = json.decode(response.body);
|
||||
if (responseBody is List) {
|
||||
throw '${responseBody[0]}';
|
||||
|
@ -127,6 +142,7 @@ class CakePayApi {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
|
||||
return CakePayOrder.fromMap(bodyJson);
|
||||
} catch (e) {
|
||||
|
@ -145,7 +161,8 @@ class CakePayApi {
|
|||
'X-CSRFToken': CSRFToken,
|
||||
};
|
||||
|
||||
final response = await http.get(uri, headers: headers);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
|
||||
|
||||
|
||||
printV('Response: ${response.statusCode}');
|
||||
|
||||
|
@ -168,7 +185,11 @@ class CakePayApi {
|
|||
};
|
||||
|
||||
try {
|
||||
final response = await http.post(uri, headers: headers, body: json.encode({'email': email}));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode({'email': email}),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
|
@ -187,8 +208,8 @@ class CakePayApi {
|
|||
'Authorization': 'Api-Key $apiKey',
|
||||
};
|
||||
|
||||
final response = await http.get(uri, headers: headers);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
}
|
||||
|
@ -234,14 +255,15 @@ class CakePayApi {
|
|||
'Authorization': 'Api-Key $apiKey',
|
||||
};
|
||||
|
||||
var response = await http.get(uri, headers: headers);
|
||||
var response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
|
||||
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception(
|
||||
'Failed to fetch vendors: statusCode - ${response.statusCode}, queryParams -$queryParams, response - ${response.body}');
|
||||
}
|
||||
|
||||
final bodyJson = json.decode(utf8.decode(response.bodyBytes));
|
||||
final bodyJson = json.decode(response.body);
|
||||
|
||||
if (bodyJson is List<dynamic> && bodyJson.isEmpty) {
|
||||
return [];
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
11
lib/di.dart
11
lib/di.dart
|
@ -33,10 +33,12 @@ import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
|
|||
import 'package:cake_wallet/haven/cw_haven.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/network_requests.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/secure_preferences_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/shared_preferences_page.dart';
|
||||
import 'package:cake_wallet/src/screens/integrations/deuro/savings_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/background_sync_page.dart';
|
||||
import 'package:cake_wallet/src/screens/start_tor/start_tor_page.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_connect/services/bottom_sheet_service.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_connect/services/key_service/wallet_connect_key_service.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_connect/services/walletkit_service.dart';
|
||||
|
@ -48,6 +50,7 @@ import 'package:cake_wallet/view_model/integrations/deuro_view_model.dart';
|
|||
import 'package:cake_wallet/view_model/link_view_model.dart';
|
||||
import 'package:cake_wallet/tron/tron.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
|
||||
import 'package:cake_wallet/view_model/start_tor_view_model.dart';
|
||||
import 'package:cw_core/receive_page_option.dart';
|
||||
import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
|
||||
import 'package:cake_wallet/entities/wallet_manager.dart';
|
||||
|
@ -138,7 +141,6 @@ import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
|
|||
import 'package:cake_wallet/src/screens/settings/privacy_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/security_backup_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/silent_payments_settings.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/tor_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart';
|
||||
import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
|
||||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
|
||||
|
@ -690,7 +692,6 @@ Future<void> setup({
|
|||
return walletKitService;
|
||||
});
|
||||
|
||||
getIt.registerFactory(() => NFTViewModel(appStore, getIt.get<BottomSheetService>()));
|
||||
getIt.registerFactory(() => BalancePage(
|
||||
nftViewModel: getIt.get<NFTViewModel>(),
|
||||
dashboardViewModel: getIt.get<DashboardViewModel>(),
|
||||
|
@ -1495,7 +1496,7 @@ Future<void> setup({
|
|||
() => WalletConnectConnectionsView(walletKitService: getIt.get<WalletKitService>()),
|
||||
);
|
||||
|
||||
getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>()));
|
||||
getIt.registerFactory(() => NFTViewModel(appStore, getIt.get<BottomSheetService>()));
|
||||
|
||||
getIt.registerFactory(() => SignViewModel(getIt.get<AppStore>().wallet!));
|
||||
|
||||
|
@ -1512,7 +1513,11 @@ Future<void> setup({
|
|||
getIt.registerFactory(() => BackgroundSyncLogsViewModel());
|
||||
|
||||
getIt.registerFactory(() => DevBackgroundSyncLogsPage(getIt.get<BackgroundSyncLogsViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => DevNetworkRequests());
|
||||
|
||||
getIt.registerFactory(() => StartTorPage(StartTorViewModel(),));
|
||||
|
||||
getIt.registerFactory(() => DEuroViewModel(getIt<AppStore>()));
|
||||
|
||||
getIt.registerFactory(() => DEuroSavingsPage(getIt<DEuroViewModel>()));
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||
import 'package:cake_wallet/polygon/polygon.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:ens_dart/ens_dart.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:web3dart/web3dart.dart';
|
||||
|
||||
class EnsRecord {
|
||||
|
||||
static Future<String> fetchEnsAddress(String name, {WalletBase? wallet}) async {
|
||||
|
||||
Web3Client? _client;
|
||||
|
||||
if (wallet != null && wallet.type == WalletType.ethereum) {
|
||||
|
@ -20,7 +22,9 @@ class EnsRecord {
|
|||
}
|
||||
|
||||
if (_client == null) {
|
||||
_client = Web3Client("https://ethereum-rpc.publicnode.com", Client());
|
||||
late final client = ProxyWrapper().getHttpIOClient();
|
||||
|
||||
_client = Web3Client("https://ethereum-rpc.publicnode.com", client);
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
|
||||
class FioAddressProvider {
|
||||
static const apiAuthority = 'fio.blockpane.com';
|
||||
|
@ -13,13 +13,17 @@ class FioAddressProvider {
|
|||
final body = <String, String>{"fio_name": fioAddress};
|
||||
|
||||
final uri = Uri.https(apiAuthority, availCheck);
|
||||
final response =
|
||||
await http.post(uri, headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
return isFioRegistered;
|
||||
}
|
||||
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
isFioRegistered = responseJSON['is_registered'] as int == 1;
|
||||
|
||||
|
@ -35,9 +39,13 @@ class FioAddressProvider {
|
|||
};
|
||||
|
||||
final uri = Uri.https(apiAuthority, getAddress);
|
||||
final response =
|
||||
await http.post(uri, headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode == 400) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final error = responseJSON['error'] as String;
|
||||
|
|
|
@ -66,6 +66,7 @@ class PreferencesKey {
|
|||
static const moneroWalletPasswordUpdateV1Base = 'monero_wallet_update_v1';
|
||||
static const syncModeKey = 'sync_mode';
|
||||
static const syncAllKey = 'sync_all';
|
||||
static const builtinTorKey = 'builtin_tor';
|
||||
static const lastPopupDate = 'last_popup_date';
|
||||
static const lastAppReviewDate = 'last_app_review_date';
|
||||
static const sortBalanceBy = 'sort_balance_by';
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
|
||||
Future<String> fetchUnstoppableDomainAddress(String domain, String ticker) async {
|
||||
var address = '';
|
||||
|
||||
try {
|
||||
final uri = Uri.parse("https://api.unstoppabledomains.com/profile/public/${Uri.encodeQueryComponent(domain)}?fields=records");
|
||||
final jsonString = await http.read(uri);
|
||||
final jsonParsed = json.decode(jsonString) as Map<String, dynamic>;
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
final jsonParsed = json.decode(response.body) as Map<String, dynamic>;
|
||||
if (jsonParsed["records"] == null) {
|
||||
throw Exception(".records response from $uri is empty");
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
|||
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
|
||||
class WellKnownRecord {
|
||||
WellKnownRecord({
|
||||
|
@ -40,14 +40,15 @@ class WellKnownRecord {
|
|||
}
|
||||
|
||||
// lookup domain/.well-known/nano-currency.json and check if it has a nano address:
|
||||
final http.Response response = await http.get(
|
||||
Uri.parse("https://$domain/.well-known/$jsonLocation.json?names=$name"),
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: Uri.parse("https://$domain/.well-known/$jsonLocation.json?names=$name"),
|
||||
headers: <String, String>{"Accept": "application/json"},
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, dynamic> decoded = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
// Access the first element in the names array and retrieve its address
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
|
||||
class ZanoAlias {
|
||||
static Future<String?> fetchZanoAliasAddress(String alias) async {
|
||||
try {
|
||||
final uri = Uri.parse("http://zano.cakewallet.com:11211/json_rpc");
|
||||
final response = await http.post(
|
||||
uri,
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
body: json.encode({
|
||||
"id": 0,
|
||||
"jsonrpc": "2.0",
|
||||
|
@ -16,6 +16,7 @@ class ZanoAlias {
|
|||
"params": {"alias": alias}
|
||||
}),
|
||||
);
|
||||
|
||||
final jsonParsed = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
return jsonParsed['result']['alias_details']['address'] as String?;
|
||||
|
|
|
@ -12,7 +12,7 @@ import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
|
||||
class ChainflipExchangeProvider extends ExchangeProvider {
|
||||
ChainflipExchangeProvider({required this.tradesStore})
|
||||
|
@ -275,7 +275,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
|
|||
Future<Map<String, dynamic>> _getRequest(String path, Map<String, String> params) async {
|
||||
final uri = Uri.https(_baseURL, path, params);
|
||||
|
||||
final response = await http.get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if ((response.statusCode != 200) || (response.body.contains('error'))) {
|
||||
throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
|
||||
|
@ -287,7 +288,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
|
|||
Future<Map<String, dynamic>?> _getStatus(Map<String, String> params) async {
|
||||
final uri = Uri.https(_baseURL, _txInfoPath, params);
|
||||
|
||||
final response = await http.get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode == 404) return null;
|
||||
|
||||
|
|
|
@ -13,11 +13,11 @@ import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
|||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/device_info.dart';
|
||||
import 'package:cake_wallet/utils/distribution_info.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
class ChangeNowExchangeProvider extends ExchangeProvider {
|
||||
ChangeNowExchangeProvider({required SettingsStore settingsStore})
|
||||
: _settingsStore = settingsStore,
|
||||
|
@ -73,7 +73,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
|||
'flow': _getFlow(isFixedRateMode)
|
||||
};
|
||||
final uri = Uri.https(apiAuthority, rangePath, params);
|
||||
final response = await get(uri, headers: headers);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
|
||||
|
||||
|
||||
if (response.statusCode == 400) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
@ -118,7 +119,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
|||
params['fromAmount'] = amount.toString();
|
||||
|
||||
final uri = Uri.https(apiAuthority, estimatedAmountPath, params);
|
||||
final response = await get(uri, headers: headers);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final fromAmount = double.parse(responseJSON['fromAmount'].toString());
|
||||
final toAmount = double.parse(responseJSON['toAmount'].toString());
|
||||
|
@ -177,7 +179,12 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
|||
}
|
||||
|
||||
final uri = Uri.https(apiAuthority, createTradePath);
|
||||
final response = await post(uri, headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode == 400) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
@ -220,7 +227,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
|||
final headers = {apiHeaderKey: apiKey};
|
||||
final params = <String, String>{'id': id};
|
||||
final uri = Uri.https(apiAuthority, findTradeByIdPath, params);
|
||||
final response = await get(uri, headers: headers);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
|
||||
|
||||
|
||||
if (response.statusCode == 404) throw TradeNotFoundException(id, provider: description);
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ import 'package:cake_wallet/exchange/trade_not_found_exception.dart';
|
|||
import 'package:cake_wallet/exchange/trade_request.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
class ExolixExchangeProvider extends ExchangeProvider {
|
||||
ExolixExchangeProvider() : super(pairList: supportedPairs(_notSupported));
|
||||
|
@ -86,8 +86,9 @@ class ExolixExchangeProvider extends ExchangeProvider {
|
|||
// Maximum of 2 attempts to fetch limits
|
||||
for (int i = 0; i < 2; i++) {
|
||||
final uri = Uri.https(apiBaseUrl, ratePath, params);
|
||||
final response = await get(uri);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final minAmount = responseJSON['minAmount'];
|
||||
|
@ -133,7 +134,8 @@ class ExolixExchangeProvider extends ExchangeProvider {
|
|||
params['amount'] = amount.toString();
|
||||
|
||||
final uri = Uri.https(apiBaseUrl, ratePath, params);
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
|
@ -172,7 +174,12 @@ class ExolixExchangeProvider extends ExchangeProvider {
|
|||
body['amount'] = request.fromAmount;
|
||||
|
||||
final uri = Uri.https(apiBaseUrl, transactionsPath);
|
||||
final response = await post(uri, headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode == 400) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
@ -214,8 +221,8 @@ class ExolixExchangeProvider extends ExchangeProvider {
|
|||
Future<Trade> findTradeById({required String id}) async {
|
||||
final findTradeByIdPath = '$transactionsPath/$id';
|
||||
final uri = Uri.https(apiBaseUrl, findTradeByIdPath);
|
||||
final response = await get(uri);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
if (response.statusCode == 404) throw TradeNotFoundException(id, provider: description);
|
||||
|
||||
if (response.statusCode == 400) {
|
||||
|
|
|
@ -10,9 +10,9 @@ import 'package:cake_wallet/exchange/trade_not_created_exception.dart';
|
|||
import 'package:cake_wallet/exchange/trade_request.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class LetsExchangeExchangeProvider extends ExchangeProvider {
|
||||
LetsExchangeExchangeProvider() : super(pairList: supportedPairs(_notSupported));
|
||||
|
@ -152,7 +152,11 @@ class LetsExchangeExchangeProvider extends ExchangeProvider {
|
|||
|
||||
final uri = Uri.https(_baseUrl,
|
||||
isFixedRateMode ? _createTransactionRevertPath : _createTransactionPath, tradeParams);
|
||||
final response = await http.post(uri, headers: headers);
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('LetsExchange create trade failed: ${response.body}');
|
||||
|
@ -218,7 +222,8 @@ class LetsExchangeExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
|
||||
final url = Uri.https(_baseUrl, '$_getTransactionPath/$id');
|
||||
final response = await http.get(url, headers: headers);
|
||||
final response = await ProxyWrapper().get(clearnetUri: url, headers: headers);
|
||||
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('LetsExchange fetch trade failed: ${response.body}');
|
||||
|
@ -266,7 +271,11 @@ class LetsExchangeExchangeProvider extends ExchangeProvider {
|
|||
|
||||
try {
|
||||
final uri = Uri.https(_baseUrl, isFixedRateMode ? _infoRevertPath : _infoPath, params);
|
||||
final response = await http.post(uri, headers: headers);
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('LetsExchange fetch info failed: ${response.body}');
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
|
||||
|
@ -11,9 +10,9 @@ import 'package:cake_wallet/exchange/trade_not_found_exception.dart';
|
|||
import 'package:cake_wallet/exchange/trade_request.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
class SideShiftExchangeProvider extends ExchangeProvider {
|
||||
SideShiftExchangeProvider() : super(pairList: supportedPairs(_notSupported));
|
||||
|
@ -60,8 +59,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
|
|||
Future<bool> checkIsAvailable() async {
|
||||
const url = apiBaseUrl + permissionPath;
|
||||
final uri = Uri.parse(url);
|
||||
final response = await get(uri);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
if (response.statusCode == 500) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final error = responseJSON['error']['message'] as String;
|
||||
|
@ -90,7 +89,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
|
|||
"$apiBaseUrl$rangePath/${fromCurrency.title.toLowerCase()}-$fromNetwork/${toCurrency.title.toLowerCase()}-$toNetwork";
|
||||
|
||||
final uri = Uri.parse(url);
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode == 500) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
@ -137,7 +137,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
|
|||
"$apiBaseUrl$rangePath/$fromCurrency-$depositNetwork/$toCurrency-$settleNetwork?amount=$amount";
|
||||
|
||||
final uri = Uri.parse(url);
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (response.statusCode == 500) {
|
||||
|
@ -186,7 +187,12 @@ class SideShiftExchangeProvider extends ExchangeProvider {
|
|||
final headers = {'Content-Type': 'application/json'};
|
||||
|
||||
final uri = Uri.parse(url);
|
||||
final response = await post(uri, headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode != 201) {
|
||||
if (response.statusCode == 400) {
|
||||
|
@ -227,8 +233,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
|
|||
Future<Trade> findTradeById({required String id}) async {
|
||||
final url = apiBaseUrl + orderPath + '/' + id;
|
||||
final uri = Uri.parse(url);
|
||||
final response = await get(uri);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
if (response.statusCode == 404) {
|
||||
throw TradeNotFoundException(id, provider: description);
|
||||
}
|
||||
|
@ -281,7 +287,12 @@ class SideShiftExchangeProvider extends ExchangeProvider {
|
|||
'depositNetwork': _networkFor(request.fromCurrency),
|
||||
};
|
||||
final uri = Uri.parse(url);
|
||||
final response = await post(uri, headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode != 201) {
|
||||
if (response.statusCode == 400) {
|
||||
|
|
|
@ -11,8 +11,8 @@ import 'package:cake_wallet/exchange/trade_request.dart';
|
|||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cake_wallet/utils/device_info.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
class SimpleSwapExchangeProvider extends ExchangeProvider {
|
||||
SimpleSwapExchangeProvider() : super(pairList: supportedPairs(_notSupported));
|
||||
|
@ -48,7 +48,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
|
|||
@override
|
||||
Future<bool> checkIsAvailable() async {
|
||||
final uri = Uri.https(apiAuthority, getEstimatePath, <String, String>{'api_key': apiKey});
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
return !(response.statusCode == 403);
|
||||
}
|
||||
|
@ -66,7 +66,8 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
final uri = Uri.https(apiAuthority, rangePath, params);
|
||||
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode == 500) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
@ -104,10 +105,10 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
|
|||
'fixed': isFixedRateMode.toString()
|
||||
};
|
||||
final uri = Uri.https(apiAuthority, getEstimatePath, params);
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.body == "null") return 0.00;
|
||||
|
||||
final data = json.decode(response.body) as String;
|
||||
|
||||
return double.parse(data) / amount;
|
||||
|
@ -134,7 +135,12 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
final uri = Uri.https(apiAuthority, createExchangePath, params);
|
||||
|
||||
final response = await post(uri, headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode != 200 && response.statusCode != 201) {
|
||||
if (response.statusCode == 400) {
|
||||
|
@ -176,8 +182,9 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
|
|||
Future<Trade> findTradeById({required String id}) async {
|
||||
final params = {'api_key': apiKey, 'id': id};
|
||||
final uri = Uri.https(apiAuthority, getExchangePath, params);
|
||||
final response = await get(uri);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode == 404) {
|
||||
throw TradeNotFoundException(id, provider: description);
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import 'package:cake_wallet/exchange/trade_not_created_exception.dart';
|
|||
import 'package:cake_wallet/exchange/trade_request.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class StealthExExchangeProvider extends ExchangeProvider {
|
||||
StealthExExchangeProvider() : super(pairList: supportedPairs(_notSupported));
|
||||
|
@ -63,8 +63,12 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
|
||||
try {
|
||||
final response = await http.post(Uri.parse(_baseUrl + _rangePath),
|
||||
headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: Uri.parse(_baseUrl + _rangePath),
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('StealthEx fetch limits failed: ${response.body}');
|
||||
}
|
||||
|
@ -134,8 +138,12 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
|||
'additional_fee_percent': _additionalFeePercent,
|
||||
};
|
||||
|
||||
final response = await http.post(Uri.parse(_baseUrl + _exchangesPath),
|
||||
headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: Uri.parse(_baseUrl + _exchangesPath),
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
|
||||
if (response.statusCode != 201) {
|
||||
throw Exception('StealthEx create trade failed: ${response.body}');
|
||||
|
@ -202,8 +210,9 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
|||
final headers = {'Authorization': apiKey, 'Content-Type': 'application/json'};
|
||||
|
||||
final uri = Uri.parse('$_baseUrl$_exchangesPath/$id');
|
||||
final response = await http.get(uri, headers: headers);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
|
||||
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('StealthEx fetch trade failed: ${response.body}');
|
||||
}
|
||||
|
@ -260,8 +269,12 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
|
||||
try {
|
||||
final response = await http.post(Uri.parse(_baseUrl + _amountPath),
|
||||
headers: headers, body: json.encode(body));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: Uri.parse(_baseUrl + _amountPath),
|
||||
headers: headers,
|
||||
body: json.encode(body),
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) return {};
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final rate = responseJSON['rate'] as Map<String, dynamic>?;
|
||||
|
|
|
@ -10,9 +10,9 @@ import 'package:cake_wallet/exchange/trade_not_found_exception.dart';
|
|||
import 'package:cake_wallet/exchange/trade_request.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
class SwapTradeExchangeProvider extends ExchangeProvider {
|
||||
SwapTradeExchangeProvider() : super(pairList: supportedPairs(_notSupported));
|
||||
|
@ -69,7 +69,8 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
|
|||
}) async {
|
||||
try {
|
||||
final uri = Uri.https(apiAuthority, getCoins);
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
|
@ -116,7 +117,12 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
|
||||
final uri = Uri.https(apiAuthority, getRate, params);
|
||||
final response = await post(uri, body: body, headers: headers);
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
body: json.encode(body),
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
final responseBody = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (response.statusCode != 200)
|
||||
|
@ -153,7 +159,12 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
|
||||
final uri = Uri.https(apiAuthority, createOrder, params);
|
||||
final response = await post(uri, body: body, headers: headers);
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
body: json.encode(body),
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
final responseBody = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (response.statusCode == 400 || responseBody["success"] == false) {
|
||||
|
@ -196,7 +207,12 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
|
||||
final uri = Uri.https(apiAuthority, order, params);
|
||||
final response = await post(uri, body: body, headers: headers);
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
body: json.encode(body),
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
final responseBody = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (response.statusCode == 400 || responseBody["success"] == false) {
|
||||
|
|
|
@ -7,10 +7,10 @@ import 'package:cake_wallet/exchange/trade.dart';
|
|||
import 'package:cake_wallet/exchange/trade_request.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class ThorChainExchangeProvider extends ExchangeProvider {
|
||||
ThorChainExchangeProvider({required this.tradesStore})
|
||||
|
@ -164,7 +164,8 @@ class ThorChainExchangeProvider extends ExchangeProvider {
|
|||
if (id.isEmpty) throw Exception('Trade id is empty');
|
||||
final formattedId = id.startsWith('0x') ? id.substring(2) : id;
|
||||
final uri = Uri.https(_baseNodeURL, '$_txInfoPath$formattedId');
|
||||
final response = await http.get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode == 404) {
|
||||
throw Exception('Trade not found for id: $formattedId');
|
||||
|
@ -217,8 +218,8 @@ class ThorChainExchangeProvider extends ExchangeProvider {
|
|||
|
||||
static Future<Map<String, String>?>? lookupAddressByName(String name) async {
|
||||
final uri = Uri.https(_baseURL, '$_nameLookUpPath$name');
|
||||
final response = await http.get(uri);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
return null;
|
||||
}
|
||||
|
@ -244,8 +245,8 @@ class ThorChainExchangeProvider extends ExchangeProvider {
|
|||
Future<Map<String, dynamic>> _getSwapQuote(Map<String, String> params) async {
|
||||
Uri uri = Uri.https(_baseNodeURL, _quotePath, params);
|
||||
|
||||
final response = await http.get(uri);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected HTTP status: ${response.statusCode}');
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import 'package:cake_wallet/exchange/trade.dart';
|
|||
import 'package:cake_wallet/exchange/trade_request.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
class TrocadorExchangeProvider extends ExchangeProvider {
|
||||
TrocadorExchangeProvider({this.useTorOnly = false, this.providerStates = const {}})
|
||||
|
@ -52,8 +52,9 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
];
|
||||
|
||||
static const apiKey = secrets.trocadorApiKey;
|
||||
static const onionApiAuthority = 'trocadorfyhlu27aefre5u7zri66gudtzdyelymftvr4yjwcxhfaqsid.onion';
|
||||
static const clearNetAuthority = 'api.trocador.app';
|
||||
static const onionApiAuthority = clearNetAuthority;
|
||||
// static const onionApiAuthority = 'trocadorfyhlu27aefre5u7zri66gudtzdyelymftvr4yjwcxhfaqsid.onion';
|
||||
static const markup = secrets.trocadorExchangeMarkup;
|
||||
static const newRatePath = '/new_rate';
|
||||
static const createTradePath = '/new_trade';
|
||||
|
@ -97,7 +98,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
|
||||
final uri = await _getUri(coinPath, params);
|
||||
final response = await get(uri, headers: {'API-Key': apiKey});
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: {'API-Key': apiKey});
|
||||
|
||||
|
||||
if (response.statusCode != 200)
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
|
@ -138,12 +140,10 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
};
|
||||
|
||||
final uri = await _getUri(newRatePath, params);
|
||||
final response = await get(uri, headers: {'API-Key': apiKey});
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: {'API-Key': apiKey});
|
||||
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (responseJSON['error'] != null) throw Exception(responseJSON['error']);
|
||||
|
||||
final fromAmount = double.parse(responseJSON['amount_from'].toString());
|
||||
final toAmount = double.parse(responseJSON['amount_to'].toString());
|
||||
final rateId = responseJSON['trade_id'] as String? ?? '';
|
||||
|
@ -206,8 +206,9 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
params['provider'] = _provider.first as String;
|
||||
|
||||
final uri = await _getUri(createTradePath, params);
|
||||
final response = await get(uri, headers: {'API-Key': apiKey});
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: {'API-Key': apiKey});
|
||||
|
||||
|
||||
if (response.statusCode == 400) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final error = responseJSON['error'] as String;
|
||||
|
@ -255,9 +256,10 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
@override
|
||||
Future<Trade> findTradeById({required String id}) async {
|
||||
final uri = await _getUri(tradePath, {'id': id});
|
||||
return get(uri, headers: {'API-Key': apiKey}).then((response) {
|
||||
return ProxyWrapper().get(clearnetUri: uri, headers: {'API-Key': apiKey}).then((response) async {
|
||||
if (response.statusCode != 200)
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
|
||||
|
||||
final responseListJson = json.decode(response.body) as List;
|
||||
final responseJSON = responseListJson.first;
|
||||
|
@ -292,7 +294,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
|
||||
Future<List<TrocadorPartners>> fetchProviders() async {
|
||||
final uri = await _getUri(providersListPath, {'api_key': apiKey});
|
||||
final response = await get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode != 200)
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
|
@ -355,7 +358,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
if (useTorOnly) return uri;
|
||||
|
||||
try {
|
||||
await get(uri);
|
||||
await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
return uri;
|
||||
} catch (e) {
|
||||
|
|
|
@ -10,8 +10,7 @@ import 'package:cake_wallet/exchange/trade_state.dart';
|
|||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
class XOSwapExchangeProvider extends ExchangeProvider {
|
||||
XOSwapExchangeProvider() : super(pairList: supportedPairs(_notSupported));
|
||||
|
||||
|
@ -72,7 +71,8 @@ class XOSwapExchangeProvider extends ExchangeProvider {
|
|||
final uri = Uri.https(_apiAuthority, _apiPath + _assets,
|
||||
{'networks': normalizedNetwork, 'query': currency.title});
|
||||
|
||||
final response = await http.get(uri, headers: _headers);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Failed to fetch assets for ${currency.title} on ${currency.tag}');
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ class XOSwapExchangeProvider extends ExchangeProvider {
|
|||
if (curFrom == null || curTo == null) return [];
|
||||
final pairId = curFrom + '_' + curTo;
|
||||
final uri = Uri.https(_apiAuthority, '$_apiPath$_pairsPath/$pairId$_ratePath');
|
||||
final response = await http.get(uri, headers: _headers);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
if (response.statusCode != 200) return [];
|
||||
return json.decode(response.body) as List<dynamic>;
|
||||
} catch (e) {
|
||||
|
@ -205,7 +206,12 @@ class XOSwapExchangeProvider extends ExchangeProvider {
|
|||
'pairId': pairId,
|
||||
};
|
||||
|
||||
final response = await http.post(uri, headers: _headers, body: json.encode(payload));
|
||||
final response = await ProxyWrapper().post(
|
||||
clearnetUri: uri,
|
||||
headers: _headers,
|
||||
body: json.encode(payload),
|
||||
);
|
||||
|
||||
if (response.statusCode != 201) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final error = responseJSON['error'] ?? 'Unknown error';
|
||||
|
@ -254,7 +260,8 @@ class XOSwapExchangeProvider extends ExchangeProvider {
|
|||
Future<Trade> findTradeById({required String id}) async {
|
||||
try {
|
||||
final uri = Uri.https(_apiAuthority, '$_apiPath$_orders/$id');
|
||||
final response = await http.get(uri, headers: _headers);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
if (responseJSON.containsKey('code') && responseJSON['code'] == 'NOT_FOUND') {
|
||||
|
|
|
@ -25,9 +25,12 @@ import 'package:cake_wallet/routes.dart';
|
|||
import 'package:cake_wallet/src/screens/root/root.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/store/authentication_store.dart';
|
||||
import 'package:cake_wallet/themes/core/material_base_theme.dart';
|
||||
import 'package:cake_wallet/themes/utils/theme_provider.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/device_info.dart';
|
||||
import 'package:cake_wallet/utils/exception_handler.dart';
|
||||
import 'package:cake_wallet/utils/feature_flag.dart';
|
||||
import 'package:cake_wallet/view_model/link_view_model.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cw_core/address_info.dart';
|
||||
|
@ -38,6 +41,8 @@ import 'package:cw_core/node.dart';
|
|||
import 'package:cw_core/payjoin_session.dart';
|
||||
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/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -87,6 +92,9 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {
|
|||
ledgerFile.writeAsStringSync("$content\n${event.message}");
|
||||
});
|
||||
}
|
||||
if (FeatureFlag.hasDevOptions) {
|
||||
ProxyWrapper.logger = MemoryProxyLogger();
|
||||
}
|
||||
|
||||
runApp(App(key: topLevelKey));
|
||||
isAppRunning = true;
|
||||
|
@ -194,8 +202,8 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
|
|||
final powNodes =
|
||||
await CakeHive.openBox<Node>(Node.boxName + "pow"); // must be different from Node.boxName
|
||||
final transactionDescriptions = await CakeHive.openBox<TransactionDescription>(
|
||||
TransactionDescription.boxName,
|
||||
encryptionKey: transactionDescriptionsBoxKey);
|
||||
TransactionDescription.boxName,
|
||||
encryptionKey: transactionDescriptionsBoxKey);
|
||||
final trades = await CakeHive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
|
||||
final orders = await CakeHive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
|
||||
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||
|
@ -279,7 +287,11 @@ Future<void> initialSetup({
|
|||
navigatorKey: navigatorKey,
|
||||
secureStorage: secureStorage,
|
||||
);
|
||||
await bootstrap(navigatorKey, loadWallet: loadWallet);
|
||||
await bootstrapOffline();
|
||||
final settingsStore = getIt<SettingsStore>();
|
||||
if (!settingsStore.currentBuiltinTor) {
|
||||
bootstrapOnline(navigatorKey, loadWallet: loadWallet);
|
||||
}
|
||||
}
|
||||
|
||||
class App extends StatefulWidget {
|
||||
|
@ -293,20 +305,24 @@ class App extends StatefulWidget {
|
|||
class AppState extends State<App> with SingleTickerProviderStateMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Observer(
|
||||
builder: (BuildContext context) {
|
||||
return Observer(builder: (BuildContext context) {
|
||||
final appStore = getIt.get<AppStore>();
|
||||
final authService = getIt.get<AuthService>();
|
||||
final linkViewModel = getIt.get<LinkViewModel>();
|
||||
final tradeMonitor = getIt.get<TradeMonitor>();
|
||||
final settingsStore = appStore.settingsStore;
|
||||
final statusBarColor = Colors.transparent;
|
||||
final authenticationStore = getIt.get<AuthenticationStore>();
|
||||
final initialRoute = authenticationStore.state == AuthenticationState.uninitialized
|
||||
? Routes.welcome
|
||||
: Routes.login;
|
||||
? Routes.welcome
|
||||
: settingsStore.currentBuiltinTor ? Routes.startTor : Routes.login;
|
||||
final currentTheme = appStore.themeStore.currentTheme;
|
||||
final statusBarBrightness = currentTheme.isDark ? Brightness.light : Brightness.dark;
|
||||
final statusBarIconBrightness = currentTheme.isDark ? Brightness.light : Brightness.dark;
|
||||
final statusBarBrightness = currentTheme.type == currentTheme.isDark
|
||||
? Brightness.light
|
||||
: Brightness.dark;
|
||||
final statusBarIconBrightness = currentTheme.type == currentTheme.isDark
|
||||
? Brightness.light
|
||||
: Brightness.dark;
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
statusBarColor: statusBarColor,
|
||||
statusBarBrightness: statusBarBrightness,
|
||||
|
@ -322,7 +338,8 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
|
|||
tradeMonitor: tradeMonitor,
|
||||
child: ThemeProvider(
|
||||
themeStore: appStore.themeStore,
|
||||
materialAppBuilder: (context, theme, darkTheme, themeMode) => MaterialApp(
|
||||
materialAppBuilder: (context, theme, darkTheme, themeMode) =>
|
||||
MaterialApp(
|
||||
navigatorObservers: [routeObserver],
|
||||
navigatorKey: navigatorKey,
|
||||
debugShowCheckedModeBanner: false,
|
||||
|
@ -365,8 +382,10 @@ class _HomeState extends State<_Home> {
|
|||
SystemChrome.setPreferredOrientations(
|
||||
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
|
||||
} else {
|
||||
SystemChrome.setPreferredOrientations(
|
||||
[DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
|
||||
SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'dart:convert';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cake_wallet/mastodon/mastodon_user.dart';
|
||||
|
||||
class MastodonAPI {
|
||||
|
@ -20,7 +20,8 @@ class MastodonAPI {
|
|||
queryParameters: queryParams,
|
||||
);
|
||||
|
||||
final response = await http.get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode != 200) return null;
|
||||
|
||||
|
@ -47,7 +48,8 @@ class MastodonAPI {
|
|||
queryParameters: queryParams,
|
||||
);
|
||||
|
||||
final response = await http.get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected HTTP status: ${response.statusCode}');
|
||||
|
|
|
@ -15,24 +15,29 @@ import 'package:cake_wallet/store/settings_store.dart';
|
|||
import 'package:cake_wallet/store/authentication_store.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
|
||||
Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey, {required bool loadWallet}) async {
|
||||
final appStore = getIt.get<AppStore>();
|
||||
Future<void> bootstrapOffline() async {
|
||||
final authenticationStore = getIt.get<AuthenticationStore>();
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
final fiatConversionStore = getIt.get<FiatConversionStore>();
|
||||
|
||||
final currentWalletName =
|
||||
getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName);
|
||||
if (currentWalletName != null) {
|
||||
authenticationStore.installed();
|
||||
}
|
||||
}
|
||||
|
||||
void bootstrapOnline(GlobalKey<NavigatorState> navigatorKey, {required bool loadWallet}) {
|
||||
final appStore = getIt.get<AppStore>();
|
||||
final authenticationStore = getIt.get<AuthenticationStore>();
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
final fiatConversionStore = getIt.get<FiatConversionStore>();
|
||||
|
||||
if (loadWallet) {
|
||||
startAuthenticationStateChange(authenticationStore, navigatorKey);
|
||||
}
|
||||
|
||||
startCurrentWalletChangeReaction(appStore, settingsStore, fiatConversionStore);
|
||||
startCurrentFiatChangeReaction(appStore, settingsStore, fiatConversionStore);
|
||||
startCurrentFiatApiModeChangeReaction(appStore, settingsStore, fiatConversionStore);
|
||||
startOnCurrentNodeChangeReaction(appStore);
|
||||
startFiatRateUpdate(appStore, settingsStore, fiatConversionStore);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,15 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/utils/tor.dart';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
Timer? _checkConnectionTimer;
|
||||
|
||||
|
@ -36,6 +40,10 @@ void startCheckConnectionReaction(WalletBase wallet, SettingsStore settingsStore
|
|||
final alive = await settingsStore.getCurrentNode(wallet.type).requestNode();
|
||||
|
||||
if (alive) {
|
||||
if (settingsStore.currentBuiltinTor) {
|
||||
await ensureTorStarted(context: null);
|
||||
}
|
||||
|
||||
await wallet.connectToNode(node: settingsStore.getCurrentNode(wallet.type));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/ethereum/ethereum.dart';
|
|||
import 'package:cake_wallet/polygon/polygon.dart';
|
||||
import 'package:cake_wallet/solana/solana.dart';
|
||||
import 'package:cake_wallet/tron/tron.dart';
|
||||
import 'package:cake_wallet/utils/tor.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
|
@ -83,6 +84,10 @@ void startCurrentWalletChangeReaction(
|
|||
bitcoin!.updatePayjoinState(wallet, settingsStore.usePayjoin);
|
||||
}
|
||||
|
||||
if (settingsStore.currentBuiltinTor) {
|
||||
await ensureTorStarted(context: null);
|
||||
}
|
||||
|
||||
await wallet.connectToNode(node: node);
|
||||
if (wallet.type == WalletType.nano || wallet.type == WalletType.banano) {
|
||||
final powNode = settingsStore.getCurrentPowNode(wallet.type);
|
||||
|
|
|
@ -38,6 +38,7 @@ import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
|
|||
import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/network_requests.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/secure_preferences_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/shared_preferences_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/background_sync_logs_page.dart';
|
||||
|
@ -93,7 +94,6 @@ import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
|
|||
import 'package:cake_wallet/src/screens/settings/privacy_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/security_backup_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/silent_payments_settings.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/tor_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart';
|
||||
import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
|
||||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
|
||||
|
@ -101,6 +101,7 @@ import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart
|
|||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_info_page.dart';
|
||||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart';
|
||||
import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart';
|
||||
import 'package:cake_wallet/src/screens/start_tor/start_tor_page.dart';
|
||||
import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart';
|
||||
import 'package:cake_wallet/src/screens/support/support_page.dart';
|
||||
import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart';
|
||||
|
@ -857,9 +858,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
),
|
||||
);
|
||||
|
||||
case Routes.torPage:
|
||||
return MaterialPageRoute<void>(builder: (_) => getIt.get<TorPage>());
|
||||
|
||||
case Routes.signPage:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => SignPage(
|
||||
|
@ -910,7 +908,12 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<DevBackgroundSyncLogsPage>(),
|
||||
);
|
||||
|
||||
|
||||
case Routes.devNetworkRequests:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<DevNetworkRequests>(),
|
||||
);
|
||||
|
||||
case Routes.devMoneroCallProfiler:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<DevMoneroCallProfilerPage>(),
|
||||
|
@ -920,6 +923,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<DevSecurePreferencesPage>(),
|
||||
);
|
||||
|
||||
case Routes.startTor:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<StartTorPage>(),
|
||||
);
|
||||
|
||||
case Routes.dEuroSavings:
|
||||
return MaterialPageRoute<void>(
|
||||
|
|
|
@ -110,14 +110,16 @@ class Routes {
|
|||
static const walletConnectConnectionsListing = '/wallet-connect-connections-listing';
|
||||
static const nftDetailsPage = '/nft_details_page';
|
||||
static const importNFTPage = '/import_nft_page';
|
||||
static const torPage = '/tor_page';
|
||||
static const backgroundSync = '/background_sync';
|
||||
static const startTor = '/start_tor';
|
||||
|
||||
static const devMoneroBackgroundSync = '/dev/monero_background_sync';
|
||||
static const devMoneroCallProfiler = '/dev/monero_call_profiler';
|
||||
|
||||
static const devSharedPreferences = '/dev/shared_preferences';
|
||||
static const devSecurePreferences = '/dev/secure_preferences';
|
||||
static const devBackgroundSyncLogs = '/dev/background_sync_logs';
|
||||
static const devNetworkRequests = '/dev/network_requests';
|
||||
|
||||
static const signPage = '/sign_page';
|
||||
static const connectDevices = '/device/connect';
|
||||
|
|
155
lib/src/screens/dev/network_requests.dart
Normal file
155
lib/src/screens/dev/network_requests.dart
Normal file
|
@ -0,0 +1,155 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/view_model/dev/network_requests_view_model.dart';
|
||||
import 'package:cw_core/utils/proxy_logger/abstract.dart';
|
||||
import 'package:cw_core/utils/proxy_logger/memory_proxy_logger.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
||||
class DevNetworkRequests extends BasePage {
|
||||
final NetworkRequestsViewModel viewModel = NetworkRequestsViewModel();
|
||||
|
||||
DevNetworkRequests() {
|
||||
viewModel.loadLogs();
|
||||
}
|
||||
|
||||
@override
|
||||
String? get title => "[dev] network requests";
|
||||
|
||||
@override
|
||||
Widget? trailing(BuildContext context) {
|
||||
return IconButton(
|
||||
icon: Icon(Icons.refresh),
|
||||
onPressed: () => viewModel.loadLogs(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Observer(
|
||||
builder: (_) {
|
||||
if (viewModel.logs.isEmpty) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text("No logs loaded"),
|
||||
SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () => viewModel.loadLogs(),
|
||||
child: Text("Load Logs"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return ListView.builder(
|
||||
itemCount: viewModel.logs.length,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
final item = viewModel.logs[i];
|
||||
return ListTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return DevRequestDetails(item);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: switch (item.network) {
|
||||
RequestNetwork.clearnet => Text("C"),
|
||||
RequestNetwork.tor => Text("T"),
|
||||
},
|
||||
trailing: switch (item.method) {
|
||||
RequestMethod.get => Text("GET"),
|
||||
RequestMethod.post => Text("POST"),
|
||||
RequestMethod.put => Text("PUT"),
|
||||
RequestMethod.delete => Text("DELETE"),
|
||||
RequestMethod.newHttpClient ||
|
||||
RequestMethod.newHttpIOClient ||
|
||||
RequestMethod.newProxySocket => null,
|
||||
},
|
||||
title: Text(item.time.toIso8601String()),
|
||||
subtitle: switch (item.method) {
|
||||
RequestMethod.get ||
|
||||
RequestMethod.post ||
|
||||
RequestMethod.put ||
|
||||
RequestMethod.delete => Text("${item.uri}"),
|
||||
RequestMethod.newHttpClient => Text("newHttpClient"),
|
||||
RequestMethod.newHttpIOClient => Text("newHttpIOClient"),
|
||||
RequestMethod.newProxySocket => Text("newProxySocket"),
|
||||
},
|
||||
tileColor: item.error != null ? Colors.red : null,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DevRequestDetails extends BasePage {
|
||||
final MemoryProxyLoggerEntry req;
|
||||
DevRequestDetails(this.req);
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: _body(context),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _body(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_sectionTitle("Time"),
|
||||
SelectableText(req.time.toString()),
|
||||
|
||||
_sectionTitle("Method"),
|
||||
SelectableText(req.method.toString()),
|
||||
|
||||
_sectionTitle("URI"),
|
||||
SelectableText(req.uri?.toString() ?? "null"),
|
||||
|
||||
_sectionTitle("Network"),
|
||||
SelectableText(req.network.toString()),
|
||||
|
||||
_sectionTitle("Body (as UTF-8)"),
|
||||
SelectableText(_tryDecodeBody(req.body)),
|
||||
|
||||
_sectionTitle("Response"),
|
||||
SelectableText(req.response?.body ?? "null"),
|
||||
|
||||
_sectionTitle("Error"),
|
||||
SelectableText(req.error ?? "No error"),
|
||||
|
||||
_sectionTitle("Stack Trace"),
|
||||
SelectableText(req.trace.toString()),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _sectionTitle(String title) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Text(
|
||||
title,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _tryDecodeBody(Uint8List body) {
|
||||
try {
|
||||
return utf8.decode(body);
|
||||
} catch (_) {
|
||||
return 'Binary data (${body.length} bytes)';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -196,8 +196,27 @@ class NodeForm extends StatelessWidget {
|
|||
Observer(
|
||||
builder: (_) => Column(
|
||||
children: [
|
||||
if (nodeViewModel.usesEmbeddedProxy) ...[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
StandardCheckbox(
|
||||
value: nodeViewModel.usesEmbeddedProxy,
|
||||
gradientBackground: false,
|
||||
borderColor: Theme.of(context).dividerColor,
|
||||
iconColor: Theme.of(context).colorScheme.primary,
|
||||
onChanged: null,
|
||||
caption: 'Embedded Tor SOCKS Proxy',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:cake_wallet/reactions/wallet_connect.dart';
|
|||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arrow.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/widgets/wallet_connect_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/utils/feature_flag.dart';
|
||||
|
@ -71,10 +72,28 @@ class ConnectionSyncPage extends BasePage {
|
|||
),
|
||||
],
|
||||
if (FeatureFlag.isInAppTorEnabled)
|
||||
SettingsCellWithArrow(
|
||||
title: S.current.tor_connection,
|
||||
handler: (context) => Navigator.of(context).pushNamed(Routes.torPage),
|
||||
),
|
||||
Observer(builder: (context) {
|
||||
return SettingsSwitcherCell(
|
||||
leading: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 1),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red.shade100,
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
),
|
||||
child: Text(
|
||||
'Alpha',
|
||||
style: TextStyle(
|
||||
color: Colors.red.shade700,
|
||||
fontSize: 8,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
title: S.current.enable_builtin_tor,
|
||||
value: dashboardViewModel.builtinTor,
|
||||
onValueChange: (_, bool value) => dashboardViewModel.setBuiltinTor(value, context),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -93,6 +93,12 @@ class OtherSettingsPage extends BasePage {
|
|||
handler: (BuildContext context) =>
|
||||
Navigator.of(context).pushNamed(Routes.devBackgroundSyncLogs),
|
||||
),
|
||||
if (FeatureFlag.hasDevOptions)
|
||||
SettingsCellWithArrow(
|
||||
title: '[dev] network requests logs',
|
||||
handler: (BuildContext context) =>
|
||||
Navigator.of(context).pushNamed(Routes.devNetworkRequests),
|
||||
),
|
||||
Spacer(),
|
||||
SettingsVersionCell(
|
||||
title: S.of(context).version(_otherSettingsViewModel.currentVersion)),
|
||||
|
|
|
@ -1,269 +0,0 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:tor/tor.dart';
|
||||
|
||||
class TorPage extends BasePage {
|
||||
final AppStore appStore;
|
||||
|
||||
TorPage(this.appStore);
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return TorPageBody(appStore);
|
||||
}
|
||||
}
|
||||
|
||||
class TorPageBody extends StatefulWidget {
|
||||
final AppStore appStore;
|
||||
|
||||
const TorPageBody(this.appStore, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<TorPageBody> createState() => _TorPageBodyState();
|
||||
}
|
||||
|
||||
class _TorPageBodyState extends State<TorPageBody> {
|
||||
bool torEnabled = false;
|
||||
bool connecting = false;
|
||||
|
||||
// Set the default text for the host input field.
|
||||
final hostController = TextEditingController(text: 'https://icanhazip.com/');
|
||||
|
||||
// https://check.torproject.org is another good option.
|
||||
|
||||
Future<void> startTor() async {
|
||||
setState(() {
|
||||
connecting = true; // Update flag
|
||||
});
|
||||
|
||||
// await Tor.init();
|
||||
//
|
||||
// // Start the proxy
|
||||
// await Tor.instance.start();
|
||||
//
|
||||
// // Toggle started flag.
|
||||
// setState(() {
|
||||
// torEnabled = Tor.instance.enabled; // Update flag
|
||||
// connecting = false;
|
||||
// });
|
||||
//
|
||||
// final node = widget.appStore.settingsStore.getCurrentNode(widget.appStore.wallet!.type);
|
||||
// if (node.socksProxyAddress?.isEmpty ?? true) {
|
||||
// node.socksProxyAddress = "${InternetAddress.loopbackIPv4.address}:${Tor.instance.port}";
|
||||
// }
|
||||
// widget.appStore.wallet!.connectToNode(node: node);
|
||||
|
||||
printV('Done awaiting; tor should be running');
|
||||
}
|
||||
|
||||
Future<void> endTor() async {
|
||||
// // Start the proxy
|
||||
// Tor.instance.disable();
|
||||
//
|
||||
// // Toggle started flag.
|
||||
// setState(() {
|
||||
// torEnabled = Tor.instance.enabled; // Update flag
|
||||
// });
|
||||
//
|
||||
// printV('Done awaiting; tor should be stopped');
|
||||
}
|
||||
//
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
//
|
||||
// torEnabled = Tor.instance.enabled;
|
||||
// }
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// Clean up the controller when the widget is disposed.
|
||||
hostController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: connecting
|
||||
? ConnectingScreen()
|
||||
: torEnabled
|
||||
? DisconnectScreen(disconnect: endTor)
|
||||
: ConnectScreen(connect: startTor),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ConnectScreen extends StatelessWidget {
|
||||
final Function() connect;
|
||||
|
||||
const ConnectScreen({super.key, required this.connect});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 200,
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.lock,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
size: 100,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 48),
|
||||
Text(
|
||||
'Connect to Tor',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
'Your connection to the Tor network ensures privacy and security.',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 48),
|
||||
ElevatedButton(
|
||||
onPressed: connect,
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 15),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'Connect',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
fontSize: 18,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DisconnectScreen extends StatelessWidget {
|
||||
final Function() disconnect;
|
||||
|
||||
const DisconnectScreen({super.key, required this.disconnect});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 200,
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: CustomThemeColors.syncGreen,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.check,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
size: 100,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Text(
|
||||
'Connected to Tor',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'You are currently connected to the Tor network.',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
ElevatedButton(
|
||||
onPressed: disconnect,
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 15),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'Disconnect',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
fontSize: 18,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ConnectingScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 200,
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: CustomThemeColors.syncYellow,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.hourglass_bottom,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
size: 100,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Text(
|
||||
'Connecting...',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
96
lib/src/screens/start_tor/start_tor_page.dart
Normal file
96
lib/src/screens/start_tor/start_tor_page.dart
Normal file
|
@ -0,0 +1,96 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/view_model/start_tor_view_model.dart';
|
||||
|
||||
class StartTorPage extends BasePage {
|
||||
StartTorPage(this.startTorViewModel);
|
||||
|
||||
final StartTorViewModel startTorViewModel;
|
||||
|
||||
@override
|
||||
String get title => S.current.tor_connection;
|
||||
|
||||
@override
|
||||
Widget leading(BuildContext context) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
startTorViewModel.startTor(context);
|
||||
return Container(
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(width: double.maxFinite),
|
||||
if (startTorViewModel.isLoading) ...[
|
||||
CircularProgressIndicator(),
|
||||
SizedBox(height: 20),
|
||||
_buildWaitingText(context),
|
||||
],
|
||||
if (startTorViewModel.showOptions) ...[
|
||||
_buildOptionsButtons(context),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildWaitingText(BuildContext context) {
|
||||
return Observer(
|
||||
builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
S.current.establishing_tor_connection,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
if (startTorViewModel.showOptions) _buildOptionsButtons(context),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildOptionsButtons(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
S.current.tor_connection_timeout,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
PrimaryButton(
|
||||
onPressed: () => startTorViewModel.disableTor(context),
|
||||
text: S.current.disable_tor,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
PrimaryButton(
|
||||
onPressed: () => startTorViewModel.ignoreAndLaunchApp(context),
|
||||
text: S.current.ignor,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,10 +2,10 @@ import 'dart:convert';
|
|||
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/reactions/wallet_connect.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:eth_sig_util/eth_sig_util.dart';
|
||||
import 'package:eth_sig_util/util/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:reown_walletkit/reown_walletkit.dart';
|
||||
|
||||
import 'package:cake_wallet/src/screens/wallet_connect/services/bottom_sheet_service.dart';
|
||||
|
@ -41,7 +41,7 @@ class EvmChainServiceImpl {
|
|||
}) : ethClient = web3Client ??
|
||||
Web3Client(
|
||||
appStore.settingsStore.getCurrentNode(appStore.wallet!.type).uri.toString(),
|
||||
http.Client(),
|
||||
ProxyWrapper().getHttpIOClient(),
|
||||
) {
|
||||
for (final event in EventsConstants.allEvents) {
|
||||
walletKit.registerEventEmitter(
|
||||
|
@ -563,14 +563,15 @@ class EvmChainServiceImpl {
|
|||
},
|
||||
);
|
||||
|
||||
final response = await http.get(
|
||||
uri,
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: uri,
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"X-API-Key": secrets.moralisApiKey,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
final decodedResponse = jsonDecode(response.body)[0] as Map<String, dynamic>;
|
||||
|
||||
final symbol = (decodedResponse['symbol'] ?? '') as String;
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:cake_wallet/src/screens/wallet_connect/services/walletkit_servic
|
|||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:reown_walletkit/reown_walletkit.dart';
|
||||
|
||||
|
@ -153,7 +154,10 @@ class WCCDetailsWidget extends BasePage {
|
|||
child: CircleAvatar(
|
||||
backgroundImage: (pairing.peerMetadata!.icons.isNotEmpty
|
||||
? NetworkImage(pairing.peerMetadata!.icons[0])
|
||||
: const AssetImage('assets/images/app_logo.png')) as ImageProvider<Object>,
|
||||
: AssetImage(
|
||||
CakeTor.instance.enabled
|
||||
? 'assets/images/tor_logo.svg'
|
||||
: 'assets/images/app_logo.png')) as ImageProvider<Object>,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20.0),
|
||||
|
|
|
@ -126,9 +126,9 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
|
|||
dividerColor: Colors.transparent,
|
||||
padding: EdgeInsets.zero,
|
||||
tabs: [
|
||||
Tab(text: S.of(context).widgets_seed),
|
||||
if (showKeyTab) Tab(text: S.of(context).keys),
|
||||
if (showLegacySeedTab) Tab(text: S.of(context).legacy),
|
||||
Tab(text: S.of(context).widgets_seed, key: ValueKey('wallet_keys_page_seed')),
|
||||
if (showKeyTab) Tab(text: S.of(context).keys, key: ValueKey('wallet_keys_page_keys'),),
|
||||
if (showLegacySeedTab) Tab(text: S.of(context).legacy, key: ValueKey('wallet_keys_page_seed_legacy')),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
|
||||
|
@ -265,7 +266,11 @@ class Badge extends StatelessWidget {
|
|||
}
|
||||
|
||||
Widget getImage(String imagePath, {double? height, double? width, Color? imageColor}) {
|
||||
final bool isNetworkImage = imagePath.startsWith('http') || imagePath.startsWith('https');
|
||||
bool isNetworkImage = imagePath.startsWith('http') || imagePath.startsWith('https');
|
||||
if (CakeTor.instance.enabled && isNetworkImage) {
|
||||
imagePath = "assets/images/tor_logo.svg";
|
||||
isNetworkImage = false;
|
||||
}
|
||||
final bool isSvg = imagePath.endsWith('.svg');
|
||||
final double imageHeight = height ?? 35;
|
||||
final double imageWidth = width ?? 35;
|
||||
|
|
|
@ -16,7 +16,7 @@ class StandardCheckbox extends StatelessWidget {
|
|||
final Color? borderColor;
|
||||
final Color? iconColor;
|
||||
final Color? captionColor;
|
||||
final Function(bool) onChanged;
|
||||
final Function(bool)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -40,7 +40,7 @@ class StandardCheckbox extends StatelessWidget {
|
|||
BoxDecoration(border: boxBorder, borderRadius: BorderRadius.all(Radius.circular(8.0)));
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => onChanged(!value),
|
||||
onTap: onChanged == null ? null : () => onChanged!(!value),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
|
|
|
@ -80,6 +80,7 @@ abstract class SettingsStoreBase with Store {
|
|||
required String initialLanguageCode,
|
||||
required SyncMode initialSyncMode,
|
||||
required bool initialSyncAll,
|
||||
required bool initialBuiltinTor,
|
||||
// required String initialCurrentLocale,
|
||||
required this.appVersion,
|
||||
required this.deviceName,
|
||||
|
@ -184,6 +185,7 @@ abstract class SettingsStoreBase with Store {
|
|||
initialShouldRequireTOTP2FAForAllSecurityAndBackupSettings,
|
||||
currentSyncMode = initialSyncMode,
|
||||
currentSyncAll = initialSyncAll,
|
||||
currentBuiltinTor = initialBuiltinTor,
|
||||
priority = ObservableMap<WalletType, TransactionPriority>() {
|
||||
//this.nodes = ObservableMap<WalletType, Node>.of(nodes);
|
||||
|
||||
|
@ -404,6 +406,11 @@ abstract class SettingsStoreBase with Store {
|
|||
sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
|
||||
});
|
||||
|
||||
reaction((_) => currentBuiltinTor, (bool builtinTor) {
|
||||
sharedPreferences.setBool(PreferencesKey.builtinTorKey, builtinTor);
|
||||
});
|
||||
|
||||
|
||||
reaction(
|
||||
(_) => exchangeStatus,
|
||||
(ExchangeApiMode mode) =>
|
||||
|
@ -821,6 +828,9 @@ abstract class SettingsStoreBase with Store {
|
|||
@observable
|
||||
bool currentSyncAll;
|
||||
|
||||
@observable
|
||||
bool currentBuiltinTor;
|
||||
|
||||
String appVersion;
|
||||
|
||||
String deviceName;
|
||||
|
@ -1168,6 +1178,7 @@ abstract class SettingsStoreBase with Store {
|
|||
return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 2); // default to 2 - daily sync
|
||||
});
|
||||
final savedSyncAll = sharedPreferences.getBool(PreferencesKey.syncAllKey) ?? true;
|
||||
final builtinTor = sharedPreferences.getBool(PreferencesKey.builtinTorKey) ?? false;
|
||||
|
||||
// migrated to secure:
|
||||
final timeOutDuration = await SecureKey.getInt(
|
||||
|
@ -1353,6 +1364,7 @@ abstract class SettingsStoreBase with Store {
|
|||
initialSyncAll: savedSyncAll,
|
||||
shouldShowYatPopup: shouldShowYatPopup,
|
||||
shouldShowRepWarning: shouldShowRepWarning,
|
||||
initialBuiltinTor: builtinTor,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,8 @@ import 'package:cw_core/wallet_base.dart';
|
|||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:cake_wallet/store/yat/yat_exception.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'dart:async';
|
||||
|
||||
part 'yat_store.g.dart';
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
|||
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/twitter/twitter_user.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
|
||||
class TwitterApi {
|
||||
static const twitterBearerToken = secrets.twitterBearerToken;
|
||||
|
@ -23,13 +23,14 @@ class TwitterApi {
|
|||
path: userPath + userName,
|
||||
queryParameters: queryParams);
|
||||
|
||||
final response = await http.get(uri, headers: headers).catchError((error) {
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers).catchError((error) {
|
||||
throw Exception('HTTP request failed: $error');
|
||||
});
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
}
|
||||
|
||||
|
||||
final Map<String, dynamic> responseJSON = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
if (responseJSON['errors'] != null &&
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'dart:io';
|
||||
|
||||
class FeatureFlag {
|
||||
static const bool isCakePayEnabled = false;
|
||||
static const bool isExolixEnabled = true;
|
||||
static const bool isInAppTorEnabled = false;
|
||||
static const bool isBackgroundSyncEnabled = true;
|
||||
static final bool isInAppTorEnabled = (Platform.isAndroid);
|
||||
static const int verificationWordsCount = kDebugMode ? 0 : 2;
|
||||
static const bool hasDevOptions = bool.fromEnvironment('hasDevOptions', defaultValue: kDebugMode);
|
||||
}
|
|
@ -1,13 +1,17 @@
|
|||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
|
||||
class ImageUtil {
|
||||
static Widget getImageFromPath({required String imagePath, double? height, double? width}) {
|
||||
final bool isNetworkImage = imagePath.startsWith('http') || imagePath.startsWith('https');
|
||||
bool isNetworkImage = imagePath.startsWith('http') || imagePath.startsWith('https');
|
||||
if (CakeTor.instance.enabled && isNetworkImage) {
|
||||
imagePath = "assets/images/tor_logo.svg";
|
||||
isNetworkImage = false;
|
||||
}
|
||||
final bool isSvg = imagePath.endsWith('.svg');
|
||||
final double _height = height ?? 35;
|
||||
final double _width = width ?? 35;
|
||||
|
||||
if (isNetworkImage) {
|
||||
return isSvg
|
||||
? SvgPicture.network(
|
||||
|
|
80
lib/utils/tor.dart
Normal file
80
lib/utils/tor.dart
Normal file
|
@ -0,0 +1,80 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
bool didTorStart = false;
|
||||
Future<void> ensureTorStopped({required BuildContext? context}) async {
|
||||
if (!didTorStart) {
|
||||
printV("Tor hasn't been initialized yet, so it can't be stopped.");
|
||||
return;
|
||||
}
|
||||
BuildContext? dialogContext;
|
||||
if (context != null) dialogContext = await showFullscreenDialog(context);
|
||||
didTorStart = false;
|
||||
printV("Stopping tor");
|
||||
await CakeTor.instance.stop();
|
||||
printV("Tor stopped");
|
||||
if (context != null) dismissFullscreenDialog(dialogContext!);
|
||||
}
|
||||
|
||||
Future<void> ensureTorStarted({required BuildContext? context}) async {
|
||||
if (didTorStart) {
|
||||
printV("Tor has already started");
|
||||
return;
|
||||
}
|
||||
BuildContext? dialogContext;
|
||||
if (context != null) dialogContext = await showFullscreenDialog(context);
|
||||
didTorStart = true;
|
||||
printV("Starting tor");
|
||||
// var rootToken = RootIsolateToken.instance!;
|
||||
// await Isolate.run(() async {
|
||||
// BackgroundIsolateBinaryMessenger.ensureInitialized(rootToken);
|
||||
// await CakeTor.instance.start();
|
||||
// });
|
||||
// second start is fast but populates the values on current thread
|
||||
await CakeTor.instance.start();
|
||||
printV("Tor 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) {
|
||||
printV("Waiting for tor to start (listening on port)");
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
}
|
||||
printV("Tor started on port ${CakeTor.instance.port}");
|
||||
if (context != null) dismissFullscreenDialog(dialogContext!);
|
||||
}
|
||||
|
||||
Future<BuildContext> showFullscreenDialog(BuildContext context) async {
|
||||
BuildContext? dialogContext;
|
||||
unawaited(
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) {
|
||||
dialogContext = context;
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
return dialogContext!;
|
||||
}
|
||||
|
||||
Future<void> dismissFullscreenDialog(BuildContext context) async {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
Navigator.of(context).pop();
|
||||
}
|
|
@ -6,6 +6,7 @@ import 'package:cake_wallet/entities/fiat_currency.dart';
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'cake_pay_cards_list_view_model.g.dart';
|
||||
|
@ -135,7 +136,11 @@ abstract class CakePayCardsListViewModelBase with Store {
|
|||
|
||||
|
||||
Future<void> getCountries() async {
|
||||
availableCountries = await cakePayService.getCountries();
|
||||
try {
|
||||
availableCountries = await cakePayService.getCountries();
|
||||
} catch (e) {
|
||||
printV(e);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -144,17 +149,21 @@ abstract class CakePayCardsListViewModelBase with Store {
|
|||
int? currentPage,
|
||||
}) async {
|
||||
vendorsState = CakePayVendorLoadingState();
|
||||
searchString = text ?? '';
|
||||
var newVendors = await cakePayService.getVendors(
|
||||
country: Country.getCakePayName(selectedCountry),
|
||||
page: currentPage ?? page,
|
||||
search: searchString,
|
||||
giftCards: displayGiftCards,
|
||||
prepaidCards: displayPrepaidCards,
|
||||
custom: displayCustomValueCards,
|
||||
onDemand: displayDenominationsCards);
|
||||
try {
|
||||
searchString = text ?? '';
|
||||
var newVendors = await cakePayService.getVendors(
|
||||
country: Country.getCakePayName(selectedCountry),
|
||||
page: currentPage ?? page,
|
||||
search: searchString,
|
||||
giftCards: displayGiftCards,
|
||||
prepaidCards: displayPrepaidCards,
|
||||
custom: displayCustomValueCards,
|
||||
onDemand: displayDenominationsCards);
|
||||
|
||||
cakePayVendors = CakePayVendorList = newVendors;
|
||||
cakePayVendors = CakePayVendorList = newVendors;
|
||||
} catch (e) {
|
||||
printV(e);
|
||||
}
|
||||
vendorsState = CakePayVendorLoadedState();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,11 @@ import 'package:cake_wallet/entities/service_status.dart';
|
|||
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cake_wallet/utils/tor.dart';
|
||||
import 'package:cake_wallet/wownero/wownero.dart' as wow;
|
||||
import 'package:cake_wallet/nano/nano.dart';
|
||||
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
|
@ -47,10 +52,9 @@ import 'package:cw_core/wallet_base.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:eth_sig_util/util/utils.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_daemon/flutter_daemon.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
@ -1027,6 +1031,39 @@ abstract class DashboardViewModelBase with Store {
|
|||
@computed
|
||||
bool get syncAll => settingsStore.currentSyncAll;
|
||||
|
||||
@computed
|
||||
bool get builtinTor => settingsStore.currentBuiltinTor;
|
||||
|
||||
@action
|
||||
void setBuiltinTor(bool value, BuildContext context) {
|
||||
if (value) {
|
||||
unawaited(showPopUp<bool>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).tor_connection,
|
||||
alertContent: S.of(context).tor_experimental,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop(true),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
settingsStore.currentBuiltinTor = value;
|
||||
if (value) {
|
||||
unawaited(ensureTorStarted(context: context).then((_) async {
|
||||
if (settingsStore.currentBuiltinTor == false) return; // return when tor got disabled in the meantime;
|
||||
await wallet.connectToNode(node: appStore.settingsStore.getCurrentNode(wallet.type));
|
||||
}));
|
||||
} else {
|
||||
unawaited(ensureTorStopped(context: context).then((_) async {
|
||||
if (settingsStore.currentBuiltinTor == true) return; // return when tor got enabled in the meantime;
|
||||
await wallet.connectToNode(node: appStore.settingsStore.getCurrentNode(wallet.type));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
void setSyncAll(bool value) => settingsStore.currentSyncAll = value;
|
||||
|
||||
|
@ -1073,7 +1110,17 @@ abstract class DashboardViewModelBase with Store {
|
|||
}
|
||||
}
|
||||
|
||||
static ServicesResponse? cachedServicesResponse;
|
||||
|
||||
Future<ServicesResponse> getServicesStatus() async {
|
||||
if (cachedServicesResponse != null) {
|
||||
return cachedServicesResponse!;
|
||||
}
|
||||
cachedServicesResponse = await _getServicesStatus();
|
||||
return cachedServicesResponse!;
|
||||
}
|
||||
|
||||
Future<ServicesResponse> _getServicesStatus() async {
|
||||
try {
|
||||
if (isEnabledBulletinAction) {
|
||||
final uri = Uri.https(
|
||||
|
@ -1082,8 +1129,7 @@ abstract class DashboardViewModelBase with Store {
|
|||
{'key': secrets.fiatApiKey},
|
||||
);
|
||||
|
||||
final res = await http.get(uri);
|
||||
|
||||
final res = await ProxyWrapper().get(clearnetUri: uri);
|
||||
if (res.statusCode < 200 || res.statusCode >= 300) {
|
||||
throw res.body;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import 'package:cake_wallet/reactions/wallet_connect.dart';
|
|||
import 'package:cake_wallet/solana/solana.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/tron/tron.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
||||
import 'package:cake_wallet/zano/zano.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
@ -19,7 +20,6 @@ import 'package:cw_core/erc20_token.dart';
|
|||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
|
||||
part 'home_settings_view_model.g.dart';
|
||||
|
@ -240,14 +240,14 @@ abstract class HomeSettingsViewModelBase with Store {
|
|||
);
|
||||
|
||||
try {
|
||||
final response = await http.get(
|
||||
uri,
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: uri,
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"X-API-Key": secrets.moralisApiKey,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
final decodedResponse = jsonDecode(response.body);
|
||||
|
||||
final tokenInfo = Erc20TokenInfoMoralis.fromJson(decodedResponse[0] as Map<String, dynamic>);
|
||||
|
@ -309,8 +309,8 @@ abstract class HomeSettingsViewModelBase with Store {
|
|||
);
|
||||
|
||||
try {
|
||||
final response = await http.get(uri);
|
||||
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (decodedResponse['status'] != '1') {
|
||||
|
@ -351,7 +351,8 @@ abstract class HomeSettingsViewModelBase with Store {
|
|||
);
|
||||
|
||||
try {
|
||||
final response = await http.get(uri);
|
||||
final response = await ProxyWrapper().get(clearnetUri: uri);
|
||||
|
||||
|
||||
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'package:cake_wallet/reactions/wallet_connect.dart';
|
|||
import 'package:cake_wallet/src/screens/wallet_connect/services/bottom_sheet_service.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_connect/widgets/bottom_sheet/bottom_sheet_message_display_widget.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
|
||||
|
@ -80,15 +80,16 @@ abstract class NFTViewModelBase with Store {
|
|||
|
||||
isLoading = true;
|
||||
|
||||
final response = await http.get(
|
||||
uri,
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: uri,
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"X-API-Key": secrets.moralisApiKey,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
final decodedResponse = jsonDecode(response.body);
|
||||
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
||||
if (walletType == WalletType.solana) {
|
||||
final results = await Future.wait(
|
||||
|
@ -131,14 +132,14 @@ abstract class NFTViewModelBase with Store {
|
|||
'/nft/$chainName/$address/metadata',
|
||||
);
|
||||
|
||||
final response = await http.get(
|
||||
uri,
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: uri,
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"X-API-Key": secrets.moralisApiKey,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
||||
return SolanaNFTAssetModel.fromJson(decodedResponse);
|
||||
|
@ -171,15 +172,14 @@ abstract class NFTViewModelBase with Store {
|
|||
"normalizeMetadata": "true",
|
||||
},
|
||||
);
|
||||
|
||||
final response = await http.get(
|
||||
uri,
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: uri,
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"X-API-Key": secrets.moralisApiKey,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
|
||||
final nftAsset = NFTAssetModel.fromJson(decodedResponse);
|
||||
|
|
16
lib/view_model/dev/network_requests_view_model.dart
Normal file
16
lib/view_model/dev/network_requests_view_model.dart
Normal file
|
@ -0,0 +1,16 @@
|
|||
import 'package:cw_core/utils/proxy_logger/memory_proxy_logger.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'network_requests_view_model.g.dart';
|
||||
|
||||
class NetworkRequestsViewModel = NetworkRequestsViewModelBase with _$NetworkRequestsViewModel;
|
||||
|
||||
abstract class NetworkRequestsViewModelBase with Store {
|
||||
@observable
|
||||
List<MemoryProxyLoggerEntry> logs = MemoryProxyLogger.logs;
|
||||
|
||||
@action
|
||||
Future<void> loadLogs() async {
|
||||
logs = MemoryProxyLogger.logs;
|
||||
}
|
||||
}
|
16
lib/view_model/dev/send_network_requests_view_model.dart
Normal file
16
lib/view_model/dev/send_network_requests_view_model.dart
Normal file
|
@ -0,0 +1,16 @@
|
|||
import 'package:cw_core/utils/proxy_logger/memory_proxy_logger.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'send_network_requests_view_model.g.dart';
|
||||
|
||||
class SendNetworkRequestsViewModel = SendNetworkRequestsViewModelBase with _$SendNetworkRequestsViewModel;
|
||||
|
||||
abstract class SendNetworkRequestsViewModelBase with Store {
|
||||
@observable
|
||||
List<MemoryProxyLoggerEntry> logs = MemoryProxyLogger.logs;
|
||||
|
||||
@action
|
||||
Future<void> loadLogs() async {
|
||||
logs = MemoryProxyLogger.logs;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/core/create_trade_result.dart';
|
|||
import 'package:cake_wallet/exchange/provider/chainflip_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/letsexchange_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/stealth_ex_exchange_provider.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cake_wallet/view_model/send/fees_view_model.dart';
|
||||
import 'package:cake_wallet/exchange/provider/xoswap_exchange_provider.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
@ -16,7 +17,6 @@ import 'package:cw_core/unspent_coin_type.dart';
|
|||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
@ -939,8 +939,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
|||
}
|
||||
|
||||
Future<bool> _isContractAddress(String chainName, String contractAddress) async {
|
||||
final httpClient = http.Client();
|
||||
|
||||
final uri = Uri.https(
|
||||
'deep-index.moralis.io',
|
||||
'/api/v2.2/erc20/metadata',
|
||||
|
@ -951,13 +949,14 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
|||
);
|
||||
|
||||
try {
|
||||
final response = await httpClient.get(
|
||||
uri,
|
||||
final response = await ProxyWrapper().get(
|
||||
clearnetUri: uri,
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"X-API-Key": secrets.moralisApiKey,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
final decodedResponse = jsonDecode(response.body)[0] as Map<String, dynamic>;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/entities/qr_scanner.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
@ -58,6 +59,9 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
|||
@observable
|
||||
bool useSocksProxy;
|
||||
|
||||
@computed
|
||||
bool get usesEmbeddedProxy => CakeTor.instance.started;
|
||||
|
||||
@observable
|
||||
String socksProxyAddress;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
|
@ -38,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' + S.current.orbot_running_alert : ''}';
|
||||
'${uri.endsWith('.onion') || uri.contains('.onion:') ? '\n' + (CakeTor.instance.enabled ? '' : S.current.orbot_running_alert) : ''}';
|
||||
|
||||
final ObservableList<Node> nodes;
|
||||
final SettingsStore settingsStore;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
|
@ -38,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' + S.current.orbot_running_alert : ''}';
|
||||
'${uri.endsWith('.onion') || uri.contains('.onion:') ? '\n' + (CakeTor.instance.enabled ? '' : S.current.orbot_running_alert) : ''}';
|
||||
|
||||
final ObservableList<Node> nodes;
|
||||
final SettingsStore settingsStore;
|
||||
|
|
95
lib/view_model/start_tor_view_model.dart
Normal file
95
lib/view_model/start_tor_view_model.dart
Normal file
|
@ -0,0 +1,95 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/main.dart';
|
||||
import 'package:cake_wallet/reactions/bootstrap.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/tor.dart';
|
||||
import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'start_tor_view_model.g.dart';
|
||||
|
||||
class StartTorViewModel = StartTorViewModelBase with _$StartTorViewModel;
|
||||
|
||||
abstract class StartTorViewModelBase with Store {
|
||||
StartTorViewModelBase() {
|
||||
_startTimer();
|
||||
}
|
||||
|
||||
Timer? _timer;
|
||||
final int waitTimeInSeconds = 15;
|
||||
|
||||
@observable
|
||||
bool isLoading = true;
|
||||
|
||||
@observable
|
||||
bool timeoutReached = false;
|
||||
|
||||
@observable
|
||||
int remainingSeconds = 15;
|
||||
|
||||
@computed
|
||||
bool get showOptions => timeoutReached;
|
||||
|
||||
@action
|
||||
void _startTimer() {
|
||||
remainingSeconds = waitTimeInSeconds;
|
||||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||
remainingSeconds -= 1;
|
||||
|
||||
if (remainingSeconds <= 0) {
|
||||
timer.cancel();
|
||||
timeoutReached = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@observable
|
||||
bool didStartTor = false;
|
||||
|
||||
@action
|
||||
Future<void> startTor(BuildContext context) async {
|
||||
if (didStartTor) {
|
||||
return;
|
||||
}
|
||||
await ensureTorStarted(context: null);
|
||||
while (true) {
|
||||
await Future.delayed(Duration(milliseconds: 250));
|
||||
if (CakeTor.instance.port != -1 && CakeTor.instance.started) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
didStartTor = true;
|
||||
final appStore = getIt.get<AppStore>();
|
||||
bootstrapOnline(navigatorKey, loadWallet: true);
|
||||
appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
|
||||
Navigator.pushReplacementNamed(context, Routes.login);
|
||||
}
|
||||
|
||||
@action
|
||||
void disableTor(BuildContext context) {
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
settingsStore.currentBuiltinTor = false;
|
||||
bootstrapOnline(navigatorKey, loadWallet: true);
|
||||
final appStore = getIt.get<AppStore>();
|
||||
appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
|
||||
Navigator.pushReplacementNamed(context, Routes.login);
|
||||
}
|
||||
|
||||
@action
|
||||
void ignoreAndLaunchApp(BuildContext context) {
|
||||
bootstrapOnline(navigatorKey, loadWallet: true);
|
||||
final appStore = getIt.get<AppStore>();
|
||||
appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
|
||||
Navigator.pushReplacementNamed(context, Routes.login);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_timer?.cancel();
|
||||
_timer = null;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue