mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-24 19:25:52 +00:00
Merge branch 'staging' into fix_1061
This commit is contained in:
commit
22f9d4c653
4 changed files with 67 additions and 54 deletions
|
@ -12,6 +12,9 @@ import 'dart:convert';
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/io_client.dart';
|
||||
import 'package:monero_rpc/monero_rpc.dart';
|
||||
import 'package:digest_auth/digest_auth.dart';
|
||||
import 'package:socks5_proxy/socks.dart';
|
||||
import 'package:tor_ffi_plugin/socks_socket.dart';
|
||||
|
||||
|
@ -27,11 +30,18 @@ class MoneroNodeConnectionResponse {
|
|||
final int? port;
|
||||
final bool success;
|
||||
|
||||
MoneroNodeConnectionResponse(this.cert, this.url, this.port, this.success);
|
||||
MoneroNodeConnectionResponse(
|
||||
this.cert,
|
||||
this.url,
|
||||
this.port,
|
||||
this.success,
|
||||
);
|
||||
}
|
||||
|
||||
Future<MoneroNodeConnectionResponse> testMoneroNodeConnection(
|
||||
Uri uri,
|
||||
String? username,
|
||||
String? password,
|
||||
bool allowBadX509Certificate, {
|
||||
required ({
|
||||
InternetAddress host,
|
||||
|
@ -59,36 +69,37 @@ Future<MoneroNodeConnectionResponse> testMoneroNodeConnection(
|
|||
await socket.connect();
|
||||
await socket.connectTo(uri.host, uri.port);
|
||||
|
||||
final body = jsonEncode({
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
"method": "get_info",
|
||||
});
|
||||
|
||||
final request = 'POST /json_rpc HTTP/1.1\r\n'
|
||||
'Host: ${uri.host}\r\n'
|
||||
'Content-Type: application/json\r\n'
|
||||
'Content-Length: ${body.length}\r\n'
|
||||
'\r\n'
|
||||
'$body';
|
||||
|
||||
socket.write(request);
|
||||
print("Request sent: $request");
|
||||
|
||||
final buffer = StringBuffer();
|
||||
await for (var response in socket.inputStream) {
|
||||
buffer.write(utf8.decode(response));
|
||||
if (buffer.toString().contains("\r\n\r\n")) {
|
||||
break;
|
||||
final rawRequest = DaemonRpc.rawRequestRpc(uri, 'get_info', {});
|
||||
var response = await socket.send(rawRequest);
|
||||
// check if we need authentication
|
||||
String? authenticateHeaderValue;
|
||||
for (final line in response.split('\r\n')) {
|
||||
if (line.contains('WWW-authenticate: ')) {
|
||||
// both the password and username needs to be
|
||||
if (username == null || password == null) {
|
||||
// node asking us for authentication, but we don't have any crendentials.
|
||||
return MoneroNodeConnectionResponse(null, null, null, false);
|
||||
}
|
||||
authenticateHeaderValue =
|
||||
line.replaceFirst('WWW-authenticate: ', '').trim();
|
||||
}
|
||||
}
|
||||
// header to authenticate was present, we need to remake the request with digest
|
||||
if (authenticateHeaderValue != null) {
|
||||
final digestAuth = DigestAuth(username!, password!);
|
||||
digestAuth.initFromAuthorizationHeader(authenticateHeaderValue);
|
||||
|
||||
final result = buffer.toString();
|
||||
print("Response received: $result");
|
||||
// generate the Authorization header for the second request.
|
||||
final authHeader = digestAuth.getAuthString('POST', uri.path);
|
||||
final rawRequestAuthenticated =
|
||||
DaemonRpc.rawRequestRpc(uri, 'get_info', {}, authHeader);
|
||||
// resend with an authenticated request
|
||||
response = await socket.send(rawRequestAuthenticated);
|
||||
}
|
||||
|
||||
// Check if the response contains "results" and does not contain "error"
|
||||
final success =
|
||||
result.contains('"result":') && !result.contains('"error"');
|
||||
response.contains('"result":') && !response.contains('"error"');
|
||||
|
||||
return MoneroNodeConnectionResponse(null, null, null, success);
|
||||
} catch (e, s) {
|
||||
|
@ -124,36 +135,15 @@ Future<MoneroNodeConnectionResponse> testMoneroNodeConnection(
|
|||
|
||||
return false;
|
||||
};
|
||||
|
||||
final request = await httpClient.postUrl(uri);
|
||||
|
||||
final body = utf8.encode(
|
||||
jsonEncode({
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
"method": "get_info",
|
||||
}),
|
||||
final daemonRpc = DaemonRpc(
|
||||
IOClient(httpClient),
|
||||
'$uri',
|
||||
username: username,
|
||||
password: password,
|
||||
);
|
||||
final result = await daemonRpc.call('get_info', {});
|
||||
|
||||
request.headers.add(
|
||||
'Content-Length',
|
||||
body.length.toString(),
|
||||
preserveHeaderCase: true,
|
||||
);
|
||||
request.headers.set(
|
||||
'Content-Type',
|
||||
'application/json',
|
||||
preserveHeaderCase: true,
|
||||
);
|
||||
|
||||
request.add(body);
|
||||
|
||||
final response = await request.close();
|
||||
final result = await response.transform(utf8.decoder).join();
|
||||
// print("HTTP Response: $result");
|
||||
|
||||
final success =
|
||||
result.contains('"result":') && !result.contains('"error"');
|
||||
final success = result.containsKey('status') && result['status'] == 'OK';
|
||||
|
||||
return MoneroNodeConnectionResponse(null, null, null, success);
|
||||
} catch (e, s) {
|
||||
|
@ -210,3 +200,18 @@ Future<bool> showBadX509CertificateDialog(
|
|||
|
||||
return result ?? false;
|
||||
}
|
||||
|
||||
extension on SOCKSSocket {
|
||||
/// write the raw request to the socket and return the response as String
|
||||
Future<String> send(String rawRequest) async {
|
||||
write(rawRequest);
|
||||
final buffer = StringBuffer();
|
||||
await for (final response in inputStream) {
|
||||
buffer.write(utf8.decode(response));
|
||||
if (buffer.toString().contains("\r\n\r\n")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ Future<bool> _xmrHelper(
|
|||
final data = nodeFormData;
|
||||
final url = data.host!;
|
||||
final port = data.port;
|
||||
final username = data.login;
|
||||
final password = data.password;
|
||||
|
||||
final uri = Uri.parse(url);
|
||||
|
||||
|
@ -51,6 +53,8 @@ Future<bool> _xmrHelper(
|
|||
|
||||
final response = await testMoneroNodeConnection(
|
||||
Uri.parse(uriString),
|
||||
username,
|
||||
password,
|
||||
false,
|
||||
proxyInfo: proxyInfo,
|
||||
).timeout(Duration(seconds: proxyInfo != null ? 30 : 10));
|
||||
|
@ -67,6 +71,8 @@ Future<bool> _xmrHelper(
|
|||
if (shouldAllowBadCert) {
|
||||
final response = await testMoneroNodeConnection(
|
||||
Uri.parse(uriString),
|
||||
username,
|
||||
password,
|
||||
true,
|
||||
proxyInfo: proxyInfo,
|
||||
);
|
||||
|
|
|
@ -229,7 +229,7 @@ class Namecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
|
|||
bool get hasMnemonicPassphraseSupport => true;
|
||||
|
||||
@override
|
||||
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
|
||||
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
|
||||
|
||||
@override
|
||||
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
|
||||
|
|
|
@ -204,6 +204,8 @@ dependencies:
|
|||
cbor: ^6.3.3
|
||||
cs_monero: 1.0.0-pre.1
|
||||
cs_monero_flutter_libs: 1.0.0-pre.0
|
||||
monero_rpc: ^2.0.0
|
||||
digest_auth: ^1.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in a new issue