v4.23.0 release candidate (#1974)

* v4.23.0 release candidate

* - Fix restoring zano from QR
- Fix Zano confirmations count
- Fix birdpay
- Fix balance display

* Fix Zano assets showing amount before they are added

* - handle fetching token data while the API is busy
- potential fix for duplicate transactions

* fix receive confirmations, maybe

* revert onChangeWallet cleanup

* Fix confirmations not updating

* improve zano wallet opening, fix CI commands and messages on slack (#1979)

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* Cache wallet when creating/restoring as well

* - hardcode Trocador Maximum limit for Zano temporarily
- Configure Cake Zano node to use SSL

* reformatting [skip ci]

* revert to non-ssl

* update build numbers [skip ci]

* disable zano for desktop [skip ci]

---------

Co-authored-by: cyan <cyjan@mrcyjanek.net>
This commit is contained in:
Omar Hatem 2025-01-28 23:53:43 +02:00 committed by GitHub
parent aef90e7192
commit 141a7ebfca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 472 additions and 306 deletions

View file

@ -102,10 +102,9 @@ class Node extends HiveObject with Keyable {
case WalletType.polygon:
case WalletType.solana:
case WalletType.tron:
return Uri.parse(
"http${isSSL ? "s" : ""}://$uriRaw${path!.startsWith("/") ? path : "/$path"}");
case WalletType.zano:
return Uri.https(uriRaw, '');
return Uri.parse(
"http${isSSL ? "s" : ""}://$uriRaw${path!.startsWith("/") || path!.isEmpty ? path : "/$path"}");
case WalletType.none:
throw Exception('Unexpected type ${type.toString()} for Node uri');
}
@ -177,7 +176,33 @@ class Node extends HiveObject with Keyable {
}
Future<bool> requestZanoNode() async {
return requestMoneroNode(methodName: "getinfo");
final path = '/json_rpc';
final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path);
final body = {'jsonrpc': '2.0', 'id': '0', 'method': "getinfo"};
try {
final authenticatingClient = HttpClient();
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,
headers: {'Content-Type': 'application/json'},
body: jsonBody,
);
printV("node check response: ${response.body}");
final resBody = json.decode(response.body) as Map<String, dynamic>;
return resBody['result']['height'] != null;
} catch (e) {
printV("error: $e");
return false;
}
}
Future<bool> requestMoneroNode({String methodName = 'get_info'}) async {
@ -185,7 +210,6 @@ class Node extends HiveObject with Keyable {
return await requestNodeWithProxy();
}
final path = '/json_rpc';
final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path);
final body = {'jsonrpc': '2.0', 'id': '0', 'method': methodName};
@ -195,7 +219,6 @@ class Node extends HiveObject with Keyable {
authenticatingClient.badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
final http.Client client = ioc.IOClient(authenticatingClient);
final jsonBody = json.encode(body);
@ -209,13 +232,13 @@ class Node extends HiveObject with Keyable {
if (response.statusCode == 401) {
final daemonRpc = DaemonRpc(
rpcUri.toString(),
username: login??'',
password: password??'',
username: login ?? '',
password: password ?? '',
);
final response = await daemonRpc.call('get_info', {});
return !(response['offline'] as bool);
}
printV("node check response: ${response.body}");
if ((response.body.contains("400 Bad Request") // Some other generic error
@ -298,10 +321,7 @@ class Node extends HiveObject with Keyable {
try {
final response = await http.post(
uri,
headers: {
"Content-Type": "application/json",
"nano-app": "cake-wallet"
},
headers: {"Content-Type": "application/json", "nano-app": "cake-wallet"},
body: jsonEncode(
{
"action": "account_balance",
@ -407,8 +427,7 @@ class DigestAuth {
}
/// Helper to format the nonce count.
String _formatNonceCount(int count) =>
count.toRadixString(16).padLeft(8, '0');
String _formatNonceCount(int count) => count.toRadixString(16).padLeft(8, '0');
/// Compute the MD5 hash of a string.
String md5Hash(String input) {
@ -424,8 +443,7 @@ class DaemonRpc {
DaemonRpc(this.rpcUrl, {required this.username, required this.password});
/// Perform a JSON-RPC call with Digest Authentication.
Future<Map<String, dynamic>> call(
String method, Map<String, dynamic> params) async {
Future<Map<String, dynamic>> call(String method, Map<String, dynamic> params) async {
final http.Client client = http.Client();
final DigestAuth digestAuth = DigestAuth(username, password);
@ -475,11 +493,12 @@ class DaemonRpc {
throw Exception('RPC call failed: ${authenticatedResponse.body}');
}
final Map<String, dynamic> result = jsonDecode(authenticatedResponse.body) as Map<String, dynamic>;
final Map<String, dynamic> result =
jsonDecode(authenticatedResponse.body) as Map<String, dynamic>;
if (result['error'] != null) {
throw Exception('RPC Error: ${result['error']}');
}
return result['result'] as Map<String, dynamic>;
}
}
}