mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 12:29:51 +00:00
CW-519 Enable built-in Tor (#1950)
* tor wip * Enable tor on iOS * Prevent app lag when node is exceptionally slow (usually over tor) * fix: logic in daemonBlockchainHeight refresh fix: storing tor state * Pin ledger_flutter_plus dependency to fix builds * bump arti version * wip * add single httpclient * route everything I was able to catch trough the built-in tor node * Enable proxy for http.Client [run tests] * add tor proxy support to cw_evm, cw_tron and cw_polygon [run tests] * remove log pollution, cleanup [skip slack] * fix tests not working in latest main [skip slack] [run tests] * remove cw_wownero import * fix build issues * migrate all remaining calls to use ProxyWrapper add a CI action to enforce using ProxyWrapper instead of http/http.dart to prevent leaks * fix tor background sync (will work on test builds after #2142 is merged and this PR is rebased on top) * wip [skip ci] * relicense to GPLv3 add socks5 license, build fixes * use ProxyWrapper instead of http in robinhood * Revert "relicense to GPLv3" * feat(cw_bitcoin): support socks proxy and CakeTor * fix(tor): migrate OCP and EVM over to ProxyWrapper() * chore: cleanup fix: show tor loading screen when app is starting * fix: tor switch properly dismisses fullscreen loading dialog fix: connectToNode after tor startup on app start * fix(tor): status check for xmr/wow/zano * fix(tor): onramper request fix * fix(api): ServicesResponse is now being cached and doesn't fetch data everytime DashboardViewModel is being rebuilt fix(tor): do not fallback to clearnet when tor failed. fix(tor): do not leak connections during app startup chore: refactor bootstrap() function to be separated into bootstrapOffline and bootstrapOnline fix(cw_bitcoin): migrate payjoin to use ProxyWrapper * [skip ci] remove print * address comments from review * fix: derusting tor implementation Instead of rust-based Arti I've moved back to the OG C++ tor implementation. This fixed all issues we had with Tor. - onion services now work - all requests are going through without random errors - we don't have to navigate a maze of multiple forks of multiple packages - fully working `torrc` config file (probably will be needed for Tari). - logging for Tor client - and so on. feat: network logging tab feat: use built-in proxy on Tails - this should resolve all issues for Tails users (needs testing though) * fix conflicts with main bump https to fix build issue relax store() call * fix(cw_wownero): tor connection fix(tor): connection issues * fix(cw_evm): add missing chainId fix(cw_core): solana rpc fix * feat: mark tor as experimental fix: drop anonpay onion authority fix: drop fiatapi onion authority fix: drop trocador onion authority fix: disable networkimage when tor is enabled fix: handle cakepay errors gracefully * fix re-formatting [skip ci] * changes from review * Delete android/.kotlin/sessions/kotlin-compiler-2468481326039681181.salive * fix missing imports * Update pubspec_base.yaml --------- Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
parent
18c2ba9366
commit
5082dc20f3
139 changed files with 2754 additions and 878 deletions
|
@ -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 data = jsonDecode(response.body) 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 data = jsonDecode(response.body) 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 data = jsonDecode(response.body) 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,8 +194,9 @@ class NanoClient {
|
|||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final Map<String, dynamic> decoded = json.decode(response.body) as Map<String, dynamic>;
|
||||
final decoded = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
if (decoded.containsKey("error")) {
|
||||
throw Exception("Received error ${decoded["error"]}");
|
||||
}
|
||||
|
@ -224,13 +228,13 @@ 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 Map<String, dynamic> decoded = jsonDecode(processResponse.body) as Map<String, dynamic>;
|
||||
if (decoded.containsKey("error")) {
|
||||
throw Exception("Received error ${decoded["error"]}");
|
||||
}
|
||||
|
@ -423,12 +427,11 @@ 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>;
|
||||
if (decoded.containsKey("error")) {
|
||||
throw Exception("Received error ${decoded["error"]}");
|
||||
|
@ -440,16 +443,17 @@ 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 receivableData = jsonDecode(receivableResponse.body) as Map<String, dynamic>;
|
||||
if (receivableData["blocks"] == "" || receivableData["blocks"] == null) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -492,15 +496,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 data = jsonDecode(response.body) 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 +523,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 List<N2Node> nodes = (jsonDecode(response.body) as List<dynamic>)
|
||||
.map((dynamic e) => N2Node.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
return nodes;
|
||||
|
@ -533,8 +541,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 +550,8 @@ class NanoClient {
|
|||
}),
|
||||
);
|
||||
try {
|
||||
final N2Node node = N2Node.fromJson(json.decode(response.body) as Map<String, dynamic>);
|
||||
|
||||
final N2Node node = N2Node.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
|
||||
return node.score ?? 100;
|
||||
} catch (error) {
|
||||
return 100;
|
||||
|
|
|
@ -784,11 +784,21 @@ packages:
|
|||
socks5_proxy:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: socks5_proxy
|
||||
sha256: "616818a0ea1064a4823b53c9f7eaf8da64ed82dcd51ed71371c7e54751ed5053"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.6"
|
||||
path: "."
|
||||
ref: "27ad7c2efae8d7460325c74b90f660085cbd0685"
|
||||
resolved-ref: "27ad7c2efae8d7460325c74b90f660085cbd0685"
|
||||
url: "https://github.com/LacticWhale/socks_dart"
|
||||
source: git
|
||||
version: "2.1.0"
|
||||
socks_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
path: "."
|
||||
ref: e6232c53c1595469931ababa878759a067c02e94
|
||||
resolved-ref: e6232c53c1595469931ababa878759a067c02e94
|
||||
url: "https://github.com/sneurlax/socks_socket"
|
||||
source: git
|
||||
version: "1.1.1"
|
||||
source_gen:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -865,10 +875,19 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
|
||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.0.1"
|
||||
tor_binary:
|
||||
dependency: transitive
|
||||
description:
|
||||
path: "."
|
||||
ref: cb811c610871a9517d47134b87c2f590c15c96c5
|
||||
resolved-ref: cb811c610871a9517d47134b87c2f590c15c96c5
|
||||
url: "https://github.com/MrCyjaneK/flutter-tor_binary"
|
||||
source: git
|
||||
version: "4.7.14"
|
||||
tuple:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue