stack_wallet/lib/electrumx_rpc/rpc.dart

85 lines
2.6 KiB
Dart
Raw Normal View History

2022-08-26 08:11:35 +00:00
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:stackwallet/utilities/logger.dart';
// hacky fix to receive large jsonrpc responses
class JsonRPC {
JsonRPC({
required this.host,
required this.port,
this.useSSL = false,
this.connectionTimeout = const Duration(seconds: 60),
});
2023-05-24 18:12:54 +00:00
final bool useSSL;
final String host;
final int port;
final Duration connectionTimeout;
2023-05-24 18:14:21 +00:00
Socket? socket;
2022-08-26 08:11:35 +00:00
Future<dynamic> request(String jsonRpcRequest) async {
final completer = Completer<dynamic>();
final List<int> responseData = [];
void dataHandler(List<int> data) {
responseData.addAll(data);
// 0x0A is newline
// https://electrumx-spesmilo.readthedocs.io/en/latest/protocol-basics.html
if (data.last == 0x0A) {
try {
final response = json.decode(String.fromCharCodes(responseData));
completer.complete(response);
} catch (e, s) {
Logging.instance
.log("JsonRPC json.decode: $e\n$s", level: LogLevel.Error);
completer.completeError(e, s);
} finally {
2023-05-24 18:15:19 +00:00
Logging.instance
.log("JsonRPC dataHandler: not destroying socket ${socket?.address}:${socket?.port}", level: LogLevel.Info);
// socket?.destroy();
// TODO is this all we need to do?
2022-08-26 08:11:35 +00:00
}
}
}
void errorHandler(Object error, StackTrace trace) {
Logging.instance
.log("JsonRPC errorHandler: $error\n$trace", level: LogLevel.Error);
completer.completeError(error, trace);
2023-05-24 18:15:19 +00:00
Logging.instance
.log("JsonRPC errorHandler: not destroying socket ${socket?.address}:${socket?.port}", level: LogLevel.Info);
// socket?.destroy();
// TODO do we need to recreate the socket?
2022-08-26 08:11:35 +00:00
}
void doneHandler() {
2023-05-24 18:15:19 +00:00
Logging.instance
.log("JsonRPC doneHandler: not destroying socket ${socket?.address}:${socket?.port}", level: LogLevel.Info);
// socket?.destroy();
// TODO is this all we need?
2022-08-26 08:11:35 +00:00
}
2023-05-24 18:15:10 +00:00
if (socket != null) {
// TODO check if the socket is valid, alive, connected, etc
}
2022-08-26 08:11:35 +00:00
if (useSSL) {
2023-05-24 18:14:56 +00:00
socket ??= await SecureSocket.connect(host, port,
2022-08-26 08:11:35 +00:00
timeout: connectionTimeout,
2023-05-24 18:14:56 +00:00
onBadCertificate: (_) => true);
socket!.listen(dataHandler,
onError: errorHandler, onDone: doneHandler, cancelOnError: true);
2022-08-26 08:11:35 +00:00
} else {
2023-05-24 18:14:56 +00:00
socket ??= await Socket.connect(host, port, timeout: connectionTimeout);
socket!.listen(dataHandler,
onError: errorHandler, onDone: doneHandler, cancelOnError: true);
2022-08-26 08:11:35 +00:00
}
socket?.write('$jsonRpcRequest\r\n');
return completer.future;
}
}