migrate all remaining calls to use ProxyWrapper

add a CI action to enforce using ProxyWrapper instead of http/http.dart to prevent leaks
This commit is contained in:
Czarek Nakamoto 2025-04-03 11:35:15 +02:00
parent 4d723a1b5a
commit cc32f23909
57 changed files with 643 additions and 391 deletions

21
.github/workflows/no_http_imports.yaml vendored Normal file
View file

@ -0,0 +1,21 @@
name: No http imports
on: [pull_request]
jobs:
PR_test_build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Check for http package usage
if: github.event_name == 'pull_request'
run: |
GIT_GREP_OUT="$(git grep package:http | (grep .dart: || test $? = 1) || true)"
[[ "x$GIT_GREP_OUT" == "x" ]] && exit 0
echo "$GIT_GREP_OUT"
echo "There are .dart files which use http imports"
echo "Using http package breaks proxy integration"
echo "Please use ProxyWrapper.getHttpClient() from package:cw_core/utils/proxy_wrapper.dart"
exit 1

View file

@ -15,5 +15,5 @@ jobs:
[[ "x$GIT_GREP_OUT" == "x" ]] && exit 0
echo "$GIT_GREP_OUT"
echo "There are .dart files which use print() statements"
echo "Please use printV from package: cw_core/utils/print_verbose.dart"
echo "Please use printV from package:cw_core/utils/print_verbose.dart"
exit 1

View file

@ -6,7 +6,6 @@ import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:rxdart/rxdart.dart';
enum ConnectionStatus { connected, disconnected, connecting, failed }

View file

@ -4,6 +4,7 @@ import 'dart:io';
import 'dart:isolate';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
import 'package:cw_core/format_amount.dart';
import 'package:cw_core/utils/http_client.dart';
@ -50,7 +51,6 @@ import 'package:mobx/mobx.dart';
import 'package:rxdart/subjects.dart';
import 'package:sp_scanner/sp_scanner.dart';
import 'package:hex/hex.dart';
import 'package:http/http.dart' as http;
part 'electrum_wallet.g.dart';
@ -513,7 +513,8 @@ abstract class ElectrumWalletBase extends WalletBase<
Future<void> updateFeeRates() async {
if (await checkIfMempoolAPIIsEnabled() && type == WalletType.bitcoin) {
try {
final req = await getHttpClient()
final req = await ProxyWrapper()
.getHttpClient()
.getUrl(Uri.parse(
"https://mempool.cakewallet.com/api/v1/fees/recommended"))
.timeout(Duration(seconds: 15));
@ -1961,7 +1962,8 @@ abstract class ElectrumWalletBase extends WalletBase<
if (height != null && height > 0 && await checkIfMempoolAPIIsEnabled()) {
try {
final req = await getHttpClient()
final req = await ProxyWrapper()
.getHttpClient()
.getUrl(Uri.parse(
"https://mempool.cakewallet.com/api/v1/block-height/$height"))
.timeout(Duration(seconds: 15));
@ -1971,10 +1973,12 @@ abstract class ElectrumWalletBase extends WalletBase<
if (blockHash.statusCode == 200 &&
stringData.isNotEmpty &&
jsonDecode(stringData) != null) {
final blockResponseReq = await getHttpClient()
final blockResponseReq = await ProxyWrapper()
.getHttpClient()
.getUrl(Uri.parse(
"https://mempool.cakewallet.com/api/v1/block/${stringData}"))
.timeout(Duration(seconds: 15));
final blockResponseRes = await blockResponseReq.close();
final blockResponse =
await blockResponseRes.transform(utf8.decoder).join();

View file

@ -1,8 +1,7 @@
import 'package:cw_core/utils/http_client.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:intl/intl.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
// FIXME: Hardcoded values; Works only for monero
@ -235,7 +234,7 @@ int getHavenHeightByDate({required DateTime date}) {
}
Future<int> getHavenCurrentHeight() async {
final req = await getHttpClient()
final req = await ProxyWrapper().getHttpClient()
.getUrl(Uri.parse('https://explorer.havenprotocol.org/api/networkinfo'))
.timeout(Duration(seconds: 15));
final response = await req.close();
@ -274,7 +273,7 @@ const bitcoinDates = {
};
Future<int> getBitcoinHeightByDateAPI({required DateTime date}) async {
final req = await getHttpClient()
final req = await ProxyWrapper().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();

View file

@ -1,18 +1,15 @@
import 'dart:io';
import 'package:cw_core/keyable.dart';
import 'package:cw_core/utils/http_client.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:hive/hive.dart';
import 'package:cw_core/hive_type_ids.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:http/io_client.dart' as ioc;
import 'dart:math' as math;
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:tor/tor.dart' as tor;
part 'node.g.dart';
@ -186,24 +183,22 @@ class Node extends HiveObject with Keyable {
final body = {'jsonrpc': '2.0', 'id': '0', 'method': "getinfo"};
try {
final authenticatingClient = HttpClient();
final authenticatingClient = ProxyWrapper().getHttpClient();
authenticatingClient.badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
final http.Client client = ioc.IOClient(authenticatingClient);
final jsonBody = json.encode(body);
final response = await client.post(
rpcUri,
final response = await ProxyWrapper().post(
clearnetUri: rpcUri,
headers: {'Content-Type': 'application/json'},
body: jsonBody,
);
printV("node check response: ${response.body}");
final responseString = await response.transform(utf8.decoder).join();
final resBody = json.decode(responseString) as Map<String, dynamic>;
final resBody = json.decode(response.body) as Map<String, dynamic>;
return resBody['result']['height'] != null;
} catch (e) {
printV("error: $e");
@ -221,16 +216,14 @@ class Node extends HiveObject with Keyable {
final body = {'jsonrpc': '2.0', 'id': '0', 'method': methodName};
try {
final authenticatingClient = HttpClient();
final authenticatingClient = ProxyWrapper().getHttpClient();
authenticatingClient.badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
final http.Client client = ioc.IOClient(authenticatingClient);
final jsonBody = json.encode(body);
final response = await client.post(
rpcUri,
final response = await ProxyWrapper().post(
clearnetUri: rpcUri,
headers: {'Content-Type': 'application/json'},
body: jsonBody,
);
@ -245,15 +238,15 @@ class Node extends HiveObject with Keyable {
return !(response['offline'] as bool);
}
printV("node check response: ${response.body}");
final responseString = await response.transform(utf8.decoder).join();
if ((response.body.contains("400 Bad Request") // Some other generic error
if ((responseString.contains("400 Bad Request") // Some other generic error
||
response.body.contains("plain HTTP request was sent to HTTPS port") // Cloudflare
responseString.contains("plain HTTP request was sent to HTTPS port") // Cloudflare
||
response.headers["location"] != null // Generic reverse proxy
||
response.body
responseString
.contains("301 Moved Permanently") // Poorly configured generic reverse proxy
) &&
!(useSSL ?? false)) {
@ -271,7 +264,7 @@ class Node extends HiveObject with Keyable {
}
}
final resBody = json.decode(response.body) as Map<String, dynamic>;
final resBody = json.decode(responseString) as Map<String, dynamic>;
return !(resBody['result']['offline'] as bool);
} catch (e) {
printV("error: $e");
@ -326,8 +319,8 @@ class Node extends HiveObject with Keyable {
Future<bool> requestNanoNode() async {
try {
final response = await http.post(
uri,
final response = await ProxyWrapper().post(
clearnetUri: uri,
headers: {"Content-Type": "application/json", "nano-app": "cake-wallet"},
body: jsonEncode(
{
@ -336,7 +329,8 @@ class Node extends HiveObject with Keyable {
},
),
);
final data = await jsonDecode(response.body);
final responseString = await response.transform(utf8.decoder).join();
final data = jsonDecode(responseString);
if (response.statusCode != 200 ||
data["error"] != null ||
data["balance"] == null ||
@ -352,7 +346,7 @@ class Node extends HiveObject with Keyable {
Future<bool> requestEthereumServer() async {
try {
final req = await getHttpClient()
final req = await ProxyWrapper().getHttpClient()
.getUrl(uri,)
.timeout(Duration(seconds: 15));
final response = await req.close();
@ -467,12 +461,11 @@ class DaemonRpc {
/// Perform a JSON-RPC call with Digest Authentication.
Future<Map<String, dynamic>> call(String method, Map<String, dynamic> params) async {
final http.Client client = http.Client();
final DigestAuth digestAuth = DigestAuth(username, password);
// Initial request to get the `WWW-Authenticate` header.
final initialResponse = await client.post(
Uri.parse(rpcUrl),
final initialResponse = await ProxyWrapper().post(
clearnetUri: Uri.parse(rpcUrl),
headers: {
'Content-Type': 'application/json',
},
@ -484,25 +477,26 @@ class DaemonRpc {
}),
);
if (initialResponse.statusCode != 401 ||
!initialResponse.headers.containsKey('www-authenticate')) {
throw Exception('Unexpected response: ${initialResponse.body}');
final authHeader = initialResponse.headers.value('www-authenticate');
final responseString = await initialResponse.transform(utf8.decoder).join();
if (initialResponse.statusCode != 401 || authHeader == null) {
throw Exception('Unexpected response: $responseString');
}
// Extract Digest details from `WWW-Authenticate` header.
final String authInfo = initialResponse.headers['www-authenticate']!;
digestAuth.initFromAuthorizationHeader(authInfo);
digestAuth.initFromAuthorizationHeader(authHeader);
// Create Authorization header for the second request.
String uri = Uri.parse(rpcUrl).path;
String authHeader = digestAuth.getAuthString('POST', uri);
String newAuthHeader = digestAuth.getAuthString('POST', uri);
// Make the authenticated request.
final authenticatedResponse = await client.post(
Uri.parse(rpcUrl),
final authenticatedResponse = await ProxyWrapper().post(
clearnetUri: Uri.parse(rpcUrl),
headers: {
'Content-Type': 'application/json',
'Authorization': authHeader,
'Authorization': newAuthHeader,
},
body: jsonEncode({
'jsonrpc': '2.0',
@ -513,11 +507,12 @@ class DaemonRpc {
);
if (authenticatedResponse.statusCode != 200) {
throw Exception('RPC call failed: ${authenticatedResponse.body}');
final responseString = await authenticatedResponse.transform(utf8.decoder).join();
throw Exception('RPC call failed: $responseString');
}
final Map<String, dynamic> result =
jsonDecode(authenticatedResponse.body) as Map<String, dynamic>;
final responseString2 = await authenticatedResponse.transform(utf8.decoder).join();
final result = jsonDecode(responseString2) as Map<String, dynamic>;
if (result['error'] != null) {
throw Exception('RPC Error: ${result['error']}');
}

View file

@ -1,18 +1,20 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:on_chain/solana/solana.dart';
class SolanaRPCHTTPService implements SolanaJSONRPCService {
SolanaRPCHTTPService(
{required this.url, Client? client, this.defaultRequestTimeout = const Duration(seconds: 30)})
: client = client ?? Client();
{required this.url,
this.defaultRequestTimeout = const Duration(seconds: 30)});
@override
final String url;
final Client client;
final Duration defaultRequestTimeout;
final client = ProxyWrapper().getHttpIOClient();
@override
Future<Map<String, dynamic>> call(SolanaRequestDetails params, [Duration? timeout]) async {
Future<Map<String, dynamic>> call(SolanaRequestDetails params,
[Duration? timeout]) async {
final response = await client.post(
Uri.parse(url),
body: params.toRequestBody(),
@ -23,4 +25,18 @@ class SolanaRPCHTTPService implements SolanaJSONRPCService {
final data = json.decode(response.body) as Map<String, dynamic>;
return data;
}
Future<Map<String, dynamic>> call(SolanaRequestDetails params,
[Duration? timeout]) async {
final response = await ProxyWrapper().post(
clearnetUri: Uri.parse(url),
body: json.encode(params.toJson()),
headers: {
'Content-Type': 'application/json',
},
).timeout(timeout ?? defaultRequestTimeout);
final responseString = await response.transform(utf8.decoder).join();
final data = json.decode(responseString) as Map<String, dynamic>;
return data;
}
}

View file

@ -1,24 +0,0 @@
import 'dart:io';
import 'package:http/http.dart';
import 'package:socks5_proxy/socks_client.dart';
import 'package:tor/tor.dart';
HttpClient getHttpClient() {
final client = HttpClient();
if (CakeTor.instance.enabled) {
SocksTCPClient.assignToHttpClient(client, [
ProxySettings(InternetAddress.loopbackIPv4,
CakeTor.instance.port,
password: null,
),
]);
}
return client;
}
class CakeTor {
static final Tor instance = Tor.instance;
}

View file

@ -1,17 +1,33 @@
import 'dart:io';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cw_core/utils/http_client.dart';
import 'package:socks5_proxy/socks.dart';
import 'package:socks5_proxy/socks_client.dart';
import 'package:tor/tor.dart';
import 'package:http/io_client.dart' as ioc;
class ProxyWrapper {
ProxyWrapper({
this.settingsStore,
});
ProxyWrapper();
SettingsStore? settingsStore;
ioc.IOClient getHttpIOClient() {
final httpClient = ProxyWrapper().getHttpClient();
return ioc.IOClient(httpClient);
}
@Deprecated('Use ProxyWrapper().get/post/put methods instead, and provide proper clearnet and onion uri.')
HttpClient getHttpClient() {
final client = HttpClient();
if (CakeTor.instance.enabled) {
SocksTCPClient.assignToHttpClient(client, [
ProxySettings(InternetAddress.loopbackIPv4,
CakeTor.instance.port,
password: null,
),
]);
}
return client;
}
int getPort() => CakeTor.instance.port;
@ -50,6 +66,7 @@ class ProxyWrapper {
required HttpClient client,
required Uri uri,
required Map<String, String>? headers,
String? body,
}) async {
final request = await client.postUrl(uri);
if (headers != null) {
@ -57,6 +74,29 @@ class ProxyWrapper {
request.headers.add(key, value);
});
}
if (body != null) {
request.write(body);
}
await request.flush();
return await request.close();
}
Future<HttpClientResponse> makePut({
required HttpClient client,
required Uri uri,
required Map<String, String>? headers,
String? body,
}) async {
final request = await client.putUrl(uri);
if (headers != null) {
headers.forEach((key, value) {
request.headers.add(key, value);
});
}
if (body != null) {
request.write(body);
}
await request.flush();
return await request.close();
}
@ -122,12 +162,14 @@ class ProxyWrapper {
throw Exception("Unable to connect to server");
}
Future<HttpClientResponse> post({
Map<String, String>? headers,
int? portOverride,
Uri? clearnetUri,
Uri? onionUri,
String? body,
}) async {
HttpClient? torClient;
bool torEnabled = CakeTor.instance.started;
@ -143,6 +185,7 @@ class ProxyWrapper {
client: torClient!,
uri: onionUri,
headers: headers,
body: body,
);
} catch (_) {}
}
@ -153,6 +196,7 @@ class ProxyWrapper {
client: torClient!,
uri: clearnetUri,
headers: headers,
body: body,
);
} catch (_) {}
}
@ -166,6 +210,67 @@ class ProxyWrapper {
client: HttpClient(),
uri: clearnetUri,
headers: headers,
body: body,
);
},
createHttpClient: NullOverrides().createHttpClient,
);
} catch (_) {
// we weren't able to get a response:
rethrow;
}
}
throw Exception("Unable to connect to server");
}
Future<HttpClientResponse> put({
Map<String, String>? headers,
int? portOverride,
Uri? clearnetUri,
Uri? onionUri,
String? body,
}) async {
HttpClient? torClient;
bool torEnabled = CakeTor.instance.started;
if (torEnabled) {
try {
torClient = await getProxyHttpClient(portOverride: portOverride);
} catch (_) {}
if (onionUri != null) {
try {
return await makePut(
client: torClient!,
uri: onionUri,
headers: headers,
body: body,
);
} catch (_) {}
}
if (clearnetUri != null) {
try {
return await makePut(
client: torClient!,
uri: clearnetUri,
headers: headers,
body: body,
);
} catch (_) {}
}
}
if (clearnetUri != null) {
try {
return HttpOverrides.runZoned(
() async {
return await makePut(
client: HttpClient(),
uri: clearnetUri,
headers: headers,
body: body,
);
},
createHttpClient: NullOverrides().createHttpClient,
@ -179,3 +284,8 @@ class ProxyWrapper {
throw Exception("Unable to connect to server");
}
}
class CakeTor {
static final Tor instance = Tor.instance;
}

View file

@ -635,11 +635,12 @@ packages:
socks5_proxy:
dependency: "direct main"
description:
name: socks5_proxy
sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053"
url: "https://pub.dev"
source: hosted
version: "1.0.6"
path: "."
ref: d304fcfcc97cb7212bcd347aeb5d96792c128ff3
resolved-ref: d304fcfcc97cb7212bcd347aeb5d96792c128ff3
url: "https://github.com/cake-tech/socks_dart.git"
source: git
version: "1.0.4"
source_gen:
dependency: transitive
description:

View file

@ -25,7 +25,10 @@ dependencies:
url: https://github.com/cake-tech/cake_backup.git
ref: main
version: 1.0.0
socks5_proxy: ^1.0.4
socks5_proxy:
git:
url: https://github.com/cake-tech/socks_dart.git
ref: d304fcfcc97cb7212bcd347aeb5d96792c128ff3
unorm_dart: ^0.3.0
on_chain:
git:

View file

@ -5,7 +5,7 @@ import 'dart:developer';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/utils/http_client.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_evm/evm_chain_transaction_model.dart';
import 'package:cw_evm/evm_chain_transaction_priority.dart';
import 'package:cw_evm/evm_erc20_balance.dart';
@ -13,15 +13,12 @@ import 'package:cw_evm/pending_evm_chain_transaction.dart';
import 'package:cw_evm/.secrets.g.dart' as secrets;
import 'package:flutter/foundation.dart';
import 'package:hex/hex.dart' as hex;
import 'package:http/http.dart' as http;
import 'package:web3dart/web3dart.dart';
import 'package:http/io_client.dart' as ioc;
import 'contract/erc20.dart';
abstract class EVMChainClient {
final httpClient = getHttpClient();
late final http.Client client = ioc.IOClient(httpClient);
late final client = ProxyWrapper().getHttpIOClient();
Web3Client? _client;
//! To be overridden by all child classes

View file

@ -17,7 +17,7 @@ import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/sync_status.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/utils/http_client.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_info.dart';

View file

@ -3,11 +3,11 @@ import 'dart:convert';
import 'package:cw_core/nano_account_info_response.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_nano/nano_block_info_response.dart';
import 'package:cw_core/n2_node.dart';
import 'package:cw_nano/nano_balance.dart';
import 'package:cw_nano/nano_transaction_model.dart';
import 'package:http/http.dart' as http;
import 'package:cw_core/node.dart';
import 'package:nanoutil/nanoutil.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -66,8 +66,8 @@ class NanoClient {
}
Future<NanoBalance> getBalance(String address) async {
final response = await http.post(
_node!.uri,
final response = await ProxyWrapper().post(
clearnetUri: _node!.uri,
headers: getHeaders(_node!.uri.host),
body: jsonEncode(
{
@ -76,7 +76,8 @@ class NanoClient {
},
),
);
final data = await jsonDecode(response.body);
final responseString = await response.transform(utf8.decoder).join();
final data = jsonDecode(responseString) as Map<String, dynamic>;
if (response.statusCode != 200 ||
data["error"] != null ||
data["balance"] == null ||
@ -93,8 +94,8 @@ class NanoClient {
Future<AccountInfoResponse?> getAccountInfo(String address) async {
try {
final response = await http.post(
_node!.uri,
final response = await ProxyWrapper().post(
clearnetUri: _node!.uri,
headers: getHeaders(_node!.uri.host),
body: jsonEncode(
{
@ -104,8 +105,9 @@ class NanoClient {
},
),
);
final data = await jsonDecode(response.body);
return AccountInfoResponse.fromJson(data as Map<String, dynamic>);
final responseString = await response.transform(utf8.decoder).join();
final data = jsonDecode(responseString) as Map<String, dynamic>;
return AccountInfoResponse.fromJson(data);
} catch (e) {
printV("error while getting account info $e");
return null;
@ -114,8 +116,8 @@ class NanoClient {
Future<BlockContentsResponse?> getBlockContents(String block) async {
try {
final response = await http.post(
_node!.uri,
final response = await ProxyWrapper().post(
clearnetUri: _node!.uri,
headers: getHeaders(_node!.uri.host),
body: jsonEncode(
{
@ -125,7 +127,8 @@ class NanoClient {
},
),
);
final data = await jsonDecode(response.body);
final responseString = await response.transform(utf8.decoder).join();
final data = jsonDecode(responseString) as Map<String, dynamic>;
return BlockContentsResponse.fromJson(data["contents"] as Map<String, dynamic>);
} catch (e) {
printV("error while getting block info $e");
@ -181,8 +184,8 @@ class NanoClient {
}
Future<String> requestWork(String hash) async {
final response = await http.post(
_powNode!.uri,
final response = await ProxyWrapper().post(
clearnetUri: _powNode!.uri,
headers: getHeaders(_powNode!.uri.host),
body: json.encode(
{
@ -191,14 +194,15 @@ class NanoClient {
},
),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
final Map<String, dynamic> decoded = json.decode(response.body) as Map<String, dynamic>;
final decoded = jsonDecode(responseString) as Map<String, dynamic>;
if (decoded.containsKey("error")) {
throw Exception("Received error ${decoded["error"]}");
}
return decoded["work"] as String;
} else {
throw Exception("Received work error ${response.body}");
throw Exception("Received work error ${responseString}");
}
}
@ -224,13 +228,14 @@ class NanoClient {
"block": block,
});
final processResponse = await http.post(
_node!.uri,
final processResponse = await ProxyWrapper().post(
clearnetUri: _node!.uri,
headers: getHeaders(_node!.uri.host),
body: processBody,
);
final Map<String, dynamic> decoded = json.decode(processResponse.body) as Map<String, dynamic>;
final responseString = await processResponse.transform(utf8.decoder).join();
final Map<String, dynamic> decoded = jsonDecode(responseString) as Map<String, dynamic>;
if (decoded.containsKey("error")) {
throw Exception("Received error ${decoded["error"]}");
}
@ -423,13 +428,13 @@ class NanoClient {
"subtype": "receive",
"block": receiveBlock,
});
final processResponse = await http.post(
_node!.uri,
final processResponse = await ProxyWrapper().post(
clearnetUri: _node!.uri,
headers: getHeaders(_node!.uri.host),
body: processBody,
);
final Map<String, dynamic> decoded = json.decode(processResponse.body) as Map<String, dynamic>;
final responseString = await processResponse.transform(utf8.decoder).join();
final Map<String, dynamic> decoded = json.decode(responseString) as Map<String, dynamic>;
if (decoded.containsKey("error")) {
throw Exception("Received error ${decoded["error"]}");
}
@ -440,16 +445,18 @@ class NanoClient {
required String destinationAddress,
required String privateKey,
}) async {
final receivableResponse = await http.post(_node!.uri,
headers: getHeaders(_node!.uri.host),
body: jsonEncode({
"action": "receivable",
"account": destinationAddress,
"count": "-1",
"source": true,
}));
final receivableData = await jsonDecode(receivableResponse.body);
final receivableResponse = await ProxyWrapper().post(
clearnetUri: _node!.uri,
headers: getHeaders(_node!.uri.host),
body: jsonEncode({
"action": "receivable",
"account": destinationAddress,
"count": "-1",
"source": true,
}),
);
final responseString = await receivableResponse.transform(utf8.decoder).join();
final receivableData = jsonDecode(responseString) as Map<String, dynamic>;
if (receivableData["blocks"] == "" || receivableData["blocks"] == null) {
return 0;
}
@ -492,15 +499,18 @@ class NanoClient {
Future<List<NanoTransactionModel>> fetchTransactions(String address) async {
try {
final response = await http.post(_node!.uri,
headers: getHeaders(_node!.uri.host),
body: jsonEncode({
"action": "account_history",
"account": address,
"count": "100",
// "raw": true,
}));
final data = await jsonDecode(response.body);
final response = await ProxyWrapper().post(
clearnetUri: _node!.uri,
headers: getHeaders(_node!.uri.host),
body: jsonEncode({
"action": "account_history",
"account": address,
"count": "100",
// "raw": true,
}),
);
final responseString = await response.transform(utf8.decoder).join();
final data = jsonDecode(responseString) as Map<String, dynamic>;
final transactions = data["history"] is List ? data["history"] as List<dynamic> : [];
// Map the transactions list to NanoTransactionModel using the factory
@ -516,13 +526,14 @@ class NanoClient {
Future<List<N2Node>> getN2Reps() async {
final uri = Uri.parse(N2_REPS_ENDPOINT);
final response = await http.post(
uri,
final response = await ProxyWrapper().post(
clearnetUri: uri,
headers: getHeaders(uri.host),
body: jsonEncode({"action": "reps"}),
);
try {
final List<N2Node> nodes = (json.decode(response.body) as List<dynamic>)
final responseString = await response.transform(utf8.decoder).join();
final List<N2Node> nodes = (jsonDecode(responseString) as List<dynamic>)
.map((dynamic e) => N2Node.fromJson(e as Map<String, dynamic>))
.toList();
return nodes;
@ -533,8 +544,8 @@ class NanoClient {
Future<int> getRepScore(String rep) async {
final uri = Uri.parse(N2_REPS_ENDPOINT);
final response = await http.post(
uri,
final response = await ProxyWrapper().post(
clearnetUri: uri,
headers: getHeaders(uri.host),
body: jsonEncode({
"action": "rep_info",
@ -542,7 +553,8 @@ class NanoClient {
}),
);
try {
final N2Node node = N2Node.fromJson(json.decode(response.body) as Map<String, dynamic>);
final responseString = await response.transform(utf8.decoder).join();
final N2Node node = N2Node.fromJson(jsonDecode(responseString) as Map<String, dynamic>);
return node.score ?? 100;
} catch (error) {
return 100;

View file

@ -5,15 +5,14 @@ import 'dart:math' as math;
import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_core/solana_rpc_http_service.dart';
import 'package:cw_core/utils/http_client.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_solana/pending_solana_transaction.dart';
import 'package:cw_solana/solana_balance.dart';
import 'package:cw_solana/solana_exceptions.dart';
import 'package:cw_solana/solana_transaction_model.dart';
import 'package:cw_solana/spl_token.dart';
import 'package:http/http.dart' as http;
import 'package:on_chain/solana/solana.dart';
import 'package:on_chain/solana/src/instructions/associated_token_account/constant.dart';
import 'package:on_chain/solana/src/models/pda/pda.dart';
@ -21,12 +20,11 @@ import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:on_chain/solana/src/rpc/models/models/confirmed_transaction_meta.dart';
import '.secrets.g.dart' as secrets;
class SolanaWalletClient {
final httpClient = http.Client();
SolanaRPC? _provider;
// Minimum amount in SOL to consider a transaction valid (to filter spam)
static const double minValidAmount = 0.00000003;
final httpClient = ProxyWrapper().getHttpClient();
SolanaRPC? _provider;
bool connect(Node node) {
try {
@ -89,7 +87,8 @@ class SolanaWalletClient {
}
}
Future<SolanaBalance?> getSplTokenBalance(String mintAddress, String walletAddress) async {
Future<SolanaBalance?> getSplTokenBalance(
String mintAddress, String walletAddress) async {
// Fetch the token accounts (a token can have multiple accounts for various uses)
final tokenAccounts = await getSPLTokenAccounts(mintAddress, walletAddress);
@ -125,14 +124,16 @@ class SolanaWalletClient {
),
);
final fee = (feeForMessage?.toDouble() ?? 0.0) / SolanaUtils.lamportsPerSol;
final fee =
(feeForMessage?.toDouble() ?? 0.0) / SolanaUtils.lamportsPerSol;
return fee;
} catch (_) {
return 0.0;
}
}
Future<double> getEstimatedFee(SolanaPublicKey publicKey, Commitment commitment) async {
Future<double> getEstimatedFee(
SolanaPublicKey publicKey, Commitment commitment) async {
final message = await _getMessageForNativeTransaction(
publicKey: publicKey,
destinationAddress: publicKey.toAddress().address,
@ -432,17 +433,20 @@ class SolanaWalletClient {
}
}));
final versionedBatchResponses = batchResponses.whereType<VersionedTransactionResponse>();
final versionedBatchResponses =
batchResponses.whereType<VersionedTransactionResponse>();
final parsedTransactionsFutures = versionedBatchResponses.map((tx) => parseTransaction(
txResponse: tx,
splTokenSymbol: splTokenSymbol,
walletAddress: walletAddress?.address ?? address.address,
));
final parsedTransactionsFutures =
versionedBatchResponses.map((tx) => parseTransaction(
txResponse: tx,
splTokenSymbol: splTokenSymbol,
walletAddress: walletAddress?.address ?? address.address,
));
final parsedTransactions = await Future.wait(parsedTransactionsFutures);
transactions.addAll(parsedTransactions.whereType<SolanaTransactionModel>().toList());
transactions.addAll(
parsedTransactions.whereType<SolanaTransactionModel>().toList());
// Only update UI if we have new valid transactions
if (parsedTransactions.isNotEmpty) {
@ -511,8 +515,8 @@ class SolanaWalletClient {
}
Future<SPLToken?> fetchSPLTokenInfo(String mintAddress) async {
final programAddress =
MetaplexTokenMetaDataProgramUtils.findMetadataPda(mint: SolAddress(mintAddress));
final programAddress = MetaplexTokenMetaDataProgramUtils.findMetadataPda(
mint: SolAddress(mintAddress));
final token = await _provider!.request(
SolanaRPCGetMetadataAccount(
@ -533,8 +537,9 @@ class SolanaWalletClient {
// iconPath = await _client.getIconImageFromTokenUri(metadata.uri);
// } catch (_) {}
String filteredTokenSymbol =
metadata.symbol.replaceFirst(RegExp('^\\\$'), '').replaceAll('\u0000', '');
String filteredTokenSymbol = metadata.symbol
.replaceFirst(RegExp('^\\\$'), '')
.replaceAll('\u0000', '');
return SPLToken.fromMetadata(
name: metadata.name,
@ -650,7 +655,8 @@ class SolanaWalletClient {
return message;
}
Future<double> _getFeeFromCompiledMessage(Message message, Commitment commitment) async {
Future<double> _getFeeFromCompiledMessage(
Message message, Commitment commitment) async {
final base64Message = base64Encode(message.serialize());
final fee = await getFeeForMessage(base64Message, commitment);
@ -789,7 +795,8 @@ class SolanaWalletClient {
required SolAddress mintAddress,
required bool shouldCreateATA,
}) async {
final associatedTokenAccount = AssociatedTokenAccountProgramUtils.associatedTokenAccount(
final associatedTokenAccount =
AssociatedTokenAccountProgramUtils.associatedTokenAccount(
mint: mintAddress,
owner: ownerAddress,
);
@ -860,7 +867,8 @@ class SolanaWalletClient {
final amount = (inputAmount * math.pow(10, tokenDecimals)).toInt();
ProgramDerivedAddress? associatedSenderAccount;
try {
associatedSenderAccount = AssociatedTokenAccountProgramUtils.associatedTokenAccount(
associatedSenderAccount =
AssociatedTokenAccountProgramUtils.associatedTokenAccount(
mint: mintAddress,
owner: ownerPrivateKey.publicKey().toAddress(),
);
@ -995,8 +1003,7 @@ class SolanaWalletClient {
if (uri.isEmpty || uri == '') return null;
try {
final httpClient = getHttpClient();
final http.Client client = ioc.IOClient(httpClient);
final client = ProxyWrapper().getHttpIOClient();
final response = await client.get(Uri.parse(uri));
final jsonResponse = json.decode(response.body) as Map<String, dynamic>;

View file

@ -5,7 +5,7 @@ import 'dart:developer';
import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/utils/http_client.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_tron/pending_tron_transaction.dart';
import 'package:cw_tron/tron_abi.dart';
import 'package:cw_tron/tron_balance.dart';
@ -14,14 +14,11 @@ import 'package:cw_tron/tron_token.dart';
import 'package:cw_tron/tron_transaction_model.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart';
import '.secrets.g.dart' as secrets;
import 'package:on_chain/on_chain.dart';
import 'package:http/io_client.dart' as ioc;
class TronClient {
final httpClient = getHttpClient();
late final Client client = ioc.IOClient(httpClient);
late final client = ProxyWrapper().getHttpIOClient();
TronProvider? _provider;
// This is an internal tracker, so we don't have to "refetch".

View file

@ -1,8 +1,7 @@
import 'dart:convert';
import 'package:cw_core/utils/http_client.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart' as ioc;
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:on_chain/tron/tron.dart';
import '.secrets.g.dart' as secrets;
@ -13,8 +12,7 @@ class TronHTTPProvider implements TronServiceProvider {
@override
final String url;
final httpClient = getHttpClient();
late final http.Client client = ioc.IOClient(httpClient);
late final client = ProxyWrapper().getHttpIOClient();
final Duration defaultRequestTimeout;
@override

View file

@ -6,9 +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:cake_wallet/utils/proxy_wrapper.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;
@ -31,7 +30,10 @@ class AnonPayApi {
Future<AnonpayStatusResponse> paymentStatus(String id) async {
final authority = await _getAuthority();
final response = await ProxyWrapper().get(clearnetUri: Uri.https(authority, "$anonPayStatus/$id"));
final response = await ProxyWrapper().get(
clearnetUri: Uri.https(authority, "$anonPayStatus/$id"),
onionUri: Uri.https(onionApiAuthority, "$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;
@ -205,7 +207,7 @@ class AnonPayApi {
return onionApiAuthority;
}
final uri = Uri.https(onionApiAuthority, '/anonpay');
await ProxyWrapper().get(clearnetUri: uri);
await ProxyWrapper().get(clearnetUri: uri, onionUri: uri);
return onionApiAuthority;
} catch (e) {
return clearNetAuthority;

View file

@ -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,14 +53,18 @@ 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),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
await ExceptionHandler.onError(FlutterErrorDetails(exception: response));
throw Exception('Unexpected response http code: ${response.statusCode}');
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final decodedBody = json.decode(responseString) as Map<String, dynamic>;
return AnyPayPayment.fromMap(decodedBody);
}
@ -79,9 +83,14 @@ 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),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 400) {
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final decodedBody = json.decode(responseString) as Map<String, dynamic>;
throw Exception(decodedBody['message'] as String? ?? 'Unexpected response\nError code: 400');
}
@ -89,7 +98,7 @@ class AnyPayApi {
throw Exception('Unexpected response');
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final decodedBody = json.decode(responseString) as Map<String, dynamic>;
return AnyPayPaymentCommittedInfo(
uri: uri,
currency: currency,

View file

@ -10,7 +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: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 +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 {
@ -101,21 +100,22 @@ 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,
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 201) {
final responseBody = jsonDecode(response.body);
final responseBody = jsonDecode(responseString);
return responseBody['accessToken'] as String;
} else if (response.statusCode == 403) {
final responseBody = jsonDecode(response.body);
final responseBody = jsonDecode(responseString);
final message = responseBody['message'] ?? 'Service unavailable in your country';
throw Exception(message);
} else {
throw Exception('Failed to sign up. Status: ${response.statusCode} ${response.body}');
throw Exception('Failed to sign up. Status: ${response.statusCode} ${responseString}');
}
}
@ -274,8 +274,13 @@ class DFXBuyProvider extends BuyProvider {
});
try {
final response = await http.put(url, headers: headers, body: body);
final responseData = jsonDecode(response.body);
final response = await ProxyWrapper().put(
clearnetUri: url,
headers: headers,
body: body,
);
final responseString = await response.transform(utf8.decoder).join();
final responseData = jsonDecode(responseString);
if (response.statusCode == 200) {
if (responseData is Map<String, dynamic>) {

View file

@ -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,10 +74,15 @@ 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>;
final responseString = await response.transform(utf8.decoder).join();
return jsonDecode(responseString) as Map<String, dynamic>;
} else {
return {};
}

View file

@ -8,14 +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:cake_wallet/utils/proxy_wrapper.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 {
@ -132,10 +131,15 @@ 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,
);
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>;
final paymentType = _getPaymentTypeByString(data['paymentMethodType'] as String?);
final quote = Quote.fromMeldJson(data, isBuyAction, paymentType);

View file

@ -16,13 +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:cake_wallet/utils/proxy_wrapper.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 {
@ -99,15 +98,18 @@ 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}),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 200) {
return (jsonDecode(response.body) as Map<String, dynamic>)['signature'] as String;
return (jsonDecode(responseString) as Map<String, dynamic>)['signature'] as String;
} else {
throw Exception(
'Provider currently unavailable. Status: ${response.statusCode} ${response.body}');
'Provider currently unavailable. Status: ${response.statusCode} ${responseString}');
}
}
@ -121,7 +123,10 @@ class MoonPayProvider extends BuyProvider {
final url = Uri.https(_baseUrl, path, params);
try {
final response = await ProxyWrapper().get(clearnetUri: 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(responseString) as Map<String, dynamic>;

View file

@ -9,12 +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/utils/proxy_wrapper.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 {
@ -67,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>;

View file

@ -11,7 +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: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';
@ -19,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 {
@ -123,13 +122,15 @@ 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;
final responseString = await response.transform(utf8.decoder).join();
return (jsonDecode(responseString) as Map<String, dynamic>)['connectId'] as String;
} else {
throw Exception('Provider currently unavailable. Status: ${response.statusCode}');
}

View file

@ -3,8 +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: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';
@ -74,19 +73,22 @@ 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 responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final urlFromResponse = responseJSON['url'] as String;
return urlFromResponse;
}
@ -102,19 +104,22 @@ 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 responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final sourceAmount = responseJSON['sourceAmount'] as double;
final destAmount = responseJSON['destAmount'] as double;
final achAmount = responseJSON['sourceAmountWithoutFees'] as double;

View file

@ -3,10 +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:cake_wallet/utils/proxy_wrapper.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;
@ -33,13 +32,18 @@ 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>;
final responseString = await response.transform(utf8.decoder).join();
final bodyJson = json.decode(responseString) as Map<String, dynamic>;
if (bodyJson.containsKey('user') && bodyJson['user']['email'] != null) {
return bodyJson['user']['email'] as String;
@ -65,13 +69,18 @@ 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>;
final responseString = await response.transform(utf8.decoder).join();
final bodyJson = json.decode(responseString) as Map<String, dynamic>;
if (bodyJson.containsKey('error')) {
throw Exception(bodyJson['error'] as String);
@ -117,10 +126,15 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
final responseBody = json.decode(responseString);
if (responseBody is List) {
throw '${responseBody[0]}';
} else {
@ -128,7 +142,8 @@ class CakePayApi {
}
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
final responseString = await response.transform(utf8.decoder).join();
final bodyJson = json.decode(responseString) as Map<String, dynamic>;
return CakePayOrder.fromMap(bodyJson);
} catch (e) {
throw Exception('${e}');
@ -170,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}');

View file

@ -15,6 +15,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();

View file

@ -1,9 +1,8 @@
import 'package:cake_wallet/utils/proxy_wrapper.dart';
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';
@ -32,7 +31,9 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
uri = Uri.https(_fiatApiClearNetAuthority, _fiatApiPath, queryParams);
}
final response = await ProxyWrapper().get(clearnetUri: uri);
final response = await ProxyWrapper().get(
clearnetUri: uri,
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {

View file

@ -1,8 +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';
import 'package:cw_core/utils/proxy_wrapper.dart';
class YatService {
static bool isDevMode = false;
@ -44,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));
}

View file

@ -1,13 +1,11 @@
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cw_core/utils/http_client.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';
import 'package:http/io_client.dart' as ioc;
class EnsRecord {
@ -24,8 +22,7 @@ class EnsRecord {
}
if (_client == null) {
final httpClient = getHttpClient();
late final Client client = ioc.IOClient(httpClient);
late final client = ProxyWrapper().getHttpIOClient();
_client = Web3Client("https://ethereum-rpc.publicnode.com", client);
}

View file

@ -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,14 +13,18 @@ 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>;
final responseString = await response.transform(utf8.decoder).join();
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
isFioRegistered = responseJSON['is_registered'] as int == 1;
return isFioRegistered;
@ -35,11 +39,15 @@ 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),
);
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');
@ -49,7 +57,7 @@ class FioAddressProvider {
throw Exception('Unexpected response http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final String pubAddress = responseJSON['public_address'] as String;
return pubAddress;

View file

@ -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 responseString = await response.transform(utf8.decoder).join();
final jsonParsed = json.decode(responseString) as Map<String, dynamic>;
if (jsonParsed["records"] == null) {
throw Exception(".records response from $uri is empty");
};

View file

@ -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,15 +40,16 @@ 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>;
final responseString = await response.transform(utf8.decoder).join();
final Map<String, dynamic> decoded = json.decode(responseString) as Map<String, dynamic>;
// Access the first element in the names array and retrieve its address
final List<dynamic> names = decoded["names"] as List<dynamic>;

View file

@ -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,7 +16,8 @@ class ZanoAlias {
"params": {"alias": alias}
}),
);
final jsonParsed = json.decode(response.body) as Map<String, dynamic>;
final responseString = await response.transform(utf8.decoder).join();
final jsonParsed = json.decode(responseString) as Map<String, dynamic>;
return jsonParsed['result']['alias_details']['address'] as String?;
} catch (e) {

View file

@ -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,27 +275,29 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if ((response.statusCode != 200) || (response.body.contains('error'))) {
throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
if ((response.statusCode != 200) || (responseString.contains('error'))) {
throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${responseString}');
}
return json.decode(response.body) as Map<String, dynamic>;
return json.decode(responseString) as Map<String, dynamic>;
}
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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode == 404) return null;
if ((response.statusCode != 200) || (response.body.contains('error'))) {
throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
if ((response.statusCode != 200) || (responseString.contains('error'))) {
throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${responseString}');
}
return json.decode(response.body) as Map<String, dynamic>;
return json.decode(responseString) as Map<String, dynamic>;
}
TradeState _determineState(String state) {

View file

@ -13,12 +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:cake_wallet/utils/proxy_wrapper.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,
@ -180,10 +179,15 @@ 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),
);
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');
@ -192,7 +196,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 id = responseJSON['id'] as String;
final inputAddress = responseJSON['payinAddress'] as String;
final refundAddress = responseJSON['refundAddress'] as String;

View file

@ -9,10 +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:cake_wallet/utils/proxy_wrapper.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));
@ -175,10 +174,15 @@ 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),
);
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 errors = responseJSON['errors'] as Map<String, String>;
final errorMessage = errors.values.join(', ');
throw Exception(errorMessage);
@ -187,7 +191,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
if (response.statusCode != 200 && response.statusCode != 201)
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['id'] as String;
final inputAddress = responseJSON['depositAddress'] as String;
final refundAddress = responseJSON['refundAddress'] as String?;

View file

@ -10,10 +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:cake_wallet/utils/proxy_wrapper.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));
@ -153,12 +152,16 @@ 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,
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception('LetsExchange create trade failed: ${response.body}');
throw Exception('LetsExchange create trade failed: ${responseString}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final id = responseJSON['transaction_id'] as String;
final from = responseJSON['coin_from'] as String;
final to = responseJSON['coin_to'] as String;
@ -268,11 +271,15 @@ 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,
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception('LetsExchange fetch info failed: ${response.body}');
throw Exception('LetsExchange fetch info failed: ${responseString}');
}
return json.decode(response.body) as Map<String, dynamic>;
return json.decode(responseString) as Map<String, dynamic>;
} catch (e) {
throw Exception('LetsExchange failed to fetch info ${e.toString()}');
}

View file

@ -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,10 +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:cake_wallet/utils/proxy_wrapper.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));
@ -189,11 +187,16 @@ 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),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 201) {
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 TradeNotCreatedException(description, description: error);
@ -202,7 +205,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
throw TradeNotCreatedException(description);
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final id = responseJSON['id'] as String;
final inputAddress = responseJSON['depositAddress'] as String;
final settleAddress = responseJSON['settleAddress'] as String;
@ -284,11 +287,16 @@ 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),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 201) {
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 TradeNotCreatedException(description, description: error);
@ -297,7 +305,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
throw TradeNotCreatedException(description);
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
return responseJSON['id'] as String;
}

View file

@ -11,9 +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:cake_wallet/utils/proxy_wrapper.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));
@ -137,11 +136,16 @@ 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),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200 && response.statusCode != 201) {
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 TradeNotCreatedException(description, description: error);
@ -150,7 +154,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
throw TradeNotCreatedException(description);
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final id = responseJSON['id'] as String;
final inputAddress = responseJSON['address_from'] as String;
final payoutAddress = responseJSON['address_to'] as String;

View file

@ -10,9 +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:cake_wallet/utils/proxy_wrapper.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));
@ -64,12 +63,16 @@ 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),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception('StealthEx fetch limits failed: ${response.body}');
throw Exception('StealthEx fetch limits failed: ${responseString}');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final min = toDouble(responseJSON['min_amount']);
final max = responseJSON['max_amount'] as double?;
return Limits(min: min, max: max);
@ -135,13 +138,17 @@ 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),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 201) {
throw Exception('StealthEx create trade failed: ${response.body}');
throw Exception('StealthEx create 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>;
@ -262,10 +269,14 @@ 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),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) return {};
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final rate = responseJSON['rate'] as Map<String, dynamic>?;
return {
'estimated_amount': responseJSON['estimated_amount'] as double?,

View file

@ -10,10 +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:cake_wallet/utils/proxy_wrapper.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));
@ -118,8 +117,13 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
};
final uri = Uri.https(apiAuthority, getRate, params);
final response = await post(uri, body: body, headers: headers);
final responseBody = json.decode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().post(
clearnetUri: uri,
body: json.encode(body),
headers: headers,
);
final responseString = await response.transform(utf8.decoder).join();
final responseBody = json.decode(responseString) as Map<String, dynamic>;
if (response.statusCode != 200)
throw Exception('Unexpected http status: ${response.statusCode}');
@ -155,8 +159,13 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
};
final uri = Uri.https(apiAuthority, createOrder, params);
final response = await post(uri, body: body, headers: headers);
final responseBody = json.decode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().post(
clearnetUri: uri,
body: json.encode(body),
headers: headers,
);
final responseString = await response.transform(utf8.decoder).join();
final responseBody = json.decode(responseString) as Map<String, dynamic>;
if (response.statusCode == 400 || responseBody["success"] == false) {
final error = responseBody['errors'][0]['msg'] as String;
@ -198,8 +207,13 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
};
final uri = Uri.https(apiAuthority, order, params);
final response = await post(uri, body: body, headers: headers);
final responseBody = json.decode(response.body) as Map<String, dynamic>;
final response = await ProxyWrapper().post(
clearnetUri: uri,
body: json.encode(body),
headers: headers,
);
final responseString = await response.transform(utf8.decoder).join();
final responseBody = json.decode(responseString) as Map<String, dynamic>;
if (response.statusCode == 400 || responseBody["success"] == false) {
final error = responseBody['errors'][0]['msg'] as String;

View file

@ -7,11 +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:cake_wallet/utils/proxy_wrapper.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})

View file

@ -8,10 +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:cake_wallet/utils/proxy_wrapper.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 {}})
@ -294,12 +293,13 @@ 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);
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 Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final providersJsonList = responseJSON['list'] as List<dynamic>;
final filteredProvidersList = providersJsonList

View file

@ -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,11 +71,12 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) {
throw Exception('Failed to fetch assets for ${currency.title} on ${currency.tag}');
}
final assets = json.decode(response.body) as List<dynamic>;
final assets = json.decode(responseString) as List<dynamic>;
final asset = assets.firstWhere(
(asset) {
@ -102,9 +102,10 @@ 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);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 200) return [];
return json.decode(response.body) as List<dynamic>;
return json.decode(responseString) as List<dynamic>;
} catch (e) {
printV(e.toString());
return [];
@ -205,14 +206,19 @@ 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),
);
final responseString = await response.transform(utf8.decoder).join();
if (response.statusCode != 201) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final error = responseJSON['error'] ?? 'Unknown error';
final message = responseJSON['message'] ?? '';
throw Exception('$error\n$message');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final amount = responseJSON['amount'] as Map<String, dynamic>;
final toAmount = responseJSON['toAmount'] as Map<String, dynamic>;
@ -254,9 +260,10 @@ 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);
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>;
if (responseJSON.containsKey('code') && responseJSON['code'] == 'NOT_FOUND') {
throw Exception('Trade not found');
}
@ -264,7 +271,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
final message = responseJSON['message'] ?? responseJSON['details'] ?? '';
throw Exception('$error\n$message');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final responseJSON = json.decode(responseString) as Map<String, dynamic>;
final pairId = responseJSON['pairId'] as String;
final pairParts = pairId.split('_');

View file

@ -1,7 +1,6 @@
import 'dart:convert';
import 'package:cake_wallet/utils/proxy_wrapper.dart';
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 {

View file

@ -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';

View file

@ -2,8 +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;
import 'package:cw_core/utils/proxy_wrapper.dart';
class TwitterApi {
static const twitterBearerToken = secrets.twitterBearerToken;

View file

@ -1,4 +1,4 @@
import 'package:cw_core/utils/http_client.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:flutter/material.dart';
import 'package:tor/tor.dart';
@ -37,11 +37,14 @@ Future<void> showFullscreenDialog(BuildContext context) async {
context: context,
barrierDismissible: false,
builder: (context) {
return Container(
color: Colors.transparent,
child: Center(
child: CircularProgressIndicator(
color: Colors.white,
return PopScope(
canPop: false,
child: Container(
color: Colors.transparent,
child: Center(
child: CircularProgressIndicator(
color: Colors.white,
),
),
),
);

View file

@ -13,7 +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: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';

View file

@ -12,7 +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: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';
@ -20,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';

View file

@ -7,8 +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:cw_core/utils/proxy_wrapper.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
@ -140,7 +139,6 @@ abstract class NFTViewModelBase with Store {
"X-API-Key": secrets.moralisApiKey,
},
);
final responseString = await response.transform(utf8.decoder).join();
final decodedResponse = jsonDecode(responseString) as Map<String, dynamic>;

View file

@ -7,9 +7,9 @@ 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: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';
@ -17,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';
@ -940,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',

View file

@ -1,7 +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/http_client.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:flutter/cupertino.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';

View file

@ -1,7 +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/http_client.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';

View file

@ -1,7 +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/http_client.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';