From 6ab69e08bf8f5ea381aa99c4312300e267b46278 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Thu, 3 Oct 2024 18:11:43 -0500 Subject: [PATCH] add monero onion example --- example/lib/main.dart | 112 ++++++++++++++++++++++++++++++++++++++++++ example/pubspec.lock | 22 ++++----- 2 files changed, 123 insertions(+), 11 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 9e05414..3a61e9d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -66,6 +66,10 @@ class _MyAppState extends State { // For more options, see https://bitnodes.io/nodes/addresses/?q=onion and // https://sethforprivacy.com/about/ + final moneroOnionController = TextEditingController( + text: + 'ucdouiihzwvb5edg3ezeufcs4yp26gq4x64n6b4kuffb7s7jxynnk7qd.onion:18081/json_rpc'); + Future startTor() async { await Tor.init(); @@ -346,6 +350,114 @@ class _MyAppState extends State { ), ], ), + spacerSmall, + Row( + children: [ + // Monero onion input field. + Expanded( + child: TextField( + controller: moneroOnionController, + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: 'Monero onion address to test', + ), + ), + ), + spacerSmall, + TextButton( + onPressed: torStarted + ? () async { + // Validate the onion address. + if (!moneroOnionController.text + .contains(".onion")) { + print("Invalid onion address"); + return; + } else if (!moneroOnionController.text + .contains(":")) { + print("Invalid onion address (needs port)"); + return; + } + + final String host = + moneroOnionController.text.split(":").first; + final int port = int.parse(moneroOnionController + .text + .split(":") + .last + .split("/") + .first); + final String path = moneroOnionController.text + .split(":") + .last + .split("/") + .last; // Extract the path + + var socksSocket = await SOCKSSocket.create( + proxyHost: InternetAddress.loopbackIPv4.address, + proxyPort: Tor.instance.port, + sslEnabled: false, + ); + + await socksSocket.connect(); + await socksSocket.connectTo(host, port); + + final body = jsonEncode({ + "jsonrpc": "2.0", + "id": "0", + "method": "get_info", + }); + + final request = 'POST /$path HTTP/1.1\r\n' + 'Host: $host\r\n' + 'Content-Type: application/json\r\n' + 'Content-Length: ${body.length}\r\n' + '\r\n' + '$body'; + + socksSocket.write(request); + print("Request sent: $request"); + + await for (var response + in socksSocket.inputStream) { + final result = utf8.decode(response); + print("Response received: $result"); + break; + } + + // You should see a server response printed to the console. + // + // Example response: + // Host: ucdouiihzwvb5edg3ezeufcs4yp26gq4x64n6b4kuffb7s7jxynnk7qd.onion + // Content-Type: application/json + // Content-Length: 46 + // + // {"jsonrpc":"2.0","id":"0","method":"get_info"} + // flutter: Response received: HTTP/1.1 200 Ok + // Server: Epee-based + // Content-Length: 1434 + // Content-Type: application/json + // Last-Modified: Thu, 03 Oct 2024 23:08:19 GMT + // Accept-Ranges: bytes + // + // { + // "id": "0", + // "jsonrpc": "2.0", + // "result": { + // "adjusted_time": 1727996959, + // ... + + await socksSocket.close(); + } + + // A mutex should be added to this example to prevent + // multiple connections from being made at once. TODO + : null, + child: const Text( + "Test Monero onion node connection", + ), + ), + ], + ), ], ), ), diff --git a/example/pubspec.lock b/example/pubspec.lock index a13f188..1ff8c91 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: collection - sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.19.0" + version: "1.18.0" cupertino_icons: dependency: "direct main" description: @@ -87,18 +87,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.7" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -215,7 +215,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.0" + version: "0.0.99" socks5_proxy: dependency: "direct main" description: @@ -252,10 +252,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.2.0" term_glyph: dependency: transitive description: @@ -268,10 +268,10 @@ packages: dependency: transitive description: name: test_api - sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.3" + version: "0.7.2" tor: dependency: "direct main" description: