route everything I was able to catch trough the built-in tor node

This commit is contained in:
Czarek Nakamoto 2025-01-16 14:56:52 +01:00
parent f10f2849bb
commit 3bc3b03a37
31 changed files with 665 additions and 458 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,4 @@
import 'package:cw_core/utils/http_client.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:intl/intl.dart';
import 'dart:convert';
@ -234,10 +235,14 @@ int getHavenHeightByDate({required DateTime date}) {
}
Future<int> getHavenCurrentHeight() async {
final response = await http.get(Uri.parse('https://explorer.havenprotocol.org/api/networkinfo'));
final req = await getHttpClient()
.getUrl(Uri.parse('https://explorer.havenprotocol.org/api/networkinfo'))
.timeout(Duration(seconds: 15));
final response = await req.close();
final stringResponse = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final info = jsonDecode(response.body);
final info = jsonDecode(stringResponse);
return info['data']['height'] as int;
} else {
throw Exception('Failed to load current blockchain height');
@ -269,13 +274,13 @@ const bitcoinDates = {
};
Future<int> getBitcoinHeightByDateAPI({required DateTime date}) async {
final response = await http.get(
Uri.parse(
"https://mempool.cakewallet.com/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}",
),
);
final req = await getHttpClient()
.getUrl(Uri.parse("https://mempool.cakewallet.com/api/v1/mining/blocks/timestamp/${(date.millisecondsSinceEpoch / 1000).round()}"))
.timeout(Duration(seconds: 15));
final response = await req.close();
final stringResponse = await response.transform(utf8.decoder).join();
return jsonDecode(response.body)['height'] as int;
return jsonDecode(stringResponse)['height'] as int;
}
int getBitcoinHeightByDate({required DateTime date}) {

View file

@ -352,13 +352,14 @@ class Node extends HiveObject with Keyable {
Future<bool> requestEthereumServer() async {
try {
final response = await http.get(
uri,
headers: {'Content-Type': 'application/json'},
);
final req = await getHttpClient()
.getUrl(uri,)
.timeout(Duration(seconds: 15));
final response = await req.close();
return response.statusCode >= 200 && response.statusCode < 300;
} catch (_) {
} catch (err) {
printV("Failed to request ethereum server: $err");
return false;
}
}

View file

@ -6,6 +6,7 @@ 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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:http/http.dart';
import 'package:cw_core/crypto_currency.dart';
@ -30,8 +31,9 @@ class AnonPayApi {
Future<AnonpayStatusResponse> paymentStatus(String id) async {
final authority = await _getAuthority();
final response = await get(Uri.https(authority, "$anonPayStatus/$id"));
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().get(clearnetUri: Uri.https(authority, "$anonPayStatus/$id"));
final responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final status = responseJSON['Status'] as String;
final fiatAmount = responseJSON['Fiat_Amount'] as double?;
final fiatEquiv = responseJSON['Fiat_Equiv'] as String?;
@ -71,9 +73,9 @@ class AnonPayApi {
}
final authority = await _getAuthority();
final response = await get(Uri.https(authority, anonPayPath, body));
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().get(clearnetUri: Uri.https(authority, anonPayPath, body));
final responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final id = responseJSON['ID'] as String;
final url = responseJSON['url'] as String;
final urlOnion = responseJSON['url_onion'] as String;
@ -149,14 +151,13 @@ class AnonPayApi {
final String apiAuthority = await _getAuthority();
final uri = Uri.https(apiAuthority, coinPath, params);
final response = await get(uri);
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) 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');
}
@ -204,7 +205,7 @@ class AnonPayApi {
return onionApiAuthority;
}
final uri = Uri.https(onionApiAuthority, '/anonpay');
await get(uri);
await ProxyWrapper().get(clearnetUri: uri);
return onionApiAuthority;
} catch (e) {
return clearNetAuthority;

View file

@ -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:cake_wallet/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';
@ -137,10 +138,12 @@ 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'});
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as List<dynamic>;
final data = jsonDecode(responseString) as List<dynamic>;
for (final item in data) {
if (item['name'] == fiatCurrency) return item as Map<String, dynamic>;
}
@ -160,10 +163,10 @@ 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'});
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final responseData = jsonDecode(response.body);
final responseData = jsonDecode(responseString);
if (responseData is List && responseData.isNotEmpty) {
return responseData.first as Map<String, dynamic>;

View file

@ -8,6 +8,7 @@ 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:cake_wallet/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';
@ -71,8 +72,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,9 +81,10 @@ class MeldBuyProvider extends BuyProvider {
'content-type': 'application/json',
},
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as List<dynamic>;
final data = jsonDecode(responseString) as List<dynamic>;
final paymentMethods =
data.map((e) => PaymentMethod.fromMeldJson(e as Map<String, dynamic>)).toList();
return paymentMethods;

View file

@ -16,6 +16,7 @@ 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:cake_wallet/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';
@ -120,9 +121,10 @@ 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'});
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
return jsonDecode(response.body) as Map<String, dynamic>;
return jsonDecode(responseString) as Map<String, dynamic>;
} else {
printV('MoonPay does not support fiat: $fiatCurrency');
return {};
@ -191,10 +193,10 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as Map<String, dynamic>;
final data = jsonDecode(responseString) as Map<String, dynamic>;
// Check if the response is for the correct fiat currency
if (isBuyAction) {
@ -306,13 +308,14 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw BuyException(title: providerDescription, content: 'Transaction $id is not found!');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final status = responseJSON['status'] as String;
final state = TradeState.deserialize(raw: status);
final createdAtRaw = responseJSON['createdAt'] as String;

View file

@ -9,6 +9,7 @@ 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/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';
@ -102,10 +103,10 @@ 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'});
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
final Map<String, dynamic> data = jsonDecode(responseString) as Map<String, dynamic>;
final List<dynamic> message = data['message'] as List<dynamic>;
final allAvailablePaymentMethods = message
@ -132,10 +133,11 @@ 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'});
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
final Map<String, dynamic> data = jsonDecode(responseString) as Map<String, dynamic>;
final List<dynamic> onramps = data['message'] as List<dynamic>;
@ -195,10 +197,10 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as List<dynamic>;
final data = jsonDecode(responseString) as List<dynamic>;
if (data.isEmpty) return null;
List<Quote> validQuotes = [];

View file

@ -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:cake_wallet/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';
@ -219,8 +220,9 @@ 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 responseData = jsonDecode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().get(clearnetUri: uri, headers: {'accept': 'application/json'});
final responseString = await response.transform(utf8.decoder).join();
final responseData = jsonDecode(responseString) as Map<String, dynamic>;
if (response.statusCode == 200) {
final paymentType = _getPaymentTypeByString(responseData['paymentMethod'] as String?);

View file

@ -3,6 +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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:http/http.dart';
import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/buy_provider.dart';
@ -125,13 +126,13 @@ 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);
final responseString = await orderResponse.transform(utf8.decoder).join();
if (orderResponse.statusCode != 200) {
throw BuyException(title: providerDescription, content: 'Order $id is not found!');
}
final orderResponseJSON = json.decode(orderResponse.body) as Map<String, dynamic>;
final orderResponseJSON = json.decode(responseString) as Map<String, dynamic>;
final transferId = orderResponseJSON['transferId'] as String;
final from = orderResponseJSON['sourceCurrency'] as String;
final to = orderResponseJSON['destCurrency'] as String;
@ -142,13 +143,13 @@ 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);
final transferResponseString = await transferResponse.transform(utf8.decoder).join();
if (transferResponse.statusCode != 200) {
throw BuyException(title: providerDescription, content: 'Transfer $transferId is not found!');
}
final transferResponseJSON = json.decode(transferResponse.body) as Map<String, dynamic>;
final transferResponseJSON = json.decode(transferResponseString) as Map<String, dynamic>;
final amount = transferResponseJSON['destAmount'] as double;
return Order(

View file

@ -3,6 +3,7 @@ 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:cake_wallet/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;
@ -145,7 +146,8 @@ class CakePayApi {
'X-CSRFToken': CSRFToken,
};
final response = await http.get(uri, headers: headers);
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
final responseString = await response.transform(utf8.decoder).join();
printV('Response: ${response.statusCode}');
@ -153,7 +155,7 @@ class CakePayApi {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
final bodyJson = json.decode(responseString) as Map<String, dynamic>;
throw Exception('You just bot a gift card with id: ${bodyJson['order_id']}');
}
@ -187,13 +189,13 @@ class CakePayApi {
'Authorization': 'Api-Key $apiKey',
};
final response = await http.get(uri, headers: headers);
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as List;
final bodyJson = json.decode(responseString) as List;
return bodyJson
.map<String>((country) => country['name'] as String)
.map((name) => Country.fromCakePayName(name))
@ -234,14 +236,15 @@ class CakePayApi {
'Authorization': 'Api-Key $apiKey',
};
var response = await http.get(uri, headers: headers);
var response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception(
'Failed to fetch vendors: statusCode - ${response.statusCode}, queryParams -$queryParams, response - ${response.body}');
'Failed to fetch vendors: statusCode - ${response.statusCode}, queryParams -$queryParams, response - ${responseString}');
}
final bodyJson = json.decode(utf8.decode(response.bodyBytes));
final bodyJson = json.decode(responseString);
if (bodyJson is List<dynamic> && bodyJson.isEmpty) {
return [];

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
import 'dart:convert';
@ -31,13 +32,14 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
uri = Uri.https(_fiatApiClearNetAuthority, _fiatApiPath, queryParams);
}
final response = await get(uri);
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
return 0.0;
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final results = responseJSON['results'] as Map<String, dynamic>;
if (results.isNotEmpty) {

View file

@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:cake_wallet/entities/yat_record.dart';
import 'package:cake_wallet/utils/proxy_wrapper.dart';
import 'package:http/http.dart';
class YatService {
@ -33,8 +34,9 @@ class YatService {
final yatRecords = <YatRecord>[];
try {
final response = await get(uri);
final resBody = json.decode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
final resBody = json.decode(responseString) as Map<String, dynamic>;
final results = resBody["result"] as Map<dynamic, dynamic>;
// Favour a subaddress over a standard address.
final yatRecord = (

64
lib/decred/decred.dart Normal file
View file

@ -0,0 +1,64 @@
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/output_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/unspent_transaction_output.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cake_wallet/view_model/send/output.dart';
import 'package:hive/hive.dart';
import 'package:cw_decred/transaction_priority.dart';
import 'package:cw_decred/wallet.dart';
import 'package:cw_decred/wallet_service.dart';
import 'package:cw_decred/wallet_creation_credentials.dart';
import 'package:cw_decred/amount_format.dart';
import 'package:cw_decred/transaction_credentials.dart';
import 'package:cw_decred/mnemonic.dart';
part 'cw_decred.dart';
Decred? decred = CWDecred();
abstract class Decred {
WalletCredentials createDecredNewWalletCredentials(
{required String name, WalletInfo? walletInfo});
WalletCredentials createDecredRestoreWalletFromSeedCredentials(
{required String name,
required String mnemonic,
required String password});
WalletCredentials createDecredRestoreWalletFromPubkeyCredentials(
{required String name,
required String pubkey,
required String password});
WalletService createDecredWalletService(Box<WalletInfo> walletInfoSource,
Box<UnspentCoinsInfo> unspentCoinSource);
List<TransactionPriority> getTransactionPriorities();
TransactionPriority getMediumTransactionPriority();
TransactionPriority getDecredTransactionPriorityMedium();
TransactionPriority getDecredTransactionPrioritySlow();
TransactionPriority deserializeDecredTransactionPriority(int raw);
int getFeeRate(Object wallet, TransactionPriority priority);
Object createDecredTransactionCredentials(
List<Output> outputs, TransactionPriority priority);
List<String> getAddresses(Object wallet);
String getAddress(Object wallet);
Future<void> generateNewAddress(Object wallet);
String formatterDecredAmountToString({required int amount});
double formatterDecredAmountToDouble({required int amount});
int formatterStringDoubleToDecredAmount(String amount);
List<Unspent> getUnspents(Object wallet);
void updateUnspents(Object wallet);
int heightByDate(DateTime date);
List<String> getDecredWordList();
String pubkey(Object wallet);
}

View file

@ -13,6 +13,7 @@ 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:cake_wallet/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';
@ -73,10 +74,11 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 400) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['error'] as String;
final message = responseJSON['message'] as String;
throw Exception('${error}\n$message');
@ -85,7 +87,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
if (response.statusCode != 200)
throw Exception('Unexpected http status: ${response.statusCode}');
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
return Limits(
min: responseJSON['minAmount'] as double?, max: responseJSON['maxAmount'] as double?);
}
@ -118,8 +120,9 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
params['fromAmount'] = amount.toString();
final uri = Uri.https(apiAuthority, estimatedAmountPath, params);
final response = await get(uri, headers: headers);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
final responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final fromAmount = double.parse(responseJSON['fromAmount'].toString());
final toAmount = double.parse(responseJSON['toAmount'].toString());
final rateId = responseJSON['rateId'] as String? ?? '';
@ -220,12 +223,13 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 404) throw TradeNotFoundException(id, provider: description);
if (response.statusCode == 400) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['message'] as String;
throw TradeNotFoundException(id, provider: description, description: error);
@ -234,7 +238,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
if (response.statusCode != 200)
throw Exception('Unexpected http status: ${response.statusCode}');
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final fromCurrency = responseJSON['fromCurrency'] as String;
final from = CryptoCurrency.fromString(fromCurrency);
final toCurrency = responseJSON['toCurrency'] as String;

View file

@ -9,6 +9,7 @@ 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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:http/http.dart';
@ -86,15 +87,16 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final minAmount = responseJSON['minAmount'];
final maxAmount = responseJSON['maxAmount'];
return Limits(min: _toDouble(minAmount), max: _toDouble(maxAmount));
} else if (response.statusCode == 422) {
final errorResponse = json.decode(response.body) as Map<String, dynamic>;
final errorResponse = json.decode(responseString) as Map<String, dynamic>;
if (errorResponse.containsKey('minAmount')) {
params['amount'] = errorResponse['minAmount'].toString();
continue;
@ -133,8 +135,9 @@ class ExolixExchangeProvider extends ExchangeProvider {
params['amount'] = amount.toString();
final uri = Uri.https(apiBaseUrl, ratePath, params);
final response = await get(uri);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
if (response.statusCode != 200) {
final message = responseJSON['message'] as String?;
@ -214,12 +217,12 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 404) throw TradeNotFoundException(id, provider: description);
if (response.statusCode == 400) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final errors = responseJSON['errors'] as Map<String, String>;
final errorMessage = errors.values.join(', ');
@ -229,7 +232,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
if (response.statusCode != 200)
throw Exception('Unexpected http status: ${response.statusCode}');
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final coinFrom = responseJSON['coinFrom']['coinCode'] as String;
final coinTo = responseJSON['coinTo']['coinCode'] as String;
final inputAddress = responseJSON['depositAddress'] as String;

View file

@ -10,6 +10,7 @@ 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:cake_wallet/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;
@ -218,12 +219,13 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception('LetsExchange fetch trade failed: ${response.body}');
throw Exception('LetsExchange fetch trade failed: ${responseString}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final from = responseJSON['coin_from'] as String;
final to = responseJSON['coin_to'] as String;
final payoutAddress = responseJSON['withdrawal'] as String;

View file

@ -11,6 +11,7 @@ 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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:http/http.dart';
@ -60,10 +61,10 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 500) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['error']['message'] as String;
throw Exception('$error');
@ -71,7 +72,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
if (response.statusCode != 200) return false;
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
return responseJSON['createShift'] as bool;
}
@ -90,10 +91,11 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 500) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['error']['message'] as String;
throw Exception('$error');
@ -103,7 +105,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final min = double.tryParse(responseJSON['min'] as String? ?? '');
final max = double.tryParse(responseJSON['max'] as String? ?? '');
@ -137,11 +139,12 @@ class SideShiftExchangeProvider extends ExchangeProvider {
"$apiBaseUrl$rangePath/$fromCurrency-$depositNetwork/$toCurrency-$settleNetwork?amount=$amount";
final uri = Uri.parse(url);
final response = await get(uri);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
if (response.statusCode == 500) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['error']['message'] as String;
throw Exception('SideShift Internal Server Error: $error');
@ -227,14 +230,14 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 404) {
throw TradeNotFoundException(id, provider: description);
}
if (response.statusCode == 400) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['error']['message'] as String;
throw TradeNotFoundException(id, provider: description, description: error);
@ -244,7 +247,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final fromCurrency = responseJSON['depositCoin'] as String;
final toCurrency = responseJSON['settleCoin'] as String;
final inputAddress = responseJSON['depositAddress'] as String;

View file

@ -11,6 +11,7 @@ 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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:http/http.dart';
@ -48,7 +49,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,10 +67,11 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
};
final uri = Uri.https(apiAuthority, rangePath, params);
final response = await get(uri);
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 500) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['message'] as String;
throw Exception('$error');
@ -79,7 +81,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final min = double.tryParse(responseJSON['min'] as String? ?? '');
final max = double.tryParse(responseJSON['max'] as String? ?? '');
@ -104,11 +106,12 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.body == "null") return 0.00;
if (responseString == "null") return 0.00;
final data = json.decode(response.body) as String;
final data = json.decode(responseString) as String;
return double.parse(data) / amount;
} catch (_) {
@ -176,14 +179,15 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 404) {
throw TradeNotFoundException(id, provider: description);
}
if (response.statusCode == 400) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['message'] as String;
throw TradeNotFoundException(id, provider: description, description: error);
@ -193,7 +197,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final fromCurrency = responseJSON['currency_from'] as String;
final toCurrency = responseJSON['currency_to'] as String;
final inputAddress = responseJSON['address_from'] as String;

View file

@ -10,6 +10,7 @@ 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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:http/http.dart' as http;
@ -202,12 +203,13 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception('StealthEx fetch trade failed: ${response.body}');
throw Exception('StealthEx fetch trade failed: ${responseString}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final deposit = responseJSON['deposit'] as Map<String, dynamic>;
final withdrawal = responseJSON['withdrawal'] as Map<String, dynamic>;

View file

@ -10,6 +10,7 @@ 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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:http/http.dart';
@ -69,9 +70,10 @@ 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 responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
if (response.statusCode != 200)
throw Exception('Unexpected http status: ${response.statusCode}');

View file

@ -7,6 +7,7 @@ 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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:hive/hive.dart';
@ -164,7 +165,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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 404) {
throw Exception('Trade not found for id: $formattedId');
@ -172,7 +174,7 @@ class ThorChainExchangeProvider extends ExchangeProvider {
throw Exception('Unexpected HTTP status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body);
final responseJSON = json.decode(responseString);
final Map<String, dynamic> stagesJson = responseJSON['stages'] as Map<String, dynamic>;
final inboundObservedStarted = stagesJson['inbound_observed']?['started'] as bool? ?? true;
@ -217,13 +219,13 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
return null;
}
final body = json.decode(response.body) as Map<String, dynamic>;
final body = json.decode(responseString) as Map<String, dynamic>;
final entries = body['entries'] as List<dynamic>?;
if (entries == null || entries.isEmpty) {
@ -244,17 +246,17 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception('Unexpected HTTP status: ${response.statusCode}');
}
if (response.body.contains('error')) {
throw Exception('Unexpected response: ${response.body}');
if (responseString.contains('error')) {
throw Exception('Unexpected response: ${responseString}');
}
return json.decode(response.body) as Map<String, dynamic>;
return json.decode(responseString) as Map<String, dynamic>;
}
String _normalizeCurrency(CryptoCurrency currency) {

View file

@ -8,6 +8,7 @@ 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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:http/http.dart';
@ -97,12 +98,13 @@ 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});
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200)
throw Exception('Unexpected http status: ${response.statusCode}');
final responseJSON = json.decode(response.body) as List<dynamic>;
final responseJSON = json.decode(responseString) as List<dynamic>;
if (responseJSON.isEmpty) throw Exception('No data');
@ -138,12 +140,10 @@ class TrocadorExchangeProvider extends ExchangeProvider {
};
final uri = await _getUri(newRatePath, params);
final response = await get(uri, headers: {'API-Key': apiKey});
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
if (responseJSON['error'] != null) throw Exception(responseJSON['error']);
final response = await ProxyWrapper().get(clearnetUri: uri, headers: {'API-Key': apiKey});
final responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final fromAmount = double.parse(responseJSON['amount_from'].toString());
final toAmount = double.parse(responseJSON['amount_to'].toString());
final rateId = responseJSON['trade_id'] as String? ?? '';
@ -206,10 +206,11 @@ 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});
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 400) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['error'] as String;
final message = responseJSON['message'] as String;
throw Exception('${error}\n$message');
@ -218,7 +219,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
if (response.statusCode != 200)
throw Exception('Unexpected http status: ${response.statusCode}');
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final id = responseJSON['trade_id'] as String;
final inputAddress = responseJSON['address_provider'] as String;
final refundAddress = responseJSON['refund_address'] as String;
@ -255,11 +256,12 @@ 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 responseString = await response.transform(utf8.decoder).join();
final responseListJson = json.decode(response.body) as List;
final responseListJson = json.decode(responseString) as List;
final responseJSON = responseListJson.first;
final id = responseJSON['trade_id'] as String;
final payoutAddress = responseJSON['address_user'] as String;
@ -355,7 +357,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
if (useTorOnly) return uri;
try {
await get(uri);
await ProxyWrapper().get(clearnetUri: uri);
return uri;
} catch (e) {

View file

@ -1,4 +1,5 @@
import 'dart:convert';
import 'package:cake_wallet/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';
@ -20,11 +21,12 @@ class MastodonAPI {
queryParameters: queryParams,
);
final response = await http.get(uri);
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) return null;
final Map<String, dynamic> responseJSON = json.decode(response.body) as Map<String, dynamic>;
final Map<String, dynamic> responseJSON = json.decode(responseString) as Map<String, dynamic>;
return MastodonUser.fromJson(responseJSON);
} catch (e) {
@ -47,13 +49,14 @@ class MastodonAPI {
queryParameters: queryParams,
);
final response = await http.get(uri);
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception('Unexpected HTTP status: ${response.statusCode}');
}
final List<dynamic> responseJSON = json.decode(response.body) as List<dynamic>;
final List<dynamic> responseJSON = json.decode(responseString) as List<dynamic>;
return responseJSON.map((json) => PinnedPost.fromJson(json as Map<String, dynamic>)).toList();
} catch (e) {

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/twitter/twitter_user.dart';
import 'package:cake_wallet/utils/proxy_wrapper.dart';
import 'package:http/http.dart' as http;
class TwitterApi {
@ -23,15 +24,16 @@ 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 responseString = await response.transform(utf8.decoder).join();
final Map<String, dynamic> responseJSON = jsonDecode(response.body) as Map<String, dynamic>;
final Map<String, dynamic> responseJSON = jsonDecode(responseString) as Map<String, dynamic>;
if (responseJSON['errors'] != null &&
!responseJSON['errors'][0]['detail']
.toString()

View file

@ -1,51 +1,34 @@
import 'dart:io';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/settings/tor_connection.dart';
import 'package:cake_wallet/view_model/settings/tor_view_model.dart';
import 'package:socks5_proxy/socks.dart';
import 'package:tor/tor.dart';
class ProxyWrapper {
ProxyWrapper({
this.settingsStore,
this.torViewModel,
});
SettingsStore? settingsStore;
TorViewModel? torViewModel;
HttpClient? _torClient;
int getPort() {
TorConnectionMode mode = settingsStore?.torConnectionMode ?? TorConnectionMode.disabled;
if (mode == TorConnectionMode.disabled) {
return -1;
}
return torViewModel?.torInstance.port ?? -1;
}
int getPort() => Tor.instance.port;
bool started = false;
Future<HttpClient> getProxyHttpClient({int? portOverride}) async {
if (portOverride == -1 || portOverride == null) {
portOverride = torViewModel?.torInstance.port ?? -1;
}
if (!started) {
started = true;
_torClient = HttpClient();
HttpClient getProxyHttpClient({int? portOverride}) {
final torClient = HttpClient();
if (Tor.instance.started) {
// Assign connection factory.
SocksTCPClient.assignToHttpClient(_torClient!, [
SocksTCPClient.assignToHttpClient(torClient, [
ProxySettings(
InternetAddress.loopbackIPv4,
portOverride,
portOverride ?? getPort(),
password: null,
),
]);
}
return _torClient!;
return torClient;
}
Future<HttpClientResponse> makeGet({
@ -79,31 +62,18 @@ class ProxyWrapper {
Future<HttpClientResponse> get({
Map<String, String>? headers,
int? portOverride,
TorConnectionMode? torConnectionMode,
TorConnectionStatus? torConnectionStatus,
Uri? clearnetUri,
Uri? onionUri,
}) async {
HttpClient? torClient;
late bool torEnabled;
torConnectionMode ??= settingsStore?.torConnectionMode ?? TorConnectionMode.disabled;
torConnectionStatus ??= torViewModel?.torConnectionStatus ?? TorConnectionStatus.disconnected;
bool torEnabled = Tor.instance.started;
if (torConnectionMode == TorConnectionMode.torOnly ||
torConnectionMode == TorConnectionMode.enabled) {
if (Tor.instance.started) {
torEnabled = true;
} else {
torEnabled = false;
}
if (torEnabled) {
torConnectionMode = TorConnectionMode.torOnly;
}
if (torEnabled && torConnectionStatus == TorConnectionStatus.connecting) {
throw Exception("Tor is still connecting");
}
// if tor is enabled, try to connect to the onion url first:
if (torEnabled) {
try {
@ -131,7 +101,7 @@ class ProxyWrapper {
}
}
if (clearnetUri != null && torConnectionMode != TorConnectionMode.torOnly) {
if (clearnetUri != null) {
try {
return HttpOverrides.runZoned(
() async {
@ -155,32 +125,11 @@ class ProxyWrapper {
Future<HttpClientResponse> post({
Map<String, String>? headers,
int? portOverride,
TorConnectionMode? torConnectionMode,
TorConnectionStatus? torConnectionStatus,
Uri? clearnetUri,
Uri? onionUri,
}) async {
HttpClient? torClient;
late bool torEnabled;
torConnectionMode ??= settingsStore?.torConnectionMode ?? TorConnectionMode.disabled;
torConnectionStatus ??= torViewModel?.torConnectionStatus ?? TorConnectionStatus.disconnected;
if (torConnectionMode == TorConnectionMode.torOnly ||
torConnectionMode == TorConnectionMode.enabled) {
torEnabled = true;
} else {
torEnabled = false;
}
if (torEnabled) {
torConnectionMode = TorConnectionMode.torOnly;
}
if (torEnabled && torConnectionStatus == TorConnectionStatus.connecting) {
throw Exception("Tor is still connecting");
}
// if tor is enabled, try to connect to the onion url first:
bool torEnabled = Tor.instance.started;
if (torEnabled) {
try {
@ -208,7 +157,7 @@ class ProxyWrapper {
}
}
if (clearnetUri != null && torConnectionMode != TorConnectionMode.torOnly) {
if (clearnetUri != null) {
try {
return HttpOverrides.runZoned(
() async {

View file

@ -13,6 +13,7 @@ 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/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';
@ -1106,21 +1107,21 @@ abstract class DashboardViewModelBase with Store {
{'key': secrets.fiatApiKey},
);
final res = await http.get(uri);
final res = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await res.transform(utf8.decoder).join();
if (res.statusCode < 200 || res.statusCode >= 300) {
throw res.body;
throw responseString;
}
final oldSha = sharedPreferences.getString(PreferencesKey.serviceStatusShaKey);
final hash = await Cryptography.instance.sha256().hash(utf8.encode(res.body));
final hash = await Cryptography.instance.sha256().hash(utf8.encode(responseString));
final currentSha = bytesToHex(hash.bytes);
final hasUpdates = oldSha != currentSha;
return ServicesResponse.fromJson(
json.decode(res.body) as Map<String, dynamic>,
json.decode(responseString) as Map<String, dynamic>,
hasUpdates,
currentSha,
);

View file

@ -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:cake_wallet/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';
@ -240,15 +241,15 @@ 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 responseString = await response.transform(utf8.decoder).join();
final decodedResponse = jsonDecode(responseString);
final tokenInfo = Erc20TokenInfoMoralis.fromJson(decodedResponse[0] as Map<String, dynamic>);
@ -309,12 +310,12 @@ abstract class HomeSettingsViewModelBase with Store {
);
try {
final response = await http.get(uri);
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
final decodedResponse = jsonDecode(responseString) as Map<String, dynamic>;
if (decodedResponse['status'] != '1') {
log('${response.body}\n');
log('${responseString}\n');
log('${decodedResponse['result']}\n');
return true;
}
@ -351,12 +352,13 @@ abstract class HomeSettingsViewModelBase with Store {
);
try {
final response = await http.get(uri);
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseString = await response.transform(utf8.decoder).join();
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
final decodedResponse = jsonDecode(responseString) as Map<String, dynamic>;
if (decodedResponse['status'] == '0') {
printV('${response.body}\n');
printV('${responseString}\n');
printV('${decodedResponse['result']}\n');
return true;
}

View file

@ -7,6 +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:cake_wallet/utils/proxy_wrapper.dart';
import 'package:http/http.dart' as http;
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
@ -80,15 +81,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 responseString = await response.transform(utf8.decoder).join();
final decodedResponse = jsonDecode(response.body);
final decodedResponse = jsonDecode(responseString) as Map<String, dynamic>;
if (walletType == WalletType.solana) {
final results = await Future.wait(
@ -131,15 +133,16 @@ 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>;
final responseString = await response.transform(utf8.decoder).join();
final decodedResponse = jsonDecode(responseString) as Map<String, dynamic>;
return SolanaNFTAssetModel.fromJson(decodedResponse);
}
@ -171,16 +174,15 @@ 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 responseString = await response.transform(utf8.decoder).join();
final decodedResponse = jsonDecode(responseString) as Map<String, dynamic>;
final nftAsset = NFTAssetModel.fromJson(decodedResponse);

View file

@ -9,6 +9,7 @@ import 'package:cake_wallet/exchange/provider/letsexchange_exchange_provider.dar
import 'package:cake_wallet/exchange/provider/stealth_ex_exchange_provider.dart';
import 'package:cake_wallet/view_model/send/fees_view_model.dart';
import 'package:cake_wallet/exchange/provider/xoswap_exchange_provider.dart';
import 'package:cake_wallet/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/sync_status.dart';
import 'package:cw_core/transaction_priority.dart';
@ -951,15 +952,16 @@ 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 responseString = await response.transform(utf8.decoder).join();
final decodedResponse = jsonDecode(response.body)[0] as Map<String, dynamic>;
final decodedResponse = jsonDecode(responseString)[0] as Map<String, dynamic>;
final name = decodedResponse['name'] as String?;

View file

@ -100,10 +100,7 @@ dependencies:
# git:
# url: https://github.com/cake-tech/tor.git
# ref: main
socks5_proxy:
git:
url: https://github.com/cake-tech/socks_dart.git
ref: d304fcfcc97cb7212bcd347aeb5d96792c128ff3
socks5_proxy: any
flutter_svg: ^2.0.9
polyseed: ^0.0.7
nostr_tools:
@ -184,6 +181,10 @@ dependency_overrides:
git:
url: https://github.com/vespr-wallet/ledger-flutter-plus
ref: c2e341d8038f1108690ad6f80f7b4b7156aacc76
socks5_proxy:
git:
url: https://github.com/cake-tech/socks_dart.git
ref: d304fcfcc97cb7212bcd347aeb5d96792c128ff3
flutter_icons:
image_path: "assets/images/app_logo.png"